最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何创建带主键的MySQL数据表
时间:2026-09-01 19:55:47 编辑:袖梨 来源:一聚教程网
主键必须显式声明NOT NULL且唯一,推荐用INT/BIGINT AUTO_INCREMENT;字符串主键需指定长度,禁用TEXT/BLOB;UUID应存为BINARY(16)以提升性能。
主键必须是 NOT NULL 且唯一
MySQL 要求主键列不能为 NULL,也不能重复。如果你在建表时给主键列写了 NULL 或漏写 NOT NULL,MySQL 会自动补上——但别依赖这个行为,显式声明更安全。
常见错误:用 VARCHAR 字段当主键却没设长度,或用 TEXT 类型(不支持索引),直接报错 ERROR 1170 (42000): BLOB/TEXT column 'xxx' used in key specification without a key length。
- 主键字段必须声明为
NOT NULL(即使不写,MySQL 也会强制,但建议明写) - 字符串主键必须指定长度,比如
id VARCHAR(32) PRIMARY KEY,不能只写VARCHAR - 避免用
TEXT、BLOB、JSON做主键——它们不支持索引定义
推荐用自增整数做主键:INT + AUTO_INCREMENT
除非业务强要求(如分布式 ID、UUID),否则优先选 INT 或 BIGINT 配合 AUTO_INCREMENT。它高效、紧凑、天然有序,且 MySQL 对其优化最成熟。
注意:AUTO_INCREMENT 必须搭配 PRIMARY KEY 或 UNIQUE KEY 使用,且该列要为索引列;如果建表后想加,得先加索引再改属性。
-
id INT PRIMARY KEY AUTO_INCREMENT是最简写法,等价于id INT NOT NULL PRIMARY KEY AUTO_INCREMENT - 自增值默认从 1 开始,可通过
ALTER TABLE tbl AUTO_INCREMENT = 100调整起始值 - 插入时若显式指定
id值(如INSERT INTO t(id) VALUES(5)),后续自增会从该值+1继续,不是“跳过”
用 UUID 或雪花 ID 当主键?注意性能和排序问题
如果用 UUID() 或外部生成的字符串 ID(如 CHAR(36) 或 BINARY(16)),主键就失去顺序性,会导致频繁页分裂、插入变慢、索引碎片多。
真正要用 UUID,建议转成二进制存:id BINARY(16) PRIMARY KEY DEFAULT (UNHEX(REPLACE(UUID(), '-', ''))),比字符串节省一半空间,查询也更快。
- 别用
UUID()函数直接存字符串 ——CHAR(36)太宽,索引体积大,缓存效率低 -
ORDER BY id在 UUID 主键上基本无业务意义,时间顺序无法保证 - 如果已有业务用
UUID字符串,至少加前缀索引,如INDEX idx_id_prefix (id(8)),但不如换二进制方案彻底
建表语句里定义主键的三种常见写法
主键可以在列定义内声明,也可以在表级约束中声明。两种都合法,但语义和可读性不同。列级写法更紧凑,表级写法方便多列联合主键。
错误示范:CREATE TABLE t (id INT, PRIMARY KEY (id)); 看似没问题,但如果 id 没写 NOT NULL,MySQL 会隐式加上——但你代码里没体现,容易误导协作者。
- 列级定义(推荐单列主键):
id BIGINT PRIMARY KEY AUTO_INCREMENT - 表级定义(适合联合主键):
PRIMARY KEY (user_id, order_id) - 命名主键约束(便于后期管理):
CONSTRAINT pk_user PRIMARY KEY (id),这样删主键时可以用DROP PRIMARY KEY或DROP CONSTRAINT pk_user(取决于版本)
NOT NULL 或忽略类型长度限制。主键设计一旦上线,后期改起来代价远高于初期多敲几个字符。