我想从Postgres文档中询问有关varchar(n)
类型的片段的含义:
短字符串(最多126个字节)的存储要求是1个字节加上实际的字符串,其中包括在字符情况下的空格填充。较长的字符串的开销为4个字节,而不是1个字节。
假设我有一个varchar(255)
字段。现在,以下语句:
- 如果此字段包含10个字节的字符串,则开销为1个字节。因此该字符串将使用11个字节。
- 如果该字段使用140个字节保存字符串,则开销为4个字节。因此该字符串将使用144个字节。
我想从Postgres文档中询问有关varchar(n)
类型的片段的含义:
短字符串(最多126个字节)的存储要求是1个字节加上实际的字符串,其中包括在字符情况下的空格填充。较长的字符串的开销为4个字节,而不是1个字节。
假设我有一个varchar(255)
字段。现在,以下语句:
Answers:
毫不奇怪,该手册是正确的。但是还有更多。
例如,磁盘上的大小(在任何表中,即使未实际存储在磁盘上)也可能与内存中的大小不同。在磁盘上,如手册中所述,短varchar
值(最多126个字节)的开销减少为1个字节。但是内存中的开销始终为4个字节(一旦提取了各个值)。
同样是真正的text
,varchar
,varchar(n)
或char(n)
-除了char(n)
是填补空白的,以n
人物和你通常不希望使用它。它的有效大小在多字节编码中仍然可以变化,因为它n
表示最大字符数,而不是字节数:
字符串
n
,长度不超过字符(不是字节)。
它们都在varlena
内部使用。
"char"
(带有双引号)是另一种生物,并且始终占用一个字节。
未类型化的字符串文字('foo'
)具有单个字节的开销。不要与类型化的值混淆!
用测试pg_column_size()
。
CREATE TEMP TABLE t (id int, v_small varchar, v_big varchar);
INSERT INTO t VALUES (1, 'foo', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');
SELECT pg_column_size(id) AS id
, pg_column_size(v_small) AS v_small
, pg_column_size(v_big) AS v_big
, pg_column_size(t) AS t
FROM t
UNION ALL -- 2nd row measuring values in RAM
SELECT pg_column_size(1)
, pg_column_size('foo'::varchar)
, pg_column_size('12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar)
, pg_column_size(ROW(1, 'foo'::varchar, '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar));
id | v_small | v_big | t
----+---------+-------+-----
4 | 4 | 144 | 176
4 | 7 | 144 | 176
如你看到的:
integer
没有开销(但是有对齐要求,可能会造成填充)。varchar
仍然只有1个字节,而尚未从行中提取出来-从行大小可以看出。(这就是为什么有时候选择整行要快一些的原因。)有关: