根据PostgreSQL的文档,VARCHARVARCHAR(n)TEXT之间没有性能差异。

我应该在名称或地址列中添加任意长度限制吗?

编辑:




当所有值均为36个字符时,使用char vs varchar可使索引查找明显更快我不仅对性能感兴趣,还对Erwin等其他利弊表示了惊讶。

#1 楼

答案是否定的。
Postgres Wiki中的相关建议。
如果不需要,请不要在varchar上添加长度修饰符。 (大多数时候,您不需要。)只需对所有字符数据使用text。如果需要与没有varchar作为通用字符串类型的RDBMS保持兼容,请使text(标准SQL类型)不带长度修饰符。并保存检查长度的周期。相关:

使用数据类型“文本”存储字符串的任何缺点?仍然考虑具有text约束的varchar(n),例如: )。并且您可以在(相同)约束中强制执行其他要求。
长度修饰符用于引起诸如此类或此类或此类问题...
PostgreSQL 9.1引入了一项新功能以减轻某种痛苦。发行说明:

允许text避免在适当的情况下表重写(Noah Misch,Robert Haas)
例如,将CHECK列转换为文本不再需要< br重写表。但是,增加对
ALTER TABLE ... SET DATA TYPE列的长度限制仍然需要重写表。

评论


我认为,如果只是“不对真实的数据库添加任何限制”,那么答案会更好。我觉得很多答案都需要更正和进一步的信息,但这完全是题外话,会分散您的结论,我完全同意。

–埃文·卡洛尔(Evan Carroll)
18-3-18的2:22

是的,所有内容均基于9.1-6年前的Postgres版本。到现在有点尘土飞扬,但基本建议仍然不错。

–欧文·布兰德斯特(Erwin Brandstetter)
18-3-25在21:30



为每个文本列添加检查约束以进行健全性检查并确保客户端中的错误不会通过插入很大的文本来耗尽数据库的所有磁盘空间,是个好主意还是坏主意?

–代码
19年1月2日,19:21



@Code:这是一个可行的选择。如果您有许多具有相同约束的列,请考虑域。还是为了简单起见,毕竟是varchar(n)-如果缺点通常不会影响您。 (如果要强制实际的最大长度,则该限制不是任意的。)

–欧文·布兰德斯特(Erwin Brandstetter)
19年1月2日,19:51



#2 楼

如果您将长度限制视为一种检查约束,以确保您验证数据,则可以添加一个。实际上,您可能不希望使用长度定义,而是使用实际的检查约束,以便更快地更改限制。

要更改(增加)长度限制,您需要运行ALTER TABLE,这可能需要很长时间才能完成(由于可能会重写表),在此期间需要排他的表锁定。

更改(即删除和重新创建)检查约束是非常简短的操作,只需要读取表的数据,就不会更改任何行。这样会更快(这意味着排他的表锁将保留更短的时间)。

在操作过程中,textvarcharvarchar(5000)列。

评论


出于好奇,您为什么认为在捕获数据时无法在客户端应用程序上执行此长度检查?

– PirateApp
18年3月13日在12:35

@PirateApp:因为经常会有一个以上的应用程序或一些外部数据源(想想每晚批量导入)。几乎所有数据库(和数据)的寿命都比一个应用程序长。

– a_horse_with_no_name
18-3-13在12:38



#3 楼

问题特别是是否在VARCHAR列中添加了任意长度限制?对此,答案就是“否”。没有什么可以像在支持varchar(max)的劣等数据库或使用诸如varchar(255)这样的约定的低级数据库中添加任意限制一样合理的。但是,如果规范解决了限制,我认为答案会变得更加复杂,尤其是在现代版本的PostgreSQL上。而且,为此,我倾向于YES。

我认为,如果规格要求,则限制是明智的选择。特别是对于更合理的工作量。如果没有其他原因,那么要保留元数据。 br />
如果我发现规范中包含有意义的可变长度文本键,并且我相信它具有恒定的最大长度,那么我也会使用varchar。但是,我想不出符合该标准的任何方法。


#4 楼

如果VARCHAR经常用于存储非常大的字符串,则可能会出现性能差异,因为“长字符串会由系统自动压缩”和“非常长的值也存储在后台表中”。从理论上讲,这意味着对非常长的字符串字段的大量请求将比对较短的字符串字段的请求慢。您可能永远不会遇到这个问题,因为名称和地址不会太长。

但是,根据您在数据库外部使用这些字符串的方式,您可能希望添加一个实际限制以防止滥用系统。例如,如果要在某处的表单上显示名称和地址,则可能无法在“名称”字段中显示整个文本段落,因此将“名称”列限制为500字符。

评论


AFAIK在TOASTing varchar和text字段中没有区别。

– dezso
2012年7月16日在18:33

VARCHAR纯粹是Postgres中TEXT的语法糖,存储处理方面的差异为零;您提到的压缩与后台表存储是基于列中数据的实际长度而不是列元数据完成的。 TEXT列在内部存储为varlena C结构(这是一个可变长度数组,前4个字节存储创建/更新时的长度),正是此结构根据其长度进行了优化。

–考伯特
17年8月27日在20:31



或第一个字节存储小于128个字节的字符串的长度。

–詹森
20-2-17在1:17