varchar(n) 大小?

d4b*_*bbi 2 postgresql varchar storage memory database-internals

varchar(5)当我在查询中使用时INSERT,这意味着表中的属性将在内存中占用5 个字节?(假设一个可打印字符占用一个字节)?

Erw*_*ter 6

事情没那么简单。

\n

in只是允许的字符上限(不是字节!)nvarchar(n)仅存储实际字符串,而不填充到允许的最大大小。这与基本上过时的、空白填充的数据类型相反char(n),后者始终存储最大长度。

\n

每个字符可以占用一个或多个字节,具体取决于字符和编码。常见的UTF-8编码为1-4个字节,只有基本的ASCII字符才占用一个字节。您谈到“可打印字符”,但这微不足道。可打印字符仍可占用 1-4 个字节。

\n

a_horse 手册中的引用是指 varlena 类型(包括varchar“在磁盘上”的存储(几乎不再使用任何磁盘。这同样适用于 RAM 中的临时表。所以“在表格存储中”,真的。) 。对于最多 126 个字节(不是字符!),开销减少到单个字节。源代码谈到“打包”格式。并且此格式中没有额外的对齐填充:违反了 varlena 类型的标称“int”对齐。

\n

但你说的是“在记忆中”。在 RAM 中,一旦从存储的行中提取了值,开销始终为 4 个字节- 无“压缩”格式。所有 varlena 类型都需要“int”对齐,这可能会添加1 到 3 个字节的 padding

\n

并且NULL存储有它自己的规则。看:

\n\n

所以,这些字符串的基本存储要求varchar(5)是:

\n“在磁盘上”\n

NULL... 1 位(通常)
\n \'\'... 1 字节
\n \'foo\'... 4 字节
\n \'Motor\'... 6 字节
\n \'Mot\xc3\xb6r\'... 7 字节
\n \'Mot\xc3\xb6rhead\' ... 仍然是 7 个字节,作为显式转换为varchar(5)截断为 \'Mot\xc3\xb6r\'

\n“在内存中”\n

NULL...?
\n \'\'... 4 个字节
\n \'foo\'... 7 个字节
\n \'Motor\'... 9 个字节
\n \'Mot\xc3\xb6r\'... 10 个字节
\n \'Mot\xc3\xb6rhead\' ... 仍然是 10 个字节,作为显式转换以varchar(5)截断为 \'Mot\xc3\ xb6r\'

\n

另外,可能还有对齐填充。

\n

看:

\n\n