摘要:在本教程中,您將學習如何使用 SQL UNIQUE 約束來確保一列或一組列中的所有值都是唯一的。
SQL UNIQUE 約束簡介 #
在 SQL 中,UNIQUE 約束確保一列或一組列中的所有值在同一個表中是唯一的。UNIQUE 約束透過防止在指定列中出現重複值來幫助您維護資料完整性。
在實踐中,您會發現 UNIQUE 約束對於定義需要唯一值的列(如 username 和 email)非常有用。
建立 UNIQUE 約束 #
要為列建立唯一約束,請使用以下語法:
CREATE TABLE table_name (
column1 datatype UNIQUE,
...
);Code language: SQL (Structured Query Language) (sql)在此語法中,您在建立表時使用 UNIQUE 關鍵字為 column1 建立唯一約束。這個 UNIQUE 約束是一個列約束,因為我們在表的列定義中定義它。
如果一個 UNIQUE 約束包含多個列,您可以將 UNIQUE 約束定義為表約束:
CREATE TABLE table_name (
column1 datatype,
column2 datatype,
UNIQUE (column1, column2)
);Code language: SQL (Structured Query Language) (sql)在此語法中,您在 UNIQUE 關鍵字前的括號內提供一個以逗號分隔的列列表,該關鍵字出現在列列表的末尾。
首先,建立一個名為 headhunters 的表,用於儲存獵頭資訊:
CREATE TABLE headhunters (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE
);Code language: SQL (Structured Query Language) (sql)在 headhunters 表中,我們為 email 列使用了 UNIQUE 約束,以確保 email 列不會有任何重複值。
其次,向 headhunters 表中插入一個新行:
INSERT INTO
headhunters (first_name, last_name, email)
VALUES
('John', 'Doe', '[email protected]');Code language: SQL (Structured Query Language) (sql)第三,嘗試插入一個新行,其電子郵件地址在 email 列中已經存在:
INSERT INTO
headhunters (first_name, last_name, email)
VALUES
('Jane', 'Doe', '[email protected]');Code language: SQL (Structured Query Language) (sql)資料庫系統發出錯誤,指示電子郵件地址重複,並拒絕了插入操作。
ERROR: duplicate key value violates unique constraint "headhunters_email_key"Code language: SQL (Structured Query Language) (sql)UNIQUE 約束名稱 #
在定義唯一約束時,您可以選擇使用 CONSTRAINT 子句為其分配一個名稱:
CONSTRAINT constraint_name
UNIQUE (column1, column2, ...);Code language: SQL (Structured Query Language) (sql)例如,以下語句建立了一個名為 users 的表,用於儲存使用者資訊:
CREATE TABLE users (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
username VARCHAR(25) NOT NULL,
password TEXT NOT NULL,
phone VARCHAR(20),
CONSTRAINT unique_username UNIQUE (username)
);Code language: SQL (Structured Query Language) (sql)在此示例中,我們建立了一個名為 unique_username 的唯一約束,以確保 username 列沒有重複值。
如果您沒有為 UNIQUE 約束提供名稱,資料庫系統將為其生成一個預設名稱。生成的唯一約束名稱可能因資料庫系統而異。
下表說明了不同資料庫系統中唯一約束的預設名稱:
| 資料庫系統 | 預設唯一約束名稱 | 說明 |
|---|---|---|
| SQL Server | UQ_TableName_ColumnName_Hex | 字首 UQ_,後跟表名、列名和一個十六進位制值以確保唯一性。 |
| Oracle | SYS_Cn | 字首 SYS_C,後跟一個唯一的數字 (n)。 |
| MySQL | unique_constraint_name | 使用使用者提供的名稱,如果未指定,則預設為系統生成的名稱。 |
| PostgreSQL | table_column_key | 連線表名、列名和字面字串“key”。 |
| SQLite | sqlite_autoindex_TableName_N | 字首 sqlite_autoindex_,後跟表名和一個唯一的數字 (N)。 |
| DB2 | SQLnnnnn | 字首 SQL,後跟一個唯一的數字 nnnnn。 |
向現有表新增 UNIQUE 約束 #
要向現有表新增唯一約束,您可以使用 ALTER TABLE ... ADD CONSTRAINT 語句:
ALTER TABLE table_name
ADD CONSTRAINT constraint_name
UNIQUE (colum1, column2, ...);Code language: SQL (Structured Query Language) (sql)如果表中有資料,唯一約束的列(column1, column2, ...)中的值必須是唯一的,否則您會遇到錯誤。
例如,以下語句使用 ALTER TABLE ... ADD CONSTRAINT 語句向 users 表新增一個唯一約束:
ALTER TABLE users
ADD CONSTRAINT unique_phone UNIQUE (phone);Code language: SQL (Structured Query Language) (sql)如果您想新增一個帶有 UNIQUE 約束的新列,請使用 ALTER TABLE ... ADD column 語句:
ALTER TABLE table_name
ADD new_column datatype UNIQUE;Code language: SQL (Structured Query Language) (sql)例如,以下語句將帶有 UNIQUE 約束的 employee_id 列新增到 users 表中。
ALTER TABLE users
ADD employee_id INT UNIQUE;Code language: SQL (Structured Query Language) (sql)此唯一約束確保沒有兩個員工共享同一個使用者帳戶。
刪除 UNIQUE 約束 #
要從表中刪除 UNIQUE 約束,請使用 ALTER TABLE .. DROP CONSTRAINT 語句,語法如下:
ALTER TABLE table_name
DROP CONSTRAINT unique_constraint_name;Code language: SQL (Structured Query Language) (sql)在此語法中:
- 首先,指定要從中刪除唯一約束的表名。
- 其次,在
DROP CONSTRAINT子句中提供要刪除的唯一約束的名稱。
例如,以下語句從 users 表中刪除 unique_phone 約束:
ALTER TABLE users
DROP CONSTRAINT unique_phone;Code language: SQL (Structured Query Language) (sql)UNIQUE vs. PRIMARY KEY 約束 #
一個表只能有一個主鍵 (PRIMARY KEY) 約束,但可以有多個 UNIQUE 約束。此外,PRIMARY KEY 約束不允許 NULL 值,而 UNIQUE 約束允許 NULL 值。
下表比較了 PRIMARY KEY 和 UNIQUE 約束:
| 特性 | PRIMARY KEY 約束 | UNIQUE 約束 |
|---|---|---|
| 約束數量 | 每個表一個主鍵 | 每個表多個唯一約束 |
| 允許 Null 值 | 否 | 是 |
摘要 #
- 使用
UNIQUE約束來確保一列或一組列具有唯一的值。