mysql支不支持unique索引

這篇文章主要講解了“MySQL支不支持unique索引”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“mysql支不支持unique索引”吧!

新城ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書(shū)合作)期待與您的合作!

mysql支持unique索引。在MySQL中,UNIQUE索引允許用戶在一個(gè)或多個(gè)列中強(qiáng)制實(shí)現(xiàn)值的唯一性,可以防止表中一個(gè)或多個(gè)列中擁有重復(fù)的值;每個(gè)表可以有多個(gè)UNIQUE索引,且UNIQUE索引中可以具有多個(gè)NULL值。

mysql支持unique索引。在MySQL中,UNIQUE索引可以防止表中一個(gè)或多個(gè)列中擁有重復(fù)的值。

MySQL UNIQUE索引簡(jiǎn)介

要強(qiáng)制執(zhí)行一個(gè)或多個(gè)列的唯一性值,我們經(jīng)常使用PRIMARY KEY約束。

但是,每個(gè)表只有一個(gè)主鍵。 如果要使用多個(gè)列或一組具有唯一值的列,則不能使用主鍵約束。

幸運(yùn)的是,MySQL提供了另一種稱為UNIQUE索引的索引,它允許您在一個(gè)或多個(gè)列中強(qiáng)制實(shí)現(xiàn)值的唯一性。 與PRIMARY KEY索引不同,每個(gè)表可以有多個(gè)UNIQUE索引。

要?jiǎng)?chuàng)建一個(gè)UNIQUE索引,請(qǐng)使用CREATE UNIQUE INDEX語(yǔ)句如下:

CREATE UNIQUE INDEX index_name
ON table_name(index_column_1,index_column_2,...);

在一個(gè)或多個(gè)列中強(qiáng)制實(shí)現(xiàn)值的唯一性的另一種方法是使用唯一約束。創(chuàng)建唯一約束時(shí),MySQL會(huì)在幕后創(chuàng)建一個(gè)UNIQUE的索引。

以下語(yǔ)句說(shuō)明了如何在創(chuàng)建表時(shí)創(chuàng)建唯一約束。

CREATE TABLE table_name(
...
   UNIQUE KEY(index_column_,index_column_2,...) 
);

也可以使用UNIQUE INDEX而不是UNIQUE KEY。 它們被稱為相同的東西。

如果要向現(xiàn)有表添加唯一約束,可以使用ALTER TABLE語(yǔ)句,如下所示:

ALTER TABLE table_name
ADD CONSTRAINT constraint_name UNIQUE KEY(column_1,column_2,...);

MySQL UNIQUE索引和NULL

與其他數(shù)據(jù)庫(kù)系統(tǒng)不同,MySQL將NULL值視為不同的值。 因此,您可以在UNIQUE索引中具有多個(gè)NULL值。

這就是MySQL的設(shè)計(jì)方式。 這不是一個(gè)錯(cuò)誤,即使它被報(bào)告為一個(gè)錯(cuò)誤。

另一重要的一點(diǎn)是UNIQUE約束不適用于除了BDB存儲(chǔ)引擎之外的NULL值。

MySQL UNIQUE索引示例

假設(shè)想在應(yīng)用程序中管理聯(lián)系人。還希望contacts表中的email列必須是唯一的。

要執(zhí)行此規(guī)則,請(qǐng)?jiān)贑REATE TABLE語(yǔ)句中創(chuàng)建唯一的約束,如下所示:

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語(yǔ)句,將看到MySQL為email列創(chuàng)建了一個(gè)UNIQUE索引。

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

接下來(lái),向contacts表中插入一行。

INSERT INTO contacts(first_name,last_name,phone,email)
VALUES('Max','Su','(+86)-999-9988','max.su@yiibai.com');

現(xiàn)在,如果您嘗試插入電子郵件是max.su@yiibai.com的行數(shù)據(jù),您將收到一條錯(cuò)誤消息。

INSERT INTO contacts(first_name,last_name,phone,email)
VALUES('Max','Su','(+86)-999-9988','max.su@yiibai.com');

執(zhí)行上面語(yǔ)句后,應(yīng)該會(huì)看到以下結(jié)果 -

1062 - Duplicate entry 'max.su@yiibai.com' for key 'unique_email'

