【问题标题】:Convert long Postgres bytea to decimal将长 Postgres bytea 转换为十进制
【发布时间】:2016-09-14 19:49:27
【问题描述】:

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

c30d040703020095dbb3d3746d096dd23b01c59bcbc7a4320f571511f61f3ea3def0e55404204a274500224927421bd5a8344a56316b909ef3af276b585622f1c9b7ca13563ee6fe88f4ddbe

问题在于 similar questions 没有一个处理那么大的数字。谁有解决办法?

【问题讨论】:

标签: postgresql


【解决方案1】:

这是我的看法:

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 个) .

【讨论】:

  • 看起来很棒!我还在调试我自己的解决方案,所以我会把它扔掉并拿走你的。 :-)
  • @PaulAJungwirth 还有,ta-dam,create or replace function hex2num_p(p_input text) returns numeric language plpythonu immutable strict as $$ return int(p_input, 16) $$; - Execution time: 29.971 ms(对于同一数据上的parse_hex Execution time: 2804.940 ms)以防万一我们关心速度:)
  • 29ms 更合理,不是吗?向 python 发起攻击是很可爱的。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 2022-06-24
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
相关资源
最近更新 更多