一尘不染

如何在Postgresql中获取整个表的哈希?

sql

我想要一种相当有效的方法来将整个表压缩为哈希值。

我有一些工具可以生成整个数据表,然后可以将其用于生成其他表,依此类推。我正在尝试实现一个简化的构建系统来协调构建运行并避免重复工作。我希望能够记录输入表的哈希值,以便以后可以检查它们是否已更改。建立表格需要几分钟或几小时,因此花几秒钟建立哈希表是可以接受的。

我曾经使用过的一种技巧是仅将pg_dump的输出传递给md5sum,但这需要通过网络传输整个表转储,以将其散列在本地机器上。理想情况下,我想在数据库服务器上生成哈希。

在postgresql中查找行的哈希值,使我可以一次计算一行的哈希值,然后可以通过某种方式进行组合。

任何提示将非常感谢。

编辑以发布最终结果:
tinychen的答案对我没有直接作用,因为我显然无法使用’plpgsql’。当我改为在SQL中实现该函数时,它可以工作,但对于大型表而言效率很低。因此,我没有连接所有的行散列然后对其进行散列,而是切换为使用“滚动散列”,其中前一个散列与行的文本表示形式并置,然后对其进行散列以产生下一个散列。这样好多了;显然,在短字符串上额外数百万次运行md5比将短字符串连接数百万次更好。

create function zz_concat(text, text) returns text as 
    'select md5($1 || $2);' language 'sql';

create aggregate zz_hashagg(text) (
    sfunc = zz_concat,
    stype = text,
    initcond = '');

阅读 228

收藏
2021-03-17

共1个答案

一尘不染

只需这样做就可以创建哈希表聚合函数。

create function pg_concat( text, text ) returns text as '
begin
    if $1 isnull then
        return $2;
    else
       return $1 || $2;
    end if;
end;' language 'plpgsql';

create function pg_concat_fin(text) returns text as '
begin
    return $1;
end;' language 'plpgsql';

create aggregate pg_concat (
    basetype = text,
    sfunc = pg_concat,
    stype = text,
    finalfunc = pg_concat_fin);

那么您可以使用pg_concat函数计算表的哈希值。

select md5(pg_concat(md5(CAST((f.*)AS text)))) from f order by id
2021-03-17