我可以在比较同一个表中的行的查询上使用一些补救帮助。我正在修改我们的代码以推送到 Postgres,并建立了一个测试床来使用我们的旧代码和新代码进行推送。行数很好,但这并不能告诉我数据是否相同。为此,我意识到我可以使用内置功能来获取行的哈希值。这是我的一个简单表格作为开始:
CREATE TABLE IF NOT EXISTS data.hsys (
"id" uuid NOT NULL DEFAULT NULL,
"marked_for_deletion" boolean NOT NULL DEFAULT false,
"name_" citext NOT NULL DEFAULT NULL,
CONSTRAINT hsys_id_pkey
PRIMARY KEY ("id")
);
然后哈希仅采用这一行:
select hashtext(hsys::text) from hsys;
我想要做的是在每次测试推送到一个小表后将每行的 ID、哈希值、代码版本和表名称存储起来:
CREATE TABLE IF NOT EXISTS data.row_check (
id uuid NOT NULL DEFAULT NULL,
version int8 NOT NULL DEFAULT NULL,
row_hash int8 NOT NULL DEFAULT NULL,
table_name text NOT NULL DEFAULT NULL,
CONSTRAINT row_check_pkey
PRIMARY KEY (id, version)
);
将数据插入 row_check 并不难。概念验证查询如下所示:
select
id,
0 as version,
hashtext(hsys::text) as row_hash,
'hsys' as table_name,
from hsys;
有效的插入查询如下所示:
INSERT INTO row_check (id,version,row_hash,table_name)
SELECT id, 0, hashtext(hsys::text),'hsys'
FROM hsys
ON CONFLICT ON CONSTRAINT row_check_pkey DO UPDATE SET
row_hash = EXCLUDED.row_hash,
table_name = EXCLUDED.table_name;
数据到位后,我可以看到如下内容:
select * from row_check
order by 1,2
limit 6;
id version row_hash table_name
17ea1ed4-87b0-0840-912f-d29de2a06f5d 0 -1853961325 hsys
17ea1ed4-87b0-0840-912f-d29de2a06f5d 1 -1853961325 hsys
2200d1da-73e7-419c-9e4c-efe020834e6f 0 -482794730 hsys
2200d1da-73e7-419c-9e4c-efe020834e6f 1 482794730 hsys <--- Different from version 0
47f4a50e-2358-434b-b30d-1f707ea9ee1b 0 -1539190835 hsys
47f4a50e-2358-434b-b30d-1f707ea9ee1b 1 -1539190835 hsys
我最希望从这样的样本中得到的是:
table_name id v0 v1
hsys 2200d1da-73e7-419c-9e4c-efe020834e6f 0 -482794730 482794730
但即使是这个最小的结果也会有帮助:
2200d1da-73e7-419c-9e4c-efe020834e6f hsys
这就是我被难住的地方。我想要构建的是对 row_check 的查询,该查询可以发现版本之间哈希值不同的任何 ID。我有上面的版本0和1。有人可以指出我正确的分组和/或加入方向,以仅获取跨版本不匹配的行吗?这些是我需要发现和追踪的危险信号。我确实需要返回 ID 和表名,版本和哈希值是次要的。我对此有一些限制,其中一些有帮助:
ID 值在所有表中都是唯一的。
我一次只会比较两个版本。
我有几十个表要测试。
有些表有数百万行。
最后一点可能很重要。我想用SELECT DISTINCT id
在 CTE 中,但我并没有走得太远。
谢谢你的建议。