PostgreSQL记录中的null值是如何存储的
2020-10-27 09:10 abce 阅读(1625) 评论(0) 编辑 收藏 举报
PostgreSQL如何存储null值的?
PostgreSQL存储null值的方法
使用pageinspact工具来观察null是如何存储的。执行下面的测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | postgres=# create table t(i int , j int , k int ); CREATE TABLE postgres=# insert into t values (8,1,6); INSERT 0 1 postgres=# insert into t values (3, NULL ,7); INSERT 0 1 postgres=# insert into t values (4,9,2); INSERT 0 1 postgres=# select lp,t_infomask,t_bits,t_data from heap_page_items(get_raw_page( 't' , 0)); lp | t_infomask | t_bits | t_data ----+------------+----------+---------------------------- 1 | 2048 | | \x080000000100000006000000 2 | 2049 | 10100000 | \x0300000007000000 3 | 2048 | | \x040000000900000002000000 (3 rows ) postgres=# |
可以看到,null值没有在元组的数据部分标记出来。
同时,可以看到带有null值的第二条记录的't_infomask'和’t_bits‘的值与第一条和第三条是不一致的。因此,这可能就是如何读取null值的秘密所在。
‘t_bits’是一个uint8的数组,当元组中没有null值的时候,t_bits可以被认为是空的,当元组有null值的列时,t_bits使用一个位(bit)来表示一个列是否为null。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | postgres=# create table t0(i1 int ,i2 int ,i3 int ,i4 int ,i5 int ,i6 int , postgres(# i7 int ,i8 int ,i9 int ,i10 int ,i11 int ,i12 int postgres(# ); CREATE TABLE postgres=# insert into t0 values (1,2,3,4,5,6,7,8,9,10, NULL ,12); INSERT 0 1 postgres=# insert into t0 values (1,2,3,4,5,6,7,8,9, NULL , NULL ,12); INSERT 0 1 postgres=# insert into t0 values (1,2,3,4,5,6,7,8, NULL , NULL , NULL ,12); INSERT 0 1 postgres=# insert into t0 values (1,2,3,4,5,6,7,8,9,10,11,12); INSERT 0 1 postgres=# postgres=# select lp,t_infomask,t_bits from heap_page_items(get_raw_page( 't0' , 0)); lp | t_infomask | t_bits ----+------------+------------------ 1 | 2049 | 1111111111010000 2 | 2049 | 1111111110010000 3 | 2049 | 1111111100010000 4 | 2048 | (4 rows ) postgres=# |
上面的脚本会创建一个表t0,共有12个列,然后插入几条元组,执行pageinspect工具查询研究元组。注意看元组的t_bits值:
可以得出结论:
·在t_bits中,尚未使用的标记为是0
·1表示对应的列是非空的(not null),否则就是null
在PostgreSQL中,表的列被删除后,这个列的数据结构会被保留在目录中,但是对用户是不可见的。完成下面的测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | postgres=# alter table t0 drop column i1; ALTER TABLE postgres=# insert into t0 values (2,3,4,5,6,7,8,9,10,11,12); INSERT 0 1 postgres=# select lp,t_infomask,t_bits from heap_page_items(get_raw_page( 't0' , 0)); lp | t_infomask | t_bits ----+------------+------------------ 1 | 2049 | 1111111111010000 2 | 2049 | 1111111110010000 3 | 2049 | 1111111100010000 4 | 2048 | 5 | 2049 | 0111111111110000 (5 rows ) postgres=# |
在这个测试中,我们删除了表t0的列'i1'并插入一个不含有null值的记录。使用pageinspact工具,我们可以发现插入的不含有null值的数据(lp=5)。被删除的列的t_bits值显示其也被认为是null值。
结论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)