我已经开始研究一个项目,那里有一个相当大的表(大约82,000,000行),我觉得它非常臃肿。其中一个字段定义为:
consistency character varying NOT NULL DEFAULT 'Y'::character varying
它用作布尔值,值应始终为('Y'|'N')。
注意:没有检查约束等。
我正试图找出理由改变这个领域的理由。这就是我所拥有的:
以下是我的问题。
boolean
,它应该是1个字节,而对于UTF-8中的'Y'
也应该是1个字节(至少这是我在Python中检查长度时得到的)。这里是否还有其他存储空间可以保存?=TRUE
”与“='Y'
”的原因而获得任何性能提升吗?答案 0 :(得分:21)
PostgreSQL(与Oracle不同)有一个完全成熟的boolean
type。通常,“是/否标志”应为boolean
。这是正确使用的类型!
基本上,boolean
列在磁盘上占用 1个字节,
text
或character varying
(quoting the manual here)...
短字符串(最多126个字节)的存储要求是1个字节 加上实际的字符串
简单字符的 2个字节。因此,您可以将该列的存储减少一半。
实际存储比这更复杂。每个表有一些固定的开销,page and row,有特殊的NULL
storage,有些类型需要data alignment。整体影响将非常有限 - 如果有明显的话
More on how to measure actual space requirement.
编码UTF8
在这里没有任何区别。基本ASCII字符与LATIN-1
等其他编码位兼容。
在您的情况下,根据您的描述,您应该保留您似乎已经拥有的NOT NULL constraint - 与基本类型无关。
在任何情况下使用布尔值都会略胜一筹。除了略小,boolean
的逻辑更简单,varchar
或text
通常也有COLLATION特定规则。但对于那些简单的事情,不要期待太多。
而不是
WHERE consistency = 'Y'
你可以写:
WHERE consistency = TRUE
但是,实际上,你可以简化为:
WHERE consistency
无需进一步评估。
转换表格很简单:
ALTER TABLE tbl ALTER consistency TYPE boolean
USING CASE consistency WHEN 'Y' THEN TRUE ELSE FALSE END;
此CASE
表达式将非TRUE
('Y')的所有内容折叠为FALSE
。 NOT NULL约束只是保留。
答案 1 :(得分:2)
从单个VARCHAR切换到BOOLEAN,存储大小和查询性能都不会明显更好。虽然你说的是在使用布尔值时,在谈论二进制值时技术上更清晰,但改变的成本可能远高于收益。如果您担心正确性,那么您可以检查列,例如
ALTER TABLE tablename ADD CONSTRAINT consistency CHECK (consistency IN ('Y', 'N'));