我应该为 VARCHAR 列添加任意长度限制吗?

Dan*_*dio 55 postgresql performance datatypes varchar

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

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

编辑:不是欺骗:

我知道这种CHAR类型是过去的遗物,我不仅对性能感兴趣,而且对其他优缺点感兴趣,例如 Erwin 在他惊人的回答中所述。

Erw*_*ter 78

答案是否定的

Postgres Wiki 中的相关建议。

varchar如果不需要,请不要添加长度修饰符。(大多数情况下,您不需要。)仅text用于所有字符数据。作出这样的varchar(标准SQL类型),而长度修改,如果你需要留与不具备RDBMS兼容text的通用字符串类型。

性能几乎是一样的,text在罕见的情况下,快一点,你保存周期对长度的检查。有关的:

如果您确实需要强制执行最大长度,这varchar(n)是一个有效的选择,但我仍然会考虑text使用以下CHECK约束

ALTER TABLE tbl ADD CONSTRAINT tbl_col_len CHECK (length(col) < 51);
Run Code Online (Sandbox Code Playgroud)

您可以随时修改或删除此类约束,而不必弄乱表定义和依赖对象(视图、函数、外键等)。并且您可以在(相同)约束中强制执行其他要求。

长度修饰符用于引起类似这样这样这样的问题......

PostgreSQL 9.1 引入了一个新特性来缓解一些痛苦。发行说明:

允许ALTER TABLE ... SET DATA TYPE在适当的情况下避免表重写(Noah Misch,Robert Haas)

例如,将varchar列转换为文本不再需要重写表。但是,增加varchar列的长度约束 仍然需要重写表。

更多问题varchar(n)已在以后的版本中修复。

  • 我认为如果只是“不,不要向真实的数据库添加任意限制”,这个答案会好得多。我觉得这个答案的很多内容都需要更正和进一步的信息,但这完全偏离了主题,并且会分散你对我完全同意的结论的注意力。 (3认同)
  • @Code:这是一个可行的选择。如果您有许多具有相同约束的列,请考虑 [域](https://www.postgresql.org/docs/current/sql-createdomain.html)。或者`varchar(n)` 毕竟,为了简单起见 - 如果缺点通常不会影响你。(如果您想强制执行实际的最大长度,则在您的情况下该限制不是 *任意的*。) (2认同)

a_h*_*ame 13

如果您将长度限制视为一种检查约束以确保您验证数据,那么是添加一个。事实上,你可能想使用长度定义,而是一个真正的检查约束代替,使改变的极限速度。

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

更改(即删除和重新创建)检查约束是一个非常简短的操作,只需要读取表的数据,不会更改任何行。所以这会快很多(这反过来意味着排他表锁的持有时间要短得多)。

在操作期间,a text、avarcharvarchar(5000)列之间没有任何区别。

  • @PirateApp:因为通常会有多个应用程序或一些外部数据源(想想每晚批量导入)。而且几乎总是数据库(和数据)比一个应用程序的寿命更长。 (5认同)