我在Oracle Linux Server 6.3版上使用PostgreSQL 9.2。
根据the storage layout documentation,页面布局包含:
我测试它以制作一些公式来估计预期的表格大小......(TOAST概念可能会被忽略。)
postgres=# \d t1;
Table "public.t1"
Column ',' Type ',' Modifiers
---------------+------------------------+------------------------------
code |character varying(8) |not null
name |character varying(100) |not null
act_yn |character(1) |not null default 'N'::bpchar
desc |character varying(100) |not null
org_code1 |character varying(3) |
org_cole2 |character varying(10) |
postgres=# insert into t1 values(
'11111111', -- 8
'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111', <-- 100
'Y',
'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111', <-- 100
'111',
'1111111111');
postgres=# select * from pgstattuple('t1');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
8192 | 1 | 252 | 3.08 | 1 | 252 | 3.08 | 7644 | 93.31
(1 row)
为什么tuple_len
252而不是249? (&#34;所有列的222字节&#39;最大长度&#34; PLUS
&#34; 27个字节的元组头后跟一个可选的空位图,一个可选的对象ID字段和用户数据&#34;)
3个字节来自哪里?
我的配方有问题吗?
答案 0 :(得分:5)
您的计算在几个点上都已关闭。
varchar
,text
(和character
!)的存储空间大小为quoting the manual):短字符串(最多126个字节)的存储要求是 1个字节 加上实际的字符串,其中包括案例中的空格填充 性格。较长的字符串有4个字节的开销而不是1个字节。 系统会自动压缩长字符串,所以 磁盘上的物理要求可能会更低。
大胆强调我的评论中的问题。
HeapTupleHeader occupies 23 bytes。但是每个元组(&#34; item&#34; - 行或索引条目)在数据页的开头都有一个 项标识符 ,总计在上面提到的27个字节。区别是相关的,因为实际用户数据从每个项目的开头以MAXALIGN
的倍数开始,并且项目标识符不计入此偏移量 - 以及实际的&#34;元组大小&#34;
由于数据对齐而导致的1字节填充(8的倍数),在这种情况下用于NULL位图。
类型varchar
没有填充(但上面提到的附加字节)
因此,实际计算(所有列都填充到最大值)是:
23 -- heaptupleheader
+ 1 -- NULL bitmap (or padding if row has NO null values)
+ 9 -- columns ...
+ 101
+ 2
+ 101
+ 4
+ 11
-------------
252 bytes
+ 4 -- item identifier at page start
相关:
您可以在这些答案右侧的链接列表中找到更多内容。