MySQL联合唯一约束应使用ALTER TABLE tbl ADD CONSTRAINT uk_c1_c2 UNIQUE (c1, c2)语法,需显式命名、确保无重复数据,并通过SHOW INDEX验证;删除时用DROP INDEX而非DROP CONSTRAINT。

直接给现有表加联合唯一约束,用 ALTER TABLE ... ADD UNIQUE 最稳妥;但必须确保目标列组合当前无重复值,否则命令会失败。
联合唯一约束的语法到底怎么写
MySQL 不支持直接写 ADD UNIQUE (col1, col2) 而不带约束名——虽然某些旧版本或简化模式下能执行,但官方推荐且兼容性最好的写法是显式命名约束:
ALTER TABLE my_table ADD CONSTRAINT uk_col1_col2 UNIQUE (col1, col2);- 约束名(如
uk_col1_col2)建议按惯例用uk_前缀 + 字段名缩写,避免含特殊字符或过长 - 字段顺序影响索引结构,如果后续常按
col1单独查,把col1放前面更高效 - 不能对包含大量 NULL 的列组合加联合唯一约束:MySQL 认为
NULL != NULL,所以多行(1, NULL)不算重复,但实际业务中这往往违反预期
执行前必须检查重复数据
加约束失败时 MySQL 报的错误通常是:Duplicate entry 'xxx' for key 'uk_col1_col2'。这不是语法问题,而是数据冲突。必须先清理:
- 查重复:
SELECT col1, col2, COUNT(*) FROM my_table GROUP BY col1, col2 HAVING COUNT(*) > 1; - 删冗余(保留最小 id):
DELETE t1 FROM my_table t1 INNER JOIN my_table t2 WHERE t1.col1 = t2.col1 AND t1.col2 = t2.col2 AND t1.id > t2.id; - 若不能删数据,改用
INSERT ... ON DUPLICATE KEY UPDATE或应用层兜底
加完之后怎么验证和删约束
加成功后不会自动提示“已生效”,得手动确认:
- 看索引:
SHOW INDEX FROM my_table WHERE Key_name = 'uk_col1_col2';—— 应有记录且Non_unique为 0 - 试插重复值:
INSERT INTO my_table (col1, col2) VALUES ('a', 'b'), ('a', 'b');—— 第二条应报错1062 Duplicate entry 'a-b' for key 'uk_col1_col2' - 删约束不是
DROP CONSTRAINT,而是删底层唯一索引:ALTER TABLE my_table DROP INDEX uk_col1_col2;
联合唯一约束本质是建了一个唯一 B+ 树索引,所以它既保证数据逻辑唯一,又加速 WHERE col1 = ? AND col2 = ? 查询;但别忘了,它也会略微拖慢写入速度,尤其是高并发 INSERT 场景。