假設(shè)您不僅希望電子郵件是唯一的,而且first_name,last_name和phone的組合也是唯一的。 在這種情況下,可以使用CREATE INDEX語(yǔ)句為這些列創(chuàng)建一個(gè)UNIQUE索引,如下所示:

CREATE UNIQUE INDEX idx_name_phone
ON contacts(first_name,last_name,phone);

將以下行添加到contacts表中會(huì)導(dǎo)致錯(cuò)誤,因?yàn)閒irst_name,last_name和phone的組合已存在。

INSERT INTO contacts(first_name,last_name,phone,email)
VALUES('Max','Su','(+86)-999-9988','john.d@yiibai.com');

執(zhí)行上面語(yǔ)句后,應(yīng)該會(huì)看到以下結(jié)果 -

1062 - Duplicate entry 'Max-Su-(+86)-999-9988' for key 'idx_name_phone'

可以看到,不可以將重復(fù)電話號(hào)碼插入到表中。

唯一性索引unique影響:

唯一性索引表創(chuàng)建:

DROP TABLE IF EXISTS `sc`;
CREATE TABLE `sc` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  `class` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  `score` int(11) DEFAULT NULL,
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
  `create_user_id` bigint(11) DEFAULT NULL COMMENT '創(chuàng)建人id',
  `modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改時(shí)間',
  `modify_user_id` bigint(11) DEFAULT NULL COMMENT '最后修改人id',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='學(xué)生信息表';

在其中創(chuàng)建了唯一索引name,就是說(shuō)這個(gè)學(xué)生表同名的學(xué)生只能由一位。

命令添加unique:

alter table sc add unique (name);

alter table sc add unique key `name_score` (`name`,`score`);

刪除:

alter table sc drop index `name`;

唯一性索引作用:

先行插入部分?jǐn)?shù)據(jù):

insert into sc (name,class,score) values ('呂布','一年二班',67);
insert into sc (name,class,score) values ('趙云','一年二班',90);
insert into sc (name,class,score) values ('典韋','一年二班',89);
insert into sc (name,class,score) values ('關(guān)羽','一年二班',70);

再次查看表定義:

show create table sc;

CREATE TABLE `sc` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  `class` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  `score` int(11) DEFAULT NULL,
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
  `create_user_id` bigint(11) DEFAULT NULL COMMENT '創(chuàng)建人id',
  `modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改時(shí)間',
  `modify_user_id` bigint(11) DEFAULT NULL COMMENT '最后修改人id',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='學(xué)生信息表';

這時(shí)的Auto_Increment=5

再次執(zhí)行sql:

insert into sc (name,class,score) values ('呂布','二年二班',77)
> 1062 - Duplicate entry '呂布' for key 'name'
> 時(shí)間: 0.01s

此時(shí)再次查看表定義,會(huì)發(fā)現(xiàn)Auto_Increment=6

unique除了在插入重復(fù)數(shù)據(jù)的時(shí)候會(huì)報(bào)錯(cuò),還會(huì)使auto_increment自動(dòng)增長(zhǎng)

unique與primary key的區(qū)別:

簡(jiǎn)單的講,primary key=unique+not null

具體的區(qū)別:

  • (1) 唯一性約束所在的列允許空值,但是主鍵約束所在的列不允許空值。

  • (2) 可以把唯一性約束放在一個(gè)或者多個(gè)列上,這些列或列的組合必須有唯一的。但是,唯一性約束所在的列并不是表的主鍵列。

  • (3) 唯一性約束強(qiáng)制在指定的列上創(chuàng)建一個(gè)唯一性索引。在默認(rèn)情況下,創(chuàng)建唯一性的非聚簇索引,但是,也可以指定所創(chuàng)建的索引是聚簇索引。

  • (4) 建立主鍵的目的是讓外鍵來(lái)引用.

  • (5) 一個(gè)表最多只有一個(gè)主鍵,但可以有很多唯一鍵

存在唯一鍵沖突時(shí),避免策略:

insert ignore:

insert ignore會(huì)忽略數(shù)據(jù)庫(kù)中已經(jīng)存在的數(shù)據(jù)(根據(jù)主鍵或者唯一索引判斷),如果數(shù)據(jù)庫(kù)沒(méi)有數(shù)據(jù),就插入新的數(shù)據(jù),如果有數(shù)據(jù)的話就跳過(guò)這條數(shù)據(jù).

insert ignore into sc (name,class,score) values ('呂布','二年二班',77)

