Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > mysql列数量和长度

MySQL中列数量及长度的限制

作者:tongluowan007

文章详细解析了MySQL中列数量及长度的限制,主要包括绝对最大列数4096和默认最大行大小65,535字节,行格式(如REDUNDANT、COMPACT、DYNAMIC、COMPRESSED)影响存储方式和效率,DYNAMIC为现代默认选项,适合大对象数据,建议根据实际需求选择合适的行格式,优化数据库设计和性能

MySQL中列数量及长度各是多少

由于MySQL设计的一些核心限制。答案不是单一的数字,而是分层和复杂的,取决于多个因素,包括存储引擎行格式以及MySQL版本

简单来说,最主要的限制来自于行的最大大小,而不是单纯的列数量。

以下是详细的分解说明:

1. 硬限制:绝对最大列数

无论使用何种存储引擎和行格式,MySQL每个表的绝对最大列数是4096

但是,这只是一个理论上的上限。在实际中,几乎永远无法达到这个数字,因为会受到下面“行大小限制”的约束。

2. 实际限制:行大小限制

这才是最关键的限制。一行的所有列的数据加起来,不能超过一个特定的值。

这个限制是共享给所有列的。这意味着,即使有100个列,每个列只占用100字节,总长度10,000字节,这也是可以的。但如果有一个VARCHAR(30000)的列,它自己就可能占用30,000字节,那么剩下的空间就很少了,无法再创建很多其他大字段。

示例:
创建两个VARCHAR(30000)的列,理论上需要60,000字节,这小于65,535字节。

CREATE TABLE test (
    col1 VARCHAR(30000),
    col2 VARCHAR(30000)
) ENGINE=InnoDB;

但会遇到一个错误:
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535...

为什么?
因为VARCHAR使用额外的一到两个字节来存储字符串的实际长度。所以两个VARCHAR(30000)列,最大可能占用 30000 * 2 + 2 * 2 = 60004 字节,这看起来是够的。但实际上,MySQL的计算方式更为复杂,还会考虑字符集(如utf8mb4一个字符最多占4字节)等因素,导致实际计算出的最大可能长度超过65,535字节。

3. 存储引擎和行格式的影响

不同的存储引擎和行格式对行大小的限制有不同的处理方式,这尤其影响可变长度数据(如VARCHAR, TEXT, BLOB)大对象数据

InnoDB 引擎

InnoDB是MySQL最常用、默认的存储引擎。它的行为如下:

MyISAM 引擎

总结表格

限制类型限制值/规则说明
绝对最大列数4096所有存储引擎共享的硬性上限。
默认最大行大小65,535 字节所有列(不包括某些情况下的BLOB/TEXT)的总字节数上限。
InnoDB 实际行限制~8000 字节 (主行内部分)对于使用DYNAMIC/COMPACT行格式的表,主行内存储的数据(固定长度列、768字节的VAR列前缀、BLOB指针)不能超过约8000字节。超出部分存到溢出页。
单个VAR列前缀768 字节在InnoDB中,对于非常长的可变长度列,只有前768字节会存储在主行中。
BLOB/TEXT 指针20 字节 (每个)在InnoDB中,每个BLOB或TEXT列在主行中只占用约20字节的指针。

实践建议

  1. 不要试图接近极限:即使理论上允许4096列,设计拥有成百上千列的表通常是一个糟糕的数据库设计(“宽表”),会导致性能问题和管理困难。考虑使用关系规范化(拆分成多个表)。
  2. 使用正确的数据类型:选择最合适、最小的数据类型。例如,用INT而不是BIGINT(如果值足够小),用VARCHAR(n)而不是总是VARCHAR(255)
  3. 考虑溢出行为:如果必须存储大量文本或二进制数据,了解InnoDB的溢出页机制。这有助于理解为什么查询这些大字段可能会更慢(需要额外的磁盘读取)。
  4. 检查行格式:使用 SHOW TABLE STATUS LIKE ‘table_name’; 来查看表的行格式。现代MySQL版本默认使用DYNAMIC,这是处理宽表或有大字段表的最佳选择。

总而言之,能创建的列数量主要取决于这些列的类型和长度,因为它们共同决定了是否会突破“行大小”这个最主要的限制。

行格式

好的,这是一个非常核心的MySQL(特别是InnoDB)概念。理解行格式对于数据库设计、性能优化和存储效率至关重要。

什么是行格式?

行格式(Row Format) 指的是数据库表中每一行数据在磁盘上存储时的物理组织结构。可以把它想象成一个数据结构或模板,定义了如何将一行中的各个列值、元数据(如事务ID、回滚指针等)以及索引信息打包并写入磁盘页。

不同的行格式采用不同的策略来处理:

  1. 数据存储:如何紧凑地存放数据以节省空间。
  2. 溢出处理:当遇到非常长的可变长度列(如VARCHAR, TEXT, BLOB)时,如何处理超出页面大小的部分。
  3. 压缩:是否支持数据压缩以进一步减少磁盘占用。
  4. 性能影响:如何影响查询(特别是SELECT *)和DML(INSERT, UPDATE, DELETE)操作的性能。

InnoDB的行格式

InnoDB是MySQL最常用的存储引擎,它提供了四种主要的行格式。从MySQL 5.7及以后版本,默认的行格式是 DYNAMIC

以下是这四种行格式的详细说明:

1.REDUNDANT(冗余)

2.COMPACT(紧凑)

3.DYNAMIC(动态)(默认)

4.COMPRESSED(压缩)

如何查看和设置行格式

查看表的行格式

-- 查看某个表的行格式等信息
SHOW TABLE STATUS LIKE 'your_table_name';
-- 或从信息模式中查询
SELECT TABLE_NAME, ROW_FORMAT
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_database_name' AND TABLE_NAME = 'your_table_name';

设置行格式

可以在创建表时指定:

CREATE TABLE your_table (
    ...
) ROW_FORMAT=DYNAMIC;

也可以在修改表时变更:

ALTER TABLE your_table ROW_FORMAT=COMPRESSED;

注意:修改现有表的行格式是一个代价较高的操作(会重建表),请在业务低峰期进行。

总结与选择建议

行格式优点缺点适用场景
REDUNDANT兼容性存储效率最低,无压缩旧系统兼容,不推荐
COMPACT比REDUNDANT更省空间大字段处理效率一般,无压缩旧版本默认,现在不常用
DYNAMIC默认选择,大字段处理高效无压缩绝大多数通用场景
COMPRESSED节省大量磁盘空间,缓冲池可缓存更多数据CPU开销高,写操作更慢磁盘空间敏感、读多写少的大表

简单决策流程:

  1. 如果没有特殊需求,坚持使用默认的 DYNAMIC
  2. 如果表中有很多TEXTBLOB列,强烈推荐使用 DYNAMIC
  3. 如果需要节省磁盘空间,并且愿意用CPU资源来交换,同时读写压力不大,可以考虑 COMPRESSED

到此这篇关于MySQL中列数量及长度的限制的文章就介绍到这了,更多相关mysql列数量和长度内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文