mysql - VARCHAR 列应该放在 MySQL 表定义的末尾吗?

标签 mysql rdbms varchar

我听说(从一位同事那里,他从另一位开发人员那里听说)VARCHAR 列应该始终放在 MySQL 中的表定义的末尾,因为它们的长度是可变的,因此可能会减慢查询速度。

不过,我对堆栈溢出所做的研究似乎与此相矛盾,并表明列顺序很重要,但对于这在多大程度上适用于 VARCHAR 存在不同的共识。

他没有具体说明存储引擎,也没有说明这是否仅适用于不常访问的 VARCHAR 列。

最佳答案

询问有关“MySQL”的问题没有帮助,因为 MySQL 将存储归属于存储引擎,并且它们以非常不同的方式实现存储。为任何单独的存储引擎问这个问题是有意义的。

在MEMORY引擎中,不存在变长数据类型。 VARCHAR 悄悄地变成了 CHAR。在您的问题的上下文中:将 VARCHAR 放在表定义中的什么位置并不重要。

在 MyISAM 引擎中,如果表没有任何可变长度数据(VARCHAR、VARBINARY 或任何 TEXT 或 BLOB 类型),则它是 MyISAM 的 FIXED 变体,即记录具有固定字节长度。这可能会对性能产生影响,特别是如果数据被重复删除和插入(即表不是仅附加)。一旦任何可变长度数据类型成为表定义的一部分,它就会成为 MyISAM 的 DYNAMIC 变体,并且 MyISAM 在内部将除最短的 CHAR 类型之外的任何类型更改为 VARCHAR。同样,CHAR/VARCHAR 的位置甚至定义都无关紧要。

在 InnoDB 引擎中,数据存储在 16 KB 大小的页面中。一个页面有一个带校验和的页脚,一个页眉,还有一个页目录。页目录包含每一行该行相对于页首的偏移量。页面还包含空闲空间,所有 I/O 都在页面中完成。

因此,只要页面中有可用空间,InnoDB 就可以就地增长 VARCHAR,并在页面内移动行,而不会产生任何额外的 I/O。此外,由于所有行都被寻址为(页码,页面目录条目),因此页面内行的移动仅限于页面,从外部看不到。

这也意味着对于 InnoDB 来说,一行中列的顺序根本不重要。

这是 MySQL 最常用的三种存储引擎,列的顺序对这三种都没有影响。可能存在其他更奇特的存储引擎,但事实并非如此。

关于mysql - VARCHAR 列应该放在 MySQL 表定义的末尾吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6139597/

相关文章:

sql-server - 从 sql server 迁移到 Oracle varchar 长度问题

mysql - 将 Magento 1.3 数据迁移/替换为 maganeto 1.6

php - 如何使用 php 和 MySQL 从表中获取各个列?

mysql - 从 MYSQL 中提取日期

search - 像关系数据库一样使用 Lucene

php - sql server 存储过程使用 varchar max 作为参数

java - 为什么我的事务在 MySQL 中死锁?

java - MMORPG 中的 JPA、JDBC 与 NoSQL

mysql - 为什么当我尝试创建此表时出现此 FK 错误?错误号 : 150 "Foreign key constraint is incorrectly formed

mysql - 在 mysql 中将日期转换为 varchar 会引发语法错误