将长Postgres bytea转换为十进制

时间:2016-09-14 19:49:27

标签: postgresql

我有一个Postgres bytea值,我希望将其存储为decimal类型(或者作为带有十进制数字的字符串)。存储为bigint的时间太长,但the docsdecimal值最多可包含131072个数字,这足够大。这是我需要处理的长度(十六进制为150-300位):

c30d040703020095dbb3d3746d096dd23b01c59bcbc7a4320f571511f61f3ea3def0e55404204a274500224927421bd5a8344a56316b909ef3af276b585622f1c9b7ca13563ee6fe88f4ddbe

麻烦的是similar questions手柄数量都不大。有人有解决方案吗?

1 个答案:

答案 0 :(得分:2)

这是我的看法:

CREATE OR REPLACE FUNCTION parse_hex(s text) RETURNS numeric AS $$
DECLARE
    len integer;
    result  bigint;
BEGIN
    SELECT length(s) INTO len;
    IF len <= 15 THEN
        EXECUTE 'SELECT x''' || s || '''::bigint' INTO result;
        RETURN result::numeric;
    ELSE
        RETURN parse_hex(left(s, (len+1)/2)) * (16::numeric)^(len/2) +
               parse_hex(right(s, len/2));
        RETURN 0;
    END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;

它使用二进制分割,即它将输入分成两半并通过递归调用自身来转换它们,然后将这两个部分组合起来。

修改:我只是运行一个简单的基准来将上述函数与Abelisto的the one linked进行比较:

$ EXPLAIN ANALYZE SELECT parse_hex(n||'c30d040703020095dbb3d3746d096dd23b01c59bcbc7a4320f571511f61f3ea3def0e55404204a274500224927421bd5a8344a56316b909ef3af276b585622f1c9b7ca13563ee6fe88f4ddbe') FROM generate_series(1,1000) s(n);
Execution time: 640.031 ms

而对于hex2dec,我得到了

Execution time: 2354.616 ms

所以我的函数更快(对于这个大小的输入),我不知道它是否主要是因为二进制分裂的更好的渐近复杂性或者它一次处理15个十六进制数字的事实(而不是1)。