一、唯一索引的核心价值
唯一索引是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 IGNOREsqlINSERT IGNORE INTO users (username) VALUES ('john'); -
条件唯一索引 (MySQL 8.0+):
sqlCREATE TABLE logs ( id INT, event_date DATE, UNIQUE (id, event_date) -- 仅当event_date在最近30天时生效 ) PARTITION BY RANGE COLUMNS(event_date);
五、最佳实践建议
-
前缀索引优化 :对长文本列使用前缀索引
sqlALTER TABLE articles ADD UNIQUE (title(50)); -- 仅索引前50字符 -
避免过度索引:高频写入表建议不超过5个索引
-
监控索引碎片 :定期执行
OPTIMIZE TABLE重建索引 -
联合索引顺序:将区分度高的列放在组合索引左侧
完整示例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分析索引使用效率,持续优化索引策略。