MySQL如何加唯一索引

一、唯一索引的核心价值

唯一索引是MySQL中保证数据完整性的重要工具,它强制要求索引列的值必须唯一(允许NULL值,但多NULL值会被视为不同值)。与主键索引不同,唯一索引允许存在多个,且不隐含非空约束。典型应用场景包括:

  • 用户邮箱/手机号唯一验证
  • 订单号防重复
  • 商品SKU编码唯一性约束
二、建表时添加唯一索引

语法模板

sql 复制代码
CREATE TABLE table_name (
    column1 datatype UNIQUE,  -- 单列唯一索引
    column2 datatype,
    ...,
    UNIQUE (col_a, col_b)     -- 多列组合唯一索引
);

实战示例

sql 复制代码
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,  -- 单列唯一索引
    email VARCHAR(100) NOT NULL,
    phone VARCHAR(20),
    INDEX idx_email_phone (email, phone) UNIQUE  -- 组合唯一索引
);

效果验证

插入重复用户名或(email+phone)组合时,MySQL将抛出ERROR 1062 (23000): Duplicate entry错误。

三、建表后添加唯一索引

方法1:ALTER TABLE(推荐)

sql 复制代码
ALTER TABLE products 
ADD UNIQUE uk_product_sku (sku);  -- 单列索引

ALTER TABLE orders 
ADD UNIQUE uk_order_user_time (user_id, order_time);  -- 组合索引

方法2:CREATE INDEX

sql 复制代码
CREATE UNIQUE INDEX idx_unique_username ON customers(username);
四、进阶操作与注意事项

1. 索引命名规范

建议使用前缀uk_(Unique Key)或uniq_开头,如uk_user_email,便于维护。

2. 处理冲突数据

添加唯一索引前,需先清理重复数据:

sql 复制代码
-- 查找重复数据
SELECT col, COUNT(*) 
FROM table_name 
GROUP BY col 
HAVING COUNT(*) > 1;

-- 删除重复记录(保留最新)
DELETE t1 
FROM table_name t1
INNER JOIN table_name t2 
WHERE t1.id > t2.id AND t1.col = t2.col;

3. 性能影响评估

  • 写操作性能下降(约10-30%)
  • 查询速度提升(尤其在WHERE/ORDER BY场景)
  • 索引占用存储空间(约表大小的1.2-1.5倍)

4. 特殊场景处理

  • 忽略重复插入 :使用INSERT IGNORE

    sql 复制代码
    INSERT IGNORE INTO users (username) VALUES ('john');
  • 条件唯一索引 (MySQL 8.0+):

    sql 复制代码
    CREATE TABLE logs (
        id INT,
        event_date DATE,
        UNIQUE (id, event_date)  -- 仅当event_date在最近30天时生效
    ) PARTITION BY RANGE COLUMNS(event_date);
五、最佳实践建议
  1. 前缀索引优化 :对长文本列使用前缀索引

    sql 复制代码
    ALTER TABLE articles ADD UNIQUE (title(50));  -- 仅索引前50字符
  2. 避免过度索引:高频写入表建议不超过5个索引

  3. 监控索引碎片 :定期执行OPTIMIZE TABLE重建索引

  4. 联合索引顺序:将区分度高的列放在组合索引左侧

完整示例SQL

sql 复制代码
-- 创建商品表并添加唯一索引
CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    sku VARCHAR(20) NOT NULL,
    name VARCHAR(100) NOT NULL,
    price DECIMAL(10,2) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT uk_product_sku UNIQUE (sku)  -- 命名约束
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 添加组合唯一索引(订单号+用户ID)
ALTER TABLE orders ADD UNIQUE uk_order_user (order_number, user_id);

总结

MySQL唯一索引是保障数据一致性的重要防线。通过合理的索引设计,可以在保证数据质量的同时提升查询性能。实际操作中需平衡读写性能、存储空间和业务需求,定期使用EXPLAIN分析索引使用效率,持续优化索引策略。

相关推荐
ClickHouseDB4 小时前
ClickHouse Cloud 与 Snowflake 实时性价比对比:CostBench 测试中的 412 倍差距来
运维·数据库·系统架构
m0_639906944 小时前
Redis入门|五种数据结构、使用场景、持久化RDB&AOF
数据结构·数据库·redis
时间售卖铺5 小时前
触发器与函数实战:MySQL高效编程秘诀
运维·数据库·mysql·云原生
qetfw5 小时前
UOS MariaDB 数据库:安装、最小权限与备份验证
linux·数据库·mariadb·uos
数智园区合作社6 小时前
问数平台怎么把同一个指标锁成一个数
大数据·数据库·人工智能·ai
lbb 小魔仙6 小时前
Windows搭建PaddleOCR+飞书Webhook自动打卡通知机器人:识别、推送与远程触发完整教程
数据库·人工智能·prometheus·时序数据库
captain3767 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
心中有你02148 小时前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
龙亘川8 小时前
综合素质评价业务建模:从过程性评价到成长档案全链路闭环
数据库·智慧城市·数据可视化
数据库小组8 小时前
NineData 实战教程:MySQL 5.5 数据迁移同步到 MySQL 8.0(跨版本升级)
数据库·mysql·mysql优化·数据库开发·数据库迁移·版本升级·数据复制