在本教程中,您将学习如何使用MySQL UNIQUE
索引来防止表中一个或多个列中拥有重复的值。
MySQL UNIQUE索引简介
要强制执行一个或多个列的唯一性值,我们经常使用PRIMARY KEY 约束。
但是,每个表只有一个主键。 如果要使用多个列或一组具有唯一值的列,则不能使用主键约束。
幸运的是,MySQL提供了另一种称为UNIQUE
索引的索引 ,它允许您在一个或多个列中强制实现值的唯一性。 与PRIMARY KEY
索引不同,每个表可以有多个UNIQUE
索引。
要创建一个UNIQUE
索引,请使用CREATE UNIQUE INDEX 语句如下:
Copy CREATE UNIQUE INDEX index_name
ON table_name(index_column_1,index_column_2,...);
在一个或多个列中强制实现值的唯一性的另一种方法是使用唯一约束。创建唯一约束时,MySQL会在幕后创建一个UNIQUE
的索引。
以下语句说明了如何在创建表 时创建唯一约束。
Copy CREATE TABLE table_name (
...
UNIQUE KEY (index_column_,index_column_2,...)
);
也可以使用UNIQUE INDEX
而不是UNIQUE KEY
。 它们被称为相同的东西。
如果要向现有表添加唯一约束,可以使用ALTER TABLE语句 ,如下所示:
Copy ALTER TABLE table_name
ADD CONSTRAINT constraint_name UNIQUE KEY (column_1,column_2,...);
MySQL UNIQUE索引和NULL
与其他数据库系统不同,MySQL将NULL 值视为不同的值 。 因此,您可以在UNIQUE
索引中具有多个NULL
值。
这就是MySQL的设计方式。 这不是一个错误,即使它被报告为一个错误。
另一重要的一点是UNIQUE
约束不适用于除了BDB存储引擎 之外的NULL
值。
MySQL UNIQUE索引示例
假设想在应用程序中管理联系人。还希望contacts
表中的email
列必须是唯一的。
要执行此规则,请在CREATE TABLE 语句中创建唯一的约束,如下所示:
Copy USE testdb;
CREATE TABLE IF NOT EXISTS contacts (
id INT AUTO_INCREMENT PRIMARY KEY ,
first_name VARCHAR ( 50 ) NOT NULL ,
last_name VARCHAR ( 50 ) NOT NULL ,
phone VARCHAR ( 15 ) NOT NULL ,
email VARCHAR ( 100 ) NOT NULL ,
UNIQUE KEY unique_email (email)
);
如果使用SHOW INDEXES
语句,将看到MySQL为email
列创建了一个UNIQUE
索引。
Copy SHOW INDEXES FROM contacts;
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| contacts | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| contacts | 0 | unique_email | 1 | email | A | 0 | NULL | NULL | | BTREE | | |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set
接下来,向contacts
表中插入一行。
Copy INSERT INTO contacts(first_name,last_name,phone,email)
VALUES ( 'Max' , 'Su' , '(+86)-999-9988' , 'max.su@yiibai.com' );
现在,如果您尝试插入电子邮件是max.su@yiibai.com
的行数据,您将收到一条错误消息。
Copy INSERT INTO contacts(first_name,last_name,phone,email)
VALUES ( 'Max' , 'Su' , '(+86)-999-9988' , 'max.su@yiibai.com' );
执行上面语句后,应该会看到以下结果 -
Copy 1062 - Duplicate entry 'max.su@yiibai.com' for key 'unique_email'
假设您不仅希望电子邮件是唯一的,而且first_name
,last_name
和phone
的组合也是唯一的。 在这种情况下,可以使用CREATE INDEX
语句为这些列创建一个UNIQUE
索引,如下所示:
Copy CREATE UNIQUE INDEX idx_name_phone
ON contacts(first_name,last_name,phone);
将以下行添加到contacts
表中会导致错误,因为first_name
,last_name
和phone
的组合已存在。
Copy INSERT INTO contacts(first_name,last_name,phone,email)
VALUES ( 'Max' , 'Su' , '(+86)-999-9988' , 'john.d@yiibai.com' );
执行上面语句后,应该会看到以下结果 -
Copy 1062 - Duplicate entry 'Max-Su-(+86)-999-9988' for key 'idx_name_phone'
可以看到,不可以将重复电话号码插入到表中。
在本教程中,您已经学习了如何使用MySQL UNIQUE
索引来防止数据库中的重复值。