我的同事程序员对他的团队领导有一个奇怪的要求;他坚持要创建长度为16 * 2 n 的varchar
列。
这种限制有什么意义?
我可以假设短字符串(例如少于128个字符)直接存储在表的记录中,从这个角度来看,限制将有助于对齐记录中的字段,更大的字符串存储在数据库中“heap”,只有对该字符串的引用保存在表记录中。
是这样吗?
此要求是否具有合理的背景?
BTW,DBMS是SQL Server 2008。
答案 0 :(得分:23)
据我所见,完全没有意义的限制。假设标准FixedVar
格式(与行/页面压缩或稀疏列使用的格式相反)并假设您正在讨论varchar(1-8000)
列
所有varchar
数据都存储在行的末尾,位于可变长度部分(如果它不能放入行中,则存储在offrow页面中)。它在该部分中消耗的空间量(以及它是否在行外结束)完全取决于实际数据的长度而不是列声明。
SQL Server将在分配内存时使用列声明中声明的长度(例如,用于sort
操作)。它在该实例中的假设是varchar
列将为filled to 50% of their declared size on average,因此在选择大小时,这可能是更好的选择。
答案 1 :(得分:4)
您应始终将数据存储在与存储数据相匹配的数据大小中。它是数据库如何保持完整性的一部分。例如,假设您正在存储电子邮件地址。如果您的数据大小是允许的最大电子邮件地址的大小,那么您将无法存储大于该数据的错误数据。这是一件好事。有些人想要制作nvarchar(max)或varchar(max)。但是,这只会导致索引问题。
就我个人而言,我会回到提出此要求的人并询问原因。然后我会提出我的原因,为什么它可能不是一个好主意。我永远不会盲目地实施这样的事情。在推迟这样的要求时,我首先会研究SQL Server如何在磁盘上组织数据,因此我可以展示需求可能对性能产生的影响。我甚至可能会惊讶地发现这个要求是有道理的,但我现在对此表示怀疑。
答案 2 :(得分:4)
之前我听说过这种做法,但在研究了这个问题后,我认为将varchar值设置为16的倍数并不存在实际原因。我认为这个要求可能来自于尝试优化使用的空间在每个页面上。在SQL Server中,页面设置为每页8 KB。行存储在页面中,因此,如果每行的大小均匀分配为8 KB,则可以节省页面空间(可以找到有关SQL Server如何存储数据的更详细说明here) 。但是,由于varchar字段使用的空间量由其实际内容决定,我不知道如何使用16的倍数或任何其他方案的长度可以帮助您优化页面上每行使用的空间量。 varchar字段的长度应该设置为业务要求所指示的范围。
此外,这个问题涵盖了类似的理由,结论似乎也是一样的:
Database column sizes for character based data