根据PostgreSQL的文档VARCHAR
,VARCHAR(n)
和之间没有性能差异TEXT
。
我应该在名称或地址列中添加任意长度限制吗?
编辑:不是欺骗:
我知道这种CHAR
类型是过去的遗迹,我不仅对性能感兴趣,而且对诸如Erwin的其他利弊也很感兴趣。
根据PostgreSQL的文档VARCHAR
,VARCHAR(n)
和之间没有性能差异TEXT
。
我应该在名称或地址列中添加任意长度限制吗?
编辑:不是欺骗:
我知道这种CHAR
类型是过去的遗迹,我不仅对性能感兴趣,而且对诸如Erwin的其他利弊也很感兴趣。
Answers:
答案是否定的。如果可以避免,
请勿添加长度修饰符varchar
。大多数时候,您实际上并不需要长度限制。仅text
用于所有字符数据。varchar
如果您需要与没有的RDBMS保持兼容,请设置为(无长度修饰符)text
。
性能几乎是相同的- text
是在罕见的情况下,快一点,你保存后,对长度的检查周期。
如果您实际上需要强制使用最大长度,请仍然使用text
并为此添加检查约束:
ALTER TABLE tbl ADD CONSTRAINT tbl_col_len CHECK (length(col) < 51);
您可以随时修改或删除这样的约束,而不必弄乱表定义和所有相关对象(视图,函数,外键等)。
使用长度修饰符,您只会遇到诸如此类或此类或此类的问题 ...
PostgreSQL 9.1引入了一个新功能来减轻这种痛苦。我在这里引用发行说明:
允许
ALTER TABLE ... SET DATA TYPE
在适当的情况下避免表重写(Noah Misch,Robert Haas)例如,将
varchar
列转换为文本不再需要重写表。但是,增加varchar
列的长度约束 仍然需要重写表。
varchar(n)
毕竟,为了简单起见-如果不利因素通常不会影响您。(如果要强制实际的最大长度,则该限制不是任意的。)
如果您将长度限制视为一种检查约束,以确保您验证数据,则可以添加一个。事实上,你可能想不使用长度定义,而是一个真正的检查约束代替,使改变的极限速度。
要更改(增加)长度限制,您需要运行,ALTER TABLE
这可能需要很长时间才能完成(由于可能会重新写入表),在此期间需要排他的表锁定。
更改(即删除和重新创建)检查约束是一项非常简短的操作,仅需要读取表的数据,就不会更改任何行。因此,这将更快(这意味着排他表锁将被保留更短的时间)。
在操作过程中,a text
,a varchar
或一varchar(5000)
列之间没有任何区别。
问题特别是是否在VARCHAR列中添加了任意长度限制?
为此,答案就是“否”。没有什么可以像在支持varchar(max)
或使用约定的劣等数据库中那样添加任意限制的理由varchar(255)
。但是,如果规范解决了限制,我认为答案会变得更加复杂,尤其是在现代版本的PostgreSQL上。而且,为此,我倾向于YES。
我认为,如果规范要求,则限制是明智的选择。特别是对于更合理的工作量。如果没有其他原因,则保留元数据。
从我这里的答案,可以看出CHAR与VARCHAR(Postgres)的索引性能,在这里我处理了元数据的值。
如果我发现规范中包含有意义的可变长度文本键,并且相信可以拥有恒定的最大长度,那么我也会使用
varchar
。但是,我想不出符合该标准的任何东西。
如果VARCHAR
定期使用它们来存储非常大的字符串,则可能会出现性能差异,因为“长字符串会由系统自动压缩”和“非常长的值也存储在后台表中”。从理论上讲,这意味着对于非常长的字符串字段的大量请求将比对较短的字符串字段的请求慢。您可能永远不会遇到这个问题,因为名称和地址不会太长。
但是,根据您在数据库外部使用这些字符串的方式,您可能希望添加一个实际限制以防止滥用系统。例如,如果要在某处的表单上显示名称和地址,则可能无法在“名称”字段中显示整个文本段落,因此将“名称”列限制为500字符。
VARCHAR
是TEXT
Postgres中的纯语法糖,在存储处理方面差异为零;您提到的压缩与后台表存储是基于列中数据的实际长度而不是列元数据完成的。TEXT列在内部存储为varlena
C结构(这是一个可变长度数组,前4个字节存储创建/更新时的长度),并且正是此结构根据其长度进行了优化。