在存储器中,VARCHAR(255)
足够智能,可以只存储给定行上所需的长度,而CHAR(255)
总是存储255个字符.
但是,既然您用MySQL标记了这个问题,我将提到一个MySQL特有的技巧:当行从存储引擎层复制到SQL层时,VARCHAR
个字段将转换为CHAR
,以获得使用固定宽度行的优势.因此,内存中的字符串变成了声明的VARCHAR
列中的padded out to the maximum length个.
当查询隐式生成临时表时,例如在排序或GROUP BY
时,这可能会占用大量内存.如果对不需要那么长的数据使用大量VARCHAR(255)
个字段,这会使临时表非常大.
您可能还想知道,这种"填充"行为意味着使用utf8字符集声明的字符串将每个字符填充到三个字节,即使对于存储为单字节内容的字符串(例如ascii或拉丁字符).同样地,utf8mb4字符集会使字符串在内存中的每个字符填充到四个字节.
因此,一个VARCHAR(255)
英寸的utf8存储一个短字符串,比如"No opinion",在磁盘上需要11个字节(10个较低的字符集字符,加上一个字节的长度),但在内存中需要765个字节,因此在临时表或排序结果中也需要765个字节.
我帮助过MySQL用户,他们在不知不觉中频繁创建了1.5GB临时表,并填满了他们的磁盘空间.它们有很多VARCHAR(255)
列,实际上存储的是非常短的字符串.
最好根据要存储的数据类型定义列.正如其他人所提到的,强制实施与应用程序相关的约束是有好处的.但它有物理上的好处,可以避免我上面描述的内存浪费.
当然,很难知道最长的邮政地址是什么,这就是为什么许多人 Select 了比任何地址都长的长VARCHAR
.255是常用的,因为它是VARCHAR
的最大长度,长度可以用一个字节编码.它也是MySQL中超过5.0的最大VARCHAR
长度.