MySQL UNIQUE INDEX
索引是一种将无序列表转换为有序列表的过程,使我们能够快速检索记录。 它为索引列中出现的每个值创建一个条目 。它在搜索MySQL表时能够最大化查询的效率。如果没有索引,我们需要扫描整个表来查找相关信息。MySQL索引的工作原理类似于书本的索引。
通常情况下,我们使用主键约束来强制一个或多个列的唯一性值。但是,每个表只能使用一个主键。因此,如果我们想要创建带有唯一值的多个列集合,就不能使用主键约束。
MySQL 允许使用另一个称为 UNIQUE INDEX 的约束来确保一个或多个列的值的唯一性。我们可以在单个表中创建多个唯一索引,而主键约束则不可能实现这一点。
语法
以下是在MySQL表中创建唯一索引的通用语法:
CREATE UNIQUE INDEX index_name
ON table_name (index_column1, index_column2,...);
MySQL允许使用UNIQUE Key语句来实现对一个或多个列的唯一值强制性约束。可以在此处阅读有关UNIQUE KEY的更多信息。
如果在表中使用UNIQUE约束,则MySQL会在后台自动创建一个UNIQUE索引。下面的语句说明了在创建表时如何创建唯一约束。
CREATE TABLE table_name(
col1 col_definition,
col2 col_definition,
...
[CONSTRAINT constraint_name]
UNIQUE Key (column_name(s))
);
注意:在创建表时建议使用约束名。如果省略约束名,MySQL会自动生成一个列名。
唯一索引和NULL
MySQL中的NULL值被视为与其他数据库不同的值,因此我们可以在唯一索引列中存储多个NULL值。尽管MySQL的这个特性有时被报告为一个bug,但实际上并不是。
MySQL唯一索引示例
让我们通过一个示例来理解。假设我们想在一个数据库应用程序中管理员工详细信息,其中需要email列是唯一的。执行以下创建带有唯一约束的表 “Employee_Detail” 的语句:
CREATE TABLE Employee_Detail(
ID int AUTO_INCREMENT PRIMARY KEY,
Name varchar(45),
Email varchar(45),
Phone varchar(15),
City varchar(25),
UNIQUE KEY unique_email (Email)
);
如果我们执行下面的语句,我们可以看到MySQL为Employee_Detail表的 Email 列创建了一个唯一索引:
SHOW INDEXES FROM Employee_Detail;
在下面的屏幕中,我们可以看到Email列被创建为唯一索引。
接下来,我们将使用以下语句将记录插入到表中:
INSERT INTO Employee_Detail(ID, Name, Email, Phone, City)
VALUES (1, 'Peter', 'peter@javatpoint.com', '49562959223', 'Texas'),
(2, 'Suzi', 'suzi@javatpoint.com', '70679834522', 'California'),
(3, 'Joseph', 'joseph@javatpoint.com', '09896765374', 'Alaska');
上述语句成功执行,因为所有列都是唯一的。如果我们插入一条记录,其中的电子邮件为 stash ,我们将收到重复错误消息。
mysql> INSERT INTO Employee_Detail(ID, Name, Email, Phone, City)
VALUES (2, 'Suzi', 'suzi@javatpoint.com', '70679834522', 'Texas');
以下输出更清楚地解释了上述所有步骤:
假设我们还希望Employee_Detail表的 名称 和 电话 也是唯一的。在这种情况下,我们将使用以下语句为这些列创建一个唯一索引:
CREATE UNIQUE INDEX index_name_phone
ON Employee_Detail (Name, Phone);
如果我们再次执行 SHOW INDEX 语句,我们可以看到MySQL还为name和phone列创建了一个唯一索引 index_name_phone 。
将此记录添加到表中会导致错误。这是因为姓名和电话的组合已经存在。
mysql> INSERT INTO Employee_Detail(ID, Name, Email, Phone, City)
VALUES (4, 'Joseph', 'joseph@javatpoint.com', '09896765374', 'Texas');
看看这个输出: