如果我在表上创建类型为 VARCHAR (50)
的列并添加行,这些行实际上有 50 个字符(如果有空终止字符,则为 51 个)?换句话说,如果我部署了我的应用程序,而进入该列的用户输入最终只是不超过 10 个字符的字符串,我是否浪费了 80% 的内存?
最佳答案
字符集
除了其他人所说的之外,该列的 CHARACTER SET
需要考虑在内。
ascii
使用 1 个字节代表 1 个字符。
latin1
使用 1 个字节代表 1 个字符。
utf8
1 个字符使用 1、2 或 3 个字节。
utf8mb4
1 个字符使用 1、2、3 或 4 个字节。
声明中的数字是字符,而不是字节。
CHAR(10)
可以容纳给定 CHARACTER SET
中最宽的 10 个字符。对于 utf8mb4,它总是占用 40 个字节。这是要么的原因
- 从不使用
CHAR
,始终使用VARCHAR
,和/或 - 为 Y/N、M/F、国家代码、邮政编码、SSN、十六进制字符串等明确说明
CHARACTER SET ascii
。
VARCHAR(10) CHARACTER SET utf8mb4
最多可以处理 10 个字符,无论是 1 字节英文字符还是 3 字节和 4 字节中文字符。
SELECT 中的临时表
SELECT
执行某些操作,例如 GROUP BY
或 ORDER BY
或“UNION”可能决定它需要为中间处理建立一个“临时”表。如果是,它首先考虑使用 MEMORY 引擎在 RAM 中构建表。如果是,则将所有 VARCHARs
转换为 CHARs
进行处理。 last_name VARCHAR(255) CHARACTER SET utf8
很常见。但是当使用这些临时表之一时,每行变成 765 字节。这不是很有效。您多久见过一次 255 个字符长的姓氏?所以
- 不要总是使用
(255)
;让它变得合理;和 - 在适当的时候使用 ascii/latin1。
关于mysql - VARCHAR 列是如何实现的?它们是实际的字符数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32387286/