mysql如何添加唯一索引_mysql create unique index方法

16次阅读

直接添加唯一索引会因重复数据报错,需先查重清理再创建;ALTER TABLE ADD UNIQUE 与 CREATE UNIQUE INDEX 效果相同;唯一索引允许多个 NULL 但存在语义陷阱;建索引会锁表,线上需谨慎评估。

mysql 如何添加唯一索引_mysql create unique index 方法

直接添加唯一索引会报错:Duplicate entry

执行 CREATE UNIQUE INDEX 时如果字段已有重复值,MySQL 立即报错 Duplicate entry 'xxx' for key 'idx_name',不会继续。这不是语法问题,而是数据校验失败。

  • 先用 SELECT column, COUNT(*) FROM table GROUP BY column HAVING COUNT(*) > 1 找出重复项
  • 清理或合并重复数据(比如保留最小 id 的行,删其余)
  • 确认无重复后再建索引,否则操作中断

ALTER TABLE ADD UNIQUE 和 CREATE UNIQUE INDEX 效果一样

两者最终都生成同类型的约束,区别 只在语法习惯和是否显式命名索引:

  • ALTER TABLE t ADD UNIQUE (col) —— MySQL 自动命名为 col(若未指定)
  • CREATE UNIQUE INDEX idx_col ON t(col) —— 可自定义索引名,便于后续 DROP INDEX idx_col ON t
  • 对单列、多列、前缀长度(如 (col(10)))的支持完全一致

唯一索引允许 NULL,但有陷阱

MySQL 的唯一索引允许多个 NULL 值(标准 SQL 要求 NULL 不参与唯一性比较),这点常被误认为“失效”:

  • 如果业务逻辑中把空字符串 ''NULL 混用,可能漏掉重复校验
  • 建议统一用 NOT NULL DEFAULT '' + 唯一索引,避免 NULL 干扰
  • 若字段必须允许空值,且需语义级唯一(即“空也算一个值”),得靠应用层或触发器兜底

建索引过程锁表,线上要谨慎

MySQL 5.6+ 支持 ALGORITHM=INPLACE,但并非所有情况都免锁:

  • 加唯一索引属于 DDL,即使支持 INPLACE,仍会在最后阶段加短暂的排他元数据锁(MDL)
  • 大表建议在低峰期执行,或使用 pt-online-schema-change 工具 规避长事务阻塞
  • 建索引期间 SHOW PROCESSLIST 里能看到状态为 altering table,此时写入会等待
实际建索引前,别跳过查重和评估锁影响——这两步省了,后面排查更费时间。

text=ZqhQzanResources