1. 主键约束 (Primary Key)
为表设置主键,确保每行数据的唯一性。这是最基本且最有效的防止重复的方法。
CREATE TABLE users (
user_id INT PRIMARY KEY,
username VARCHAR(50) UNIQUE,
email VARCHAR(100)
);
2. 唯一约束 (Unique Constraint)
对需要唯一的列或列组合设置唯一约束,防止特定字段出现重复值。
-- 单列唯一约束
ALTER TABLE products
ADD CONSTRAINT uq_product_code
UNIQUE (product_code);
-- 多列组合唯一约束
ALTER TABLE orders
ADD CONSTRAINT uq_order_customer
UNIQUE (order_date, customer_id);
3. 唯一索引 (Unique Index)
创建唯一索引,既保证数据唯一性,又提高查询性能。
CREATE UNIQUE INDEX idx_unique_email
ON employees (email);
CREATE UNIQUE INDEX idx_unique_name_dept
ON staff (first_name, last_name, department_id);
4. 应用程序逻辑控制
在业务逻辑层进行重复性检查,先查询后插入,确保数据唯一性。
// Java示例代码
public boolean addUserIfNotExists(User user) {
String sql = "SELECT COUNT(*) FROM users WHERE email = ?";
// 先检查是否存在
if (count == 0) {
// 执行插入操作
return true;
}
return false;
}
5. 使用 MERGE/UPSERT 语句
通过合并操作实现"存在则更新,不存在则插入"的逻辑,避免重复插入。
-- PostgreSQL示例
INSERT INTO customers (id, name, email)
VALUES (1, '张三', 'zhangsan@example.com')
ON CONFLICT (id) DO NOTHING;
-- SQL Server示例
MER INTO products AS target
USING (VALUES (101, 'Product A')) AS source (id, name)
ON target.id = source.id
WHEN NOT MATCHED THEN
INSERT (id, name) VALUES (source.id, source.name);
6. 触发器控制 (Triggers)
创建触发器,在数据插入或更新前检查重复性。
CREATE TRIGGER check_duplicate_before_insert
BEFORE INSERT ON orders
FOR EACH ROW
BEGIN
IF EXISTS (SELECT 1 FROM orders
WHERE customer_id = NEW.customer_id
AND order_date = NEW.order_date) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '重复订单不允许插入';
END IF;
END;
7. 使用 EXISTS 子查询
在插入语句中使用EXISTS条件判断,避免重复记录。
INSERT INTO inventory (product_id, quantity)
SELECT 1001, 50
WHERE NOT EXISTS (
SELECT 1 FROM inventory
WHERE product_id = 1001
);