Vil*_*lx- 20 size varchar database-design nvarchar
在关于TDWTF的一个稍微激烈的讨论中,出现了一个关于DB中varchar列大小的问题.
例如,取一个包含人名(仅名称,无姓)的字段.很容易看出它不会很长.大多数人的名字少于10个字符,少数是20以上的人.如果你要制作你的专栏,比如varchar(50),它肯定会拿到你遇到的所有名字.
但是对于大多数DBMS而言,无论是制作varchar(50)还是varchar(255),它的大小或速度都没有区别.
那么为什么人们试图让他们的列尽可能小?我知道在某些情况下你可能确实想要限制字符串的长度,但大多数情况并非如此.如果有一个名字极长的人的罕见情况,那么更大的利润只会是有益的.
对于MSSQL: http://msdn.microsoft.com/en-us/library/ms176089.aspx
存储大小是输入的实际数据长度+ 2个字节.
对于MySQL: http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html
如果列值需要0 - 255个字节,则为L + 1个字节;如果值可能需要超过255个字节,则为L + 2个字节
我找不到Oracle的文档,而且我没有使用过其他DBMS.但我没有理由相信它有任何不同.
小智 21
我只能代表甲骨文.如果输入值"SMITH",VARCHAR2(50)和VARCHAR2(255)将占用完全相同的空间量并执行相同的操作.
但是,为什么将所有文本列声明为VARCHAR2(4000)通常不是一个好主意的原因是列长度实际上是另一个约束.约束是业务规则的数据库实现,因此它们肯定是应该在数据库方面定义的东西.
作为一个例子.您可以在列上定义CHECK约束,以便它可以接受的值仅为"Y"和"N".这使您的应用程序不必处理'y'和'n'甚至'1'和'0'.检查约束可确保您的数据符合预期标准.然后,您的应用程序代码可以对其必须处理的数据的性质做出有效假设.
列长度定义在同一条船上.你声明一些东西是VARCHAR2(10),因为你不希望它接受'ABC123ZYX456'的条目(无论出于何种原因!)
在澳大利亚,我将STATE列定义为varchar2(3)因为我不希望人们输入"新南威尔士"或"南澳大利亚".列定义几乎迫使它们作为"NSW"和"SA"输入.从这个意义上讲,VARCHAR2(3)几乎与实际指定CHECK IN('NSW','SA','VIC'等)约束一样是一个检查约束.
简而言之,正确的列长度是编码业务规则的一种方式.它们是另一种形式的约束.它们带来了约束的所有优点(并且遭受许多相同的缺点).并且他们在很小程度上确保了一定程度的"数据清洁度","适当的"约束也有助于实现.
我也不买这个论点,最好在客户端应用程序中粘贴这些东西,因为它更容易在那里进行更改.您有20,000人使用应用程序,即20,000次更新.你有一个数据库,这是一个更新."更容易更改客户端应用程序"参数(如果为true)可能意味着数据库只会被视为一个巨大的桶,其中所有聪明的逻辑都在客户端代码中处理.这是一个很大的讨论,但由于所有RDBMS都允许您在数据库本身中定义约束等,因此很明显至少有一个值得做的事情,即这种基本逻辑属于后端.
我听说查询优化器确实考虑了varchar长度,虽然我找不到引用.
定义varchar长度有助于传达意图.定义的约束越多,数据越可靠.