【问题标题】:Postgres: Force scientific notation when serialization jsonb numberPostgres:序列化jsonb数字时强制科学记数法
【发布时间】:2021-01-11 17:23:10
【问题描述】:

所以我的问题是我在 PostgreSQL 中存储 JSON 文档,它们有时包含非常小的十进制数。

我在网上读到,在使用 JSONB、PostgreSQL 时,不要愚蠢地保存表示数字的文本,而是在内部使用数字类型。这对我来说很好。

问题是我丢失了将数据发送到 PostgreSQL 时使用的科学记数法。 如果 PostgreSQL 在序列化数字时很聪明,并且在十进制记数法导致使用太多零时使用科学记数法,这对我来说不会有太大问题。

test=# CREATE TABLE json (value JSONB);
CREATE TABLE
test=# INSERT INTO json VALUES ('1E-120');
INSERT 0 1
test=# INSERT INTO json VALUES ('"toto"');
INSERT 0 1
test=# select * from json;
                                                           value                                                            
----------------------------------------------------------------------------------------------------------------------------
 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
 "toto"

test=# 

我希望在运行我的选择时拥有什么:

1E-120
"toto"

我认为这是有问题的,因为我的代码将 JSON 反序列化为解析数字的字符数的限制。而且我也认为这非常低效。

(一种解决方案是切换到 JSON 而不是 JSONB,但这样做我将失去所有 JSONB 的好处)

【问题讨论】:

    标签: json postgresql


    【解决方案1】:

    您将需要一个根据 JSON 类型应用不同格式规则的 CASE 表达式:

    select case jsonb_typeof(value)
              when 'number' then to_char((value #>> '{}')::numeric, '9.EEEE')
              else value #>> '{}'
           end as value
    from json_table
    

    value #>> '{}' 是一种将 JSON 标量转换为 text 值的有点复杂的方法(value::text 不适用于 JSONB 标量)

    【讨论】:

    • 非常感谢您的解决方案。如果您必须在阅读表格时为“ORM”(slick/scala)使其“透明”,您会建议什么?我猜有点像视图。
    • 如果你的混淆层无法处理这样的表达式,那么是的,视图是正确的解决方案
    【解决方案2】:

    使用来自Formatting的数据格式化函数和模板

    select to_char(value::numeric, '9.EEEE') from json; 1e-120

    更新

    从表中选择多个值:

    select to_char(value::numeric, '9.EEEE') AS number_value, str_value from json; 1e-120
    

    这假设它们位于表中的不同字段中。如果不是,您需要更明确地说明您的设置。

    【讨论】:

    • 如果表中有一个字符串(json字符串)和一个数字(json数字)怎么办。您想一键阅读所有内容,但仍想正确格式化数字?
    • 如果每个 json 标量可以有不同的字段,则不需要使用 JSON 类型。我更新了我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多