VARCHAR列是如何实现的?它们是实际的字符数组吗?

时间:2015-09-04 00:07:54

标签: mysql sql optimization memory-management database-design

如果我在一个表上创建一个{{1}}类型的列并添加行,那么这些行实际上是否有50个字符(如果有一个空终止字符,则为51个字符)?换句话说,如果我部署我的应用程序并且进入该列的用户输入最终只是不超过10个字符的字符串,我是否会浪费80%的内存?

2 个答案:

答案 0 :(得分:3)

字符集

除了其他人所说的内容之外,该列的CHARACTER SET需要考虑因素。

ascii使用1个字符作为1个字符 latin1使用1个字符作为1个字符 utf8对1个字符使用1,2或3个字节 utf8mb4使用1个,2个,3个或4个字节作为1个字符。

声明上的数字是字符,而不是字节

CHAR(10)可以容纳给定CHARACTER SET中最宽的10个字符。对于utf8mb4,它总是占用40个字节。这是

的原因
  • 从不使用CHAR,始终使用VARCHAR和/或
  • 明确说出CHARACTER SET ascii,例如Y / N,M / F,国家/地区代码,邮政编码,SSN,十六进制字符串等。

VARCHAR(10) CHARACTER SET utf8mb4最多可处理10个字符,无论是1字节英文字符还是3字节和4字节中文字符。

SELECT中的临时表

SELECT执行某些操作,例如GROUP BYORDER BY或' UNION' 可能决定是否需要建立一个" temp"用于中间处理的表。如果是这样,它首先考虑使用MEMORY引擎在RAM中构建表。如果是,则将所有VARCHARs转换为CHARs以进行处理。看last_name VARCHAR(255) CHARACTER SET utf8是多种多样的。但是当使用其中一个临时表时,每行变为765个字节。这不是很有效。你经常看到一个长度为255个字符的last_name吗?所以

  • 不要总是使用(255);使它合理;和
  • 适当时使用ascii / latin1。

答案 1 :(得分:1)

回答问题的最佳方式是通过比较。

CHAR和VARCHAR类型相似,但存储和检索方式不同。从MySQL 5.0.3开始,它们的最大长度和是否保留尾随空格也不同。

例如:

DECLARE CHARARRAY CHAR(30) = 'TEST' -- RESULT IS 'TEST..<30 - 4 SPACES>' (WITH TRAILING SPACES)

另一方面:

DECLARE VARCHARARRAY VARCHAR(30) = 'TEST' -- RESULT IS 'TEST' (WITHOUT TRAILING SPACES)

CHAR和VARCHAR类型的声明长度表示您要存储的最大字符数。例如,CHAR(30)最多可以包含30个字符。

CHAR列的长度固定为创建表时声明的长度。长度可以是0到255之间的任何值。当存储CHAR值时,它们用空格填充到指定的长度。检索CHAR值时,将删除尾随空格。

VARCHAR列中的值是可变长度字符串。长度可以指定为MySQL 5.0.3之前的0到255之间的值,5.0.3及更高版本中的0到65,535之间的值。 MySQL 5.0.3及更高版本中VARCHAR的有效最大长度取决于最大行大小(65,535字节,在所有列之间共享)和使用的字符集

与CHAR相比,VARCHAR值存储为1字节或2字节长度前缀加数据。长度前缀表示值中的字节数。如果值不超过255个字节,则列使用一个长度字节;如果值可能需要超过255个字节,则列使用两个长度字节。

<强>结论

如果您想优化数据库,我建议您使用varchar而不是char。字段的大小可能因字段使用情况而异。如果您开始拥有自己设计的数据库,this link可能对您有帮助。

参考:

The CHAR and VARCHAR Types