定义了UNIQUE约束的字段中不能包含重复值,可以为一个或多个字段定义UNIQUE约束,因此,UNIQUE即可以在字段级也可以在表级定义,在UNIQUE约束的字段上可以包含空值. ORACLE自动会为具有PRIMARY KEY约束的字段(主码字段)建立一个唯一索引和一个NOT NULL约束,定义PRIMARY KEY约束时可以为它的索引,UNIQUED 可空,可以在一个表里的一个或多个字段定义.
PRIMARY KEY不可空不可重复,在一个表里可以定义联合主键;简单的说, primary key = unique + not null
unique就是唯一,当你需要限定你的某个表字段每个值都唯一,没有重复值时使用. 比如说,如果你有一个person_Info表,并且表中有个身份证的column,那么你就可以指定该字段unique.
从技术的角度来看,Primary Key和Unique Key有很多相似之处,但还是有以下异同:
相同:它们都属于实体完整性约束.
例,表结构如下:
- CREATE TABLE `good_booked` (
- `auto_id` int(10) NOT NULL auto_increment,
- `good_id` int(11) default NULL,
- `chemist_id` int(11) default NULL,
- PRIMARY KEY (`auto_id`),
- UNIQUE KEY `good_id` (`good_id`,`chemist_id`),
- KEY `current_state` (`current_state`),
- KEY `send_time` (`send_time`)
- )
想删除某个表中某个字段的unique key,代码如下:
ALTER TABLE good_booked DROP INDEX good_id;
UNIQUE防止重复插入数据示例
当unique列在一个UNIQUE键上插入包含重复值的记录时,我们可以控制MySQL如何处理这种情况,使用IGNORE关键字或者ONDUPLICATEKEYUPDATE子句跳过INSERT、中断操作或者更新旧记录为新值,这样就可以防止数据库中存在重复的数据项,代码如下:
- mysql>createtablemenus(idtinyint(4)notnullauto_increment,
- ->labelvarchar(10)null,urlvarchar(20)null,uniquekey(id));
- QueryOK,0rowsaffected(0.13sec)
- mysql>insertintomenus(label,url)values(“Home”,”home.html”);
- QueryOK,1rowaffected(0.06sec)
- mysql>insertintomenus(label,url)values(“Aboutus”,”aboutus.html”);
- QueryOK,1rowaffected(0.05sec)
- mysql>insertintomenus(label,url)values(“Services”,”services.html”);
- QueryOK,1rowaffected(0.05sec)
- mysql>insertintomenus(label,url)values(“Feedback”,”feedback.html”);
- QueryOK,1rowaffected(0.05sec)
-
- mysql>select*frommenus;
- +—-+———-+—————+
- |id|label|url|
- +—-+———-+—————+
- |1|Home|home.html|
- |2|Aboutus|aboutus.html|
- |3|Services|services.html|
- |4|Feedback|feedback.html|
- +—-+———-+—————+
- 4rowsinset(0.00sec)
如果现在在unique列插入一条违背唯一约束的记录,MySQL会中断操作,提示出错,代码如下:
- mysql>insertintomenus(id,label,url)values(4,”Contactus”,”contactus.html”);
- ERROR1062(23000):Duplicateentry“4″forkey“id”
在前面的INSERT语句添加IGNORE关键字时,如果认为语句违背了唯一约束,MySQL甚至不会尝试去执行这条语句,因此,下面的语句不会返回错误,代码如下:
- mysql>insertignoreintomenus(id,label,url)values(4,”Contactus”,”contactus.html”);
- QueryOK,0rowsaffected(0.00sec)
- mysql>select*frommenus;
- +—-+———-+—————+
- |id|label|url|
- +—-+———-+—————+
- |1|Home|home.html|
- |2|Aboutus|aboutus.html|
- |3|Services|services.html|
- |4|Feedback|feedback.html|
- +—-+———-+—————+
- 4rowsinset(0.00sec)
当有很多的INSERT语句需要被顺序地执行时,IGNORE关键字就使操作变得很方便,使用它可以保证不管哪一个INSERT包含了重复的键值,MySQL都回跳过它,而不是放弃全部操作.
在这种情况下,我们还可以通过添加MySQL4.1新增加的ONDUPLICATEKEYUPDATE子句,使MySQL自动把INSERT操作转换为UPDATE操作,这个子句必须具有需要更新的字段列表,这个列表和UPDATE语句使用的列表相同,代码如下:
- mysql>insertintomenus(id,label,url)values(4,”Contactus”,”contactus.html”)
- ->onduplicatekeyupdatelabel=”Contactus”,url=”contactus.html”;
- QueryOK,2rowsaffected(0.05sec)
在这种情况下,如果MySQL发现表已经包含具有相同唯一键的记录,它会自动更新旧的记录为ONDUPLICATEKEYUPDATE从句中指定的新值,代码如下:
- mysql>select*frommenus;
- +—-+————+—————-+
- |id|label|url|
- +—-+————+—————-+
- |1|Home|home.html|
- |2|Aboutus|aboutus.html|
- |3|Services|services.html|
- |4|Contactus|contactus.html|
- +—-+————+—————-+
- 4rowsinset(0.01sec)
-
不同点:
(1) 唯一性约束所在的列允许空值,但是主键约束所在的列不允许空值.
(2) 可以把唯一性约束放在一个或者多个列上,这些列或列的组合必须有唯一的,但是,唯一性约束所在的列并不是表的主键列.
(3) 唯一性约束强制在指定的列上创建一个唯一性索引,在默认情况下,创建唯一性的非聚簇索引,但是,也可以指定所创建的索引是聚簇索引.
(4)建立主键的目的是让外键来引用.
(5)一个表最多只有一个主键,但可以有很多唯一键. |