为什么不将每个VARCHAR指定为VARCHAR(65535)?

时间:2011-10-04 19:25:36

标签: mysql

由于Varchar字段的存储要求是基于输入字符串的实际长度,因此将每个Varchar字段指定为最大可能值的缺点是什么:Varchar(65535)?好吧,除了最大字段的1个额外字节> 255个字符?

[存储需要长度为L的字符串:如果列值需要0 - 255字节,则为L + 1个字节,如果值可能需要超过255个字节,则为L + 2个字节]

谢谢!

5 个答案:

答案 0 :(得分:13)

documents - 表列计数和行大小限制:

  

每个表(无论存储引擎如何)的最大行大小为65,535字节。存储引擎可能会对此限制设置其他约束,从而减少有效的最大行大小。

     

最大行大小会限制列的数量(可能是大小),因为所有列的总长度不能超过此大小。例如,utf8字符每个字符最多需要三个字节,因此对于CHAR(255)CHARACTER SET utf8列,服务器必须为每个值分配255×3 = 765个字节。因此,一个表不能包含超过65,535/765 = 85个这样的列。

     

可变长度列的存储包括长度字节,根据行大小进行评估。例如,VARCHAR(255)CHARACTER SET utf8列需要两个字节来存储值的长度,因此每个值最多可占用767个字节。

因此,定义单个VARCHAR(65535)列会有效地限制您使用该行上的单列(假设您已将其填满)。

所有这一切除了这样一个大尺寸对于某些类型的数据是完全错误的事实 - 如果你有一个可能包含本地和国际号码的电话号码列,你可以选择使用VARCHAR字段这样做,但将其设置为20以上的任何东西都可能毫无意义(我很慷慨)。

请参阅Bill Karwin的this answer,如果临时表格生成不必要的VARCHAR字段(与此类字段转换为CHAR并再次返回),则表示可能会造成性能损失 - 请参阅帖子了解详情)。

答案 1 :(得分:7)

我认为varchar列长度不仅仅与存储有关。它们也与数据语义有关。

即。将name列指定为varchar(100)表示存储在系统中的名称不得超过100个字符。

在存储方面,它们应该是相同的。虽然行数大小估计在varchar列的特定长度上更准确,没有它们(不需要统计数据收集系统保持varchar大小的数据分布)。

答案 2 :(得分:1)

一个可能的原因是改善与其他应用程序的兼容性。例如,如果您的应用程序使用了100个字符长的“product_no”字段,并且您希望与使用类似字段的应用程序(如40个字符长的“model_no”)进行交互,则会很麻烦。您的应用中超过40个字符的任何product_nos都会被截断,您必须找到一些方法在应用程序之间进行翻译。

答案 3 :(得分:0)

一个原因是该字段的大小是对输入数据的检查。你真的想要有人输入1000个字符的电话号码吗?字段太大是保证将垃圾输入数据库的一种方法。您将有电话号码说明(例如不随机拍摄):

“只与前台的大金发女郎交谈”

而不是真实的电话号码或电子邮件字段,其中包含有关客户的备注,因为它们没有备注字段?当您尝试向其发送电子邮件时,这种方法效果不佳。

宽表可能会在数据库中创建自己的问题,因为您可能遇到意外的记录限制(您可以将表设计为比实际存储在一个记录中更宽的表,有时这会导致插入意外失败)和性能问题因为数据跨数据页分开。我知道你可以从SQL Server中的宽表中获得它,如果mysql遇到类似的问题,我也不会感到惊讶。但是mysql专家必须真正解决这个问题。索引也可能是广泛领域的问题。数据库引擎可能不太倾向于认为索引是有用的。再说一遍,我不确定mysql是否会出现这个问题,但是需要研究一下。我知道这些是在SQL Server中使用max字段大小的问题,mysql可能有这些问题或SQL Server没有的其他问题。

答案 4 :(得分:0)

例如,MySQL中的MEMORY Engine不能很好地支持VARCHAR-Fields。引擎将为每一行保留最大字节数,而不是实际使用的长度。因此,如果您使用单个VARCHAR(1000)列定义一个表,那么对于您添加的每一行,您将拥有1000 * 3字节的内存使用量,即使它们是空字符串也是如此。

相关问题