在PostgreSQL中将varchar更改为boolean

时间:2012-10-10 16:41:56

标签: postgresql database-design query-optimization storage postgresql-9.1

我已经开始研究一个项目,那里有一个相当大的表(大约82,000,000行),我觉得它非常臃肿。其中一个字段定义为:

consistency character varying NOT NULL DEFAULT 'Y'::character varying

它用作布尔值,值应始终为('Y'|'N')。

注意:没有检查约束等。

我正试图找出理由改变这个领域的理由。这就是我所拥有的:

  • 它被用作布尔值,所以就这样吧。显式优于隐式。
  • 它可以防止编码错误,因为现在有任何可以转换成文本的内容都会盲目地存在。

以下是我的问题。

  • 尺寸/存储怎么样? db是UTF-8。所以,我认为在这方面确实没有多少节省。对于boolean,它应该是1个字节,而对于UTF-8中的'Y'也应该是1个字节(至少这是我在Python中检查长度时得到的)。这里是否还有其他存储空间可以保存?
  • 查询效果? Postgres会因“=TRUE”与“='Y'”的原因而获得任何性能提升吗?

2 个答案:

答案 0 :(得分:21)

PostgreSQL(与Oracle不同)有一个完全成熟的boolean type。通常,“是/否标志”应为boolean。这是正确使用的类型!

尺寸/存储怎么样?

基本上,boolean列在磁盘上占用 1个字节
textcharacter varyingquoting 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的逻辑更简单,varchartext通常也有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'));