執(zhí)行上面的語(yǔ)句,會(huì)發(fā)現(xiàn)并沒(méi)有報(bào)錯(cuò),但是主鍵還是自動(dòng)增長(zhǎng)了。

replace into:

  • replace into 首先嘗試插入數(shù)據(jù)到表中。 如果發(fā)現(xiàn)表中已經(jīng)有此行數(shù)據(jù)(根據(jù)主鍵或者唯一索引判斷)則先刪除此行數(shù)據(jù),然后插入新的數(shù)據(jù),否則,直接插入新數(shù)據(jù)。

  • 使用replace into,你必須具有delete和insert權(quán)限

replace into sc (name,class,score) values ('呂布','二年二班',77);

此時(shí)會(huì)發(fā)現(xiàn)呂布的班級(jí)跟年齡都改變了,但是id也變成最新的了,所以不是更新,是刪除再新增

insert on duplicate key update:

  • 如果在insert into 語(yǔ)句末尾指定了on duplicate key update,并且插入行后會(huì)導(dǎo)致在一個(gè)UNIQUE索引或PRIMARY KEY中出現(xiàn)重復(fù)值,則在出現(xiàn)重復(fù)值的行執(zhí)行UPDATE;如果不會(huì)導(dǎo)致重復(fù)的問(wèn)題,則插入新行,跟普通的insert into一樣。

  • 使用insert into,你必須具有insert和update權(quán)限

  • 如果有新記錄被插入,則受影響行的值顯示1;如果原有的記錄被更新,則受影響行的值顯示2;如果記錄被更新前后值是一樣的,則受影響行數(shù)的值顯示0

insert into sc (name,class,score) values ('關(guān)羽','二年二班',80) on duplicate key update score=100;
> Affected rows: 2
> 時(shí)間: 0.008s

舊數(shù)據(jù)中關(guān)羽是一年二班,70分,現(xiàn)在插入,最后發(fā)現(xiàn)只有分?jǐn)?shù)變成了100,班級(jí)并沒(méi)有改變。

4	關(guān)羽	一年二班	100	2018-11-16 15:32:18		2018-11-16 15:51:51

id沒(méi)有發(fā)生變化,數(shù)據(jù)只更新,但是auto_increment還是增長(zhǎng)1了。

死鎖:

insert ... on duplicate key 在執(zhí)行時(shí),innodb引擎會(huì)先判斷插入的行是否產(chǎn)生重復(fù)key錯(cuò)誤,
如果存在,在對(duì)該現(xiàn)有的行加上S(共享鎖)鎖,如果返回該行數(shù)據(jù)給mysql,然后mysql執(zhí)行完duplicate后的update操作,
然后對(duì)該記錄加上X(排他鎖),最后進(jìn)行update寫(xiě)入。

如果有兩個(gè)事務(wù)并發(fā)的執(zhí)行同樣的語(yǔ)句,
那么就會(huì)產(chǎn)生death lock,如

mysql支不支持unique索引

解決辦法:

1、盡量對(duì)存在多個(gè)唯一鍵的table使用該語(yǔ)句

2、在有可能有并發(fā)事務(wù)執(zhí)行的insert 的內(nèi)容一樣情況下不使用該語(yǔ)句

結(jié)論:

  • 這三種方法都能避免主鍵或者唯一索引重復(fù)導(dǎo)致的插入失敗問(wèn)題。

  • insert ignore能忽略重復(fù)數(shù)據(jù),只插入不重復(fù)的數(shù)據(jù)。

  • replace into和insert ... on duplicate key update,都是替換原有的重復(fù)數(shù)據(jù),區(qū)別在于replace into是刪除原有的行后,在插入新行,如有自增id,這個(gè)會(huì)造成自增id的改變;insert ... on duplicate key update在遇到重復(fù)行時(shí),會(huì)直接更新原有的行,具體更新哪些字段怎么更新,取決于update后的語(yǔ)句。

感謝各位的閱讀,以上就是“mysql支不支持unique索引”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)mysql支不支持unique索引這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

標(biāo)題名稱:mysql支不支持unique索引
文章源于:http://bm7419.com/article6/igogog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、動(dòng)態(tài)網(wǎng)站網(wǎng)站內(nèi)鏈、商城網(wǎng)站、小程序開(kāi)發(fā)域名注冊(cè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站