• Postgresql支持的浮点类型和区别案例


    Postgresql提供四类浮点型,其中两类完全相同decimal、numeric;按功能看可以分成两类:

    • 精确型:decimal、numeric
    • 不精确型:read、double precision

    https://www.postgresql.org/docs/14/datatype-numeric.html
    在这里插入图片描述

    为什么说不精确呢?因为数据类型成功插入后,查询出来值可能和你插入的值不一样,原因是长度截断和四舍五入。
    精确类型不会发生截断且如果超长了直接报错,主要插入成功了,查出来的一定等于插入的结果。

    看下具体例子:

    real:【不精确类型】【定长类型】PG10:六位有效数字,会四舍五入(PG14八位有效数字)

    create table f1 (a real);
    insert into f1 values (1.23456789);
    insert into f1 values (1234.23456789012345);
    insert into f1 values (123456.23456789);
    insert into f1 values (123456.23456789012345);
    select * from f1;
        a    
    ---------
     1.23457
     1234.23
      123456
      123456
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    double:【不精确类型】【定长类型】PG10:十五位有效数字,会四舍五入(PG14十七位有效数字)

    create table f2 (a double precision);
    insert into f2 values (123456789.123456789);
    insert into f2 values (1.1234567890123456789);
    insert into f2 values (12345678901234567890.1234567890123456789);
    select * from f2;
              a           
    ----------------------
         123456789.123457
         1.12345678901235
     1.23456789012346e+19
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    decimal / numeric:【精确类型】【变长类型】不会四舍五入,最高小数点前131072位,以及小数点后16383位,超出报错:ERROR: value overflows numeric format

    create table f3 (a decimal);
    insert into f3 values (123456789.123456789);
    insert into f3 values (1.1234567890123456789);
    insert into f3 values (12345678901234567890.1234567890123456789);
    insert into f3 values (12345678901234567890.12345678901234567890123456789012345678901234567890);
    select * from f3;
                                       a                                    
    ------------------------------------------------------------------------
                                                        123456789.123456789
                                                      1.1234567890123456789
                                   12345678901234567890.1234567890123456789
     12345678901234567890.1234567890123456789012345678901234567890123456789
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    从存储角度看,real、double是定长类型,decimal / numeric是变长类型。

    在构造tuple时,计算数据长度会走不同分支:
    《Postgresql源码(58)元组拼接heap_form_tuple剖析》

    	real类型长度计算:定长计算方法
    		heap_compute_data_size
    			data_length = att_align_datum(data_length, atti->attalign, atti->attlen, val);
    			data_length = att_addlength_datum(data_length, atti->attlen, val);
     
    	decimal类型长度计算:变长计算方法
    		heap_compute_data_size
    			if (ATT_IS_PACKABLE(atti) && VARATT_CAN_MAKE_SHORT(DatumGetPointer(val)))
    				data_length += VARATT_CONVERTED_SHORT_SIZE(DatumGetPointer(val));
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    K8S集群搭建(多master单node)
    nginx的使用
    详解.NET依赖注入中对象的创建与“销毁”
    Java回顾-网络编程
    PostgreSQL数据库动态共享内存管理器——dynamic shared memory segment
    微信支付(小程序)-java实现与小程序实现
    警惕Faust勒索病毒的最新变种faust,您需要知道的预防和恢复方法。
    戳进来,带你走近飞凌嵌入式旗舰级AIoT芯RK3588开发板
    AndroidAuto PCTS A118解决杂音问题
    YOLOv5算法改进(22)— 更换主干网络MobileNetv3 + 添加CA注意力机制
  • 原文地址:https://blog.csdn.net/jackgo73/article/details/126303459