Database design (n)varchar列的大小是多少?

Database design (n)varchar列的大小是多少?,database-design,size,varchar,nvarchar,Database Design,Size,Varchar,Nvarchar,在一个数据库中,出现了一个关于varchar列大小的问题 例如,假设一个字段包含一个人的名字(只有名字,没有姓氏)。很容易看出它不会很长。大多数人的名字少于10个字符,20个以上的人很少。如果你想让你的专栏,比如说,varchar(50),它肯定会包含你遇到的所有名字 然而,对于大多数DBMS来说,无论您使用varchar(50)还是varchar(255),在大小或速度上都没有区别 那么,为什么人们要把他们的专栏尽量缩小呢?我知道在某些情况下,您可能确实希望对字符串的长度进行限制,但大多数情况

在一个数据库中,出现了一个关于varchar列大小的问题

例如,假设一个字段包含一个人的名字(只有名字,没有姓氏)。很容易看出它不会很长。大多数人的名字少于10个字符,20个以上的人很少。如果你想让你的专栏,比如说,varchar(50),它肯定会包含你遇到的所有名字

然而,对于大多数DBMS来说,无论您使用varchar(50)还是varchar(255),在大小或速度上都没有区别

那么,为什么人们要把他们的专栏尽量缩小呢?我知道在某些情况下,您可能确实希望对字符串的长度进行限制,但大多数情况下并非如此。只有在罕见的人名过长的情况下,更大的差距才是有益的


补充道:人们希望引用“大小和速度没有差别”的说法。好啊这是:

对于MSSQL:

存储大小是输入的数据的实际长度+2字节

对于MySQL:

如果列值需要0–255字节,则为L+1字节;如果列值可能需要超过255字节,则为L+2字节

我找不到Oracle的文档,也没有使用过其他DBMS。但是我没有理由相信那里有什么不同。

那么为什么人们要尽量把他们的专栏缩小呢?我不相信把它们做得尽可能小,但要适当地调整尺寸。使(n)Varchar变小而不是变大的一些原因:

1) 对于较大的字段,所有使用数据库的客户端都必须能够处理完整大小的数据。例如,以一个每个字段包含255个字符的美国地址的系统为例:(我相信类似于您引用的TDWTF)

  • 名字
  • 地址行1
  • 地址行2
  • 城市
  • 陈述
  • 邮政编码
现在,您的数据输入屏幕需要允许并显示每个字段255个字符。这并不难,但在打印发票的较大字段时看起来不太好看,您将需要换行逻辑来处理较大的字段。取决于工具,不是那么难

但我不希望信封的地址格式出现问题,因为信封中的每个字段或其中任何一个字段都可能包含255个字符。如果字段太长而无法容纳,是否要截断?伟大的人有地址行1“房屋号街道号…等等…111号公寓。”你会删掉重要的公寓号。你要打包吗?多少钱?如果你不能把它放进信封上的小盒子里怎么办?提出一个例外,并让某人亲自写信

2) 虽然varchar(50)与varchar(255)中保存的10个字符的数据不会影响大小或速度,但允许255个字符可以占用更多的空间。如果所有字段都那么大,则可能会达到SQLServer2000中的大小限制。(我还没有读过2005年和2008年的文章,看看他们是否能处理超过一页的行。)而对于Oracle,如果有人实际使用了所有可用字符,那么更大的大小允许行链接发生

3) 索引的大小限制比叶页更严格。如果您创建的varchar太大,您可能会排除索引,尤其是复合索引



另一方面,我的地址有一个长长的第1行,我对不允许键入完整内容的网站感到失望。

我听说查询优化器确实考虑了varchar长度,尽管我找不到参考


定义varchar长度有助于传达意图。定义的约束越多,数据就越可靠。

我将用一个问题来回答您的问题:如果varchar(50)和varchar(255)之间的DBMS没有区别,为什么DBMS会让您进行区分?为什么DBMS不简单地说“使用varchar最多可使用xxx个字符,使用text/clob/等任何字符。”当然,也许Microsoft/Oracle/IBM出于历史原因可能会保留长度定义,但对于像MySQL这样具有多个存储后端的DBMS,又如何呢?为什么每个DBMS都实现可定义的字符列长度

我只能为甲骨文说话。如果输入值“SMITH”,则VARCHAR2(50)和VARCHAR2(255)占用的空间量完全相同,并且执行相同的操作

然而,将所有文本列声明为VARCHAR2(4000)通常不是一个好主意的原因是,实际上,列长度是另一个约束。约束是业务规则的数据库实现,因此它们肯定是应该在数据库方面定义的东西

例如,。在列上定义检查约束,使其可以接受的值仅为“Y”和“N”。这样,应用程序就不必处理“y”和“n”甚至“1”和“0”。检查约束可确保数据符合预期标准。然后,应用程序代码可以对它必须处理的数据的性质做出有效的假设

列长度定义在同一条船上。您将某物声明为VARCHAR2(10),因为您不希望它接受“ABC123ZYX456”条目(无论出于何种原因!)

在澳大利亚,我将STATE列定义为varchar2(3),因为我不希望人们键入“新南威尔士”或“南澳大利亚”。列定义几乎强制将它们输入为“NSW”和“SA”。从这个意义上讲,VARCHAR2(3)几乎与实际指定签入(NSW’、‘SA’、‘VIC’等)约束一样是一个检查约束

简而言之,适当的列长度是编码业务规则的一种方式。它们是另一种形式的约束。它们带来了约束的所有优点(也有许多相同的缺点)。他们确保,t