MySQL唯一約束

2019-10-16 22:58:45

在本教學中,您將了解MySQL UNIQUE約束,以強制一列或一個組合列的值的唯一性。

MySQL UNIQUE約束簡介

有時,希望在列中強制執行唯一性值,例如供應商表中供應商的電話必須是唯一的,或者供應商名稱和地址的組合不得重複,簡單一點理解就是:供應商的名稱可以相同,但是不能在同一個地址。

要執行此規則,需要使用UNIQUE約束。

UNIQUE約束是列約束或表約束,它定義了限制列或一組列中的值為唯一的規則。

要將UNIQUE約束新增到列,請使用以下語法:

CREATE TABLE table_1(
    column_name_1  data_type UNIQUE,
);

或者可以將UNIQUE約束定義為表約束,如下所示:

CREATE TABLE table_1(
   ...
   column_name_1 data_type,
   ...
   UNIQUE(column_name_1)
);

如果在column_name_1列中插入更新導致重複值的值,MySQL將發出錯誤訊息並拒絕更改。

如果要跨列強制執行唯一值,則必須將UNIQUE約束定義為表約束,並將每列用逗號分隔:

CREATE TABLE table_1(

   ...
   column_name_1 data_type,
   column_name_2 data type,
   ...
   UNIQUE(column_name_1,column_name_2)
);

MySQL將使用column_name_1column_name_2列中的值的組合來評估唯一性。

如果要為UNIQUE約束分配一個指定的名稱,可以使用CONSTRAINT子句,如下所示:

CREATE TABLE table_1(
   ...
   column_name_1 data_type,
   column_name_2 data type,
   ...
   CONSTRAINT constraint_name UNIQUE(column_name_1,column_name_2)
);

MySQL UNIQUE約束範例

以下語句建立了一個名為suppliers的新表,具有兩個唯一約束條件:

USE testdb;
CREATE TABLE IF NOT EXISTS suppliers (
    supplier_id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    phone VARCHAR(16) NOT NULL UNIQUE,
    address VARCHAR(255) NOT NULL,
    CONSTRAINT uc_name_address UNIQUE (name , address)
);

第一個UNIQUE約束應用於phone列。 這意味著每個供應商必須具有不同的電話號碼。 換句話說,沒有哪兩個供應商的電話號碼是相同的。
第二個UNIQUE約束的名稱為uc_name_address,它強制nameaddress列中值的唯一性。供應商可以擁有相同的名稱或地址,但名稱和地址不能同時相同。

我們在suppliers表中插入一些行來測試UNIQUE約束。

以下語句將一行插入到suppliers表中。

INSERT INTO suppliers(name, phone, address)
VALUES('ABC Inc', '13800138000','4000 North 1st Street, San Jose, CA, USA');

嘗試插入不同的供應商資料資訊,但是使用的電話號碼是一個在suppliers表中已經存在電話號碼。

INSERT INTO suppliers(name, phone, address)
VALUES('XYZ Corporation', '13800138000','4001 North 1st Street, San Jose, CA, USA');

MySQL發出錯誤:

Error Code: 1062. Duplicate entry '13800138000' for key 'phone'

我們將電話號碼更改為其他號碼,然後再次執行插入語句。

INSERT INTO suppliers(name, phone, address)
VALUES('XYZ Corporation', '13800138111','400 North 1st Street, San Jose, CA, USA');

上面插入語句可以成功執行。

現在執行以下INSERT語句來插入一行,其中已經存在的名稱和地址列中的值。

INSERT INTO suppliers(name, phone, address)
VALUES('XYZ Corporation', '13800138222','400 North 1st Street, San Jose, CA, USA');

MySQL發出以下錯誤資訊 -

1062 - Duplicate entry 'XYZ Corporation-400 North 1st Street, San Jose, CA, USA' for key 'uc_name_address'

因為違反了UNIQUE約束uc_name_address,所以插入失敗。

管理MySQL UNIQUE約束

當您向表中新增唯一約束時,MySQL將為資料庫建立一個相應的BTREE索引。 以下SHOW INDEX語句顯示在suppliers表上建立的所有索引。

SHOW INDEX FROM testdb.suppliers;

結果如下所示 -

如上圖所見,有兩個BTREE索引對應於建立的兩個UNIQUE約束。

要刪除UNIQUE約束,可以使用DROP INDEXALTER TABLE語句,語法如下所示:

DROP INDEX index_name ON table_name;

或者 -

ALTER TABLE table_name
DROP INDEX index_name;

例如,要刪除suppliers表上的uc_name_address約束,需要以下語句:

DROP INDEX uc_name_address ON suppliers;

再次執行SHOW INDEX語句來驗證uc_name_unique約束是否已經被刪除。

SHOW INDEX FROM testdb.suppliers;

執行上面查詢語句,得到以下結果 -

如果要將UNIQUE約束新增到已存在的表中,該怎麼辦?很簡單,使用ALTER TABLE語句,語法如下所示:

ALTER TABLE table_name
ADD CONSTRAINT constraint_name UNIQUE (column_list);

例如,要將名稱為uc_name_addressUNIQUE約束新增到suppliers表,請使用以下語句:

ALTER TABLE suppliers
ADD CONSTRAINT uc_name_address UNIQUE (name,address);

請注意,為了使語句成功執行,當然表的nameaddress列中的值的組合必須是唯一的。

在本教學中,您已經學習了如何使用MySQL UNIQUE約束來強制表中列或一組列中的值的唯一性。