MySQL中給字段添加唯一約束的方式匯總
一、先明確:為什么必須掌握唯一約束?
- 你是否知道添加唯一約束的多種方式?(創(chuàng)建表時(shí) / 修改表時(shí))
- 能否區(qū)分 “單列唯一約束” 和 “多列唯一約束” 的適用場景?
- 是否了解唯一約束的核心特性?(比如與主鍵的區(qū)別、對(duì) NULL 值的處理)
二、先鋪墊:什么是 MySQL 唯一約束?
唯一約束(UNIQUE Constraint)是 MySQL 中用于限制字段(或多個(gè)字段組合)的值不能重復(fù)的一種約束,它能保證數(shù)據(jù)表中指定字段的唯一性,防止重復(fù)數(shù)據(jù)插入,從而保障數(shù)據(jù)的有效性。比如:用戶表的phone(手機(jī)號(hào))字段添加唯一約束后,就無法插入兩個(gè)手機(jī)號(hào)相同的用戶;訂單表的order_no(訂單編號(hào))添加唯一約束后,不會(huì)出現(xiàn)重復(fù)的訂單編號(hào)。
三、核心:添加唯一約束的 3 種方式
-- 基礎(chǔ)表結(jié)構(gòu)(未加唯一約束) CREATE TABLE `sys_user` ( `id` INT PRIMARY KEY AUTO_INCREMENT, -- 主鍵(自增) `username` VARCHAR(50) NOT NULL, -- 用戶名 `phone` VARCHAR(11), -- 手機(jī)號(hào) `email` VARCHAR(50), -- 郵箱 `dept_id` INT -- 部門ID );
方式 1:創(chuàng)建表時(shí)添加唯一約束
在CREATE TABLE語句中,通過UNIQUE關(guān)鍵字直接給字段添加唯一約束,支持「單列唯一」和「多列唯一」兩種場景。
1.1 單列唯一約束(單個(gè)字段值唯一)
- 語法:在字段定義后直接添加 UNIQUE 關(guān)鍵字(或 UNIQUE KEY,兩者等價(jià))。
- SQL 示例 1:創(chuàng)建用戶表時(shí),給username(用戶名)添加唯一約束(保證用戶名不重復(fù))
CREATE TABLE `sys_user` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL UNIQUE, -- 單列唯一約束:用戶名唯一 `phone` VARCHAR(11), `email` VARCHAR(50), `dept_id` INT );
- SQL 示例 2:給phone(手機(jī)號(hào))添加唯一約束,同時(shí)指定約束名稱(便于后續(xù)刪除 / 修改)
CREATE TABLE `sys_user` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL, `phone` VARCHAR(11), `email` VARCHAR(50), `dept_id` INT, -- 單列唯一約束:指定約束名稱(uq_sys_user_phone),更易維護(hù) UNIQUE KEY `uq_sys_user_phone` (`phone`) );
- 適用場景:單個(gè)字段需要保證唯一性的場景(如用戶名、手機(jī)號(hào)、訂單編號(hào))。
1.2 多列唯一約束(聯(lián)合唯一,多個(gè)字段組合值唯一)
- 通俗定義:不是單個(gè)字段的值唯一,而是多個(gè)字段的「組合值」唯一(單個(gè)字段值可重復(fù),組合后不可重復(fù))。
- 語法:在表結(jié)構(gòu)末尾通過 UNIQUE KEY 約束名 (字段1, 字段2, ...) 定義。
- SQL 示例:給dept_id(部門 ID)和username(用戶名)添加聯(lián)合唯一約束(同一部門內(nèi)用戶名不能重復(fù),不同部門可重復(fù))
CREATE TABLE `sys_user` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL, `phone` VARCHAR(11), `email` VARCHAR(50), `dept_id` INT, -- 多列聯(lián)合唯一約束:同一部門內(nèi)用戶名唯一 UNIQUE KEY `uq_sys_user_dept_username` (`dept_id`, `username`) );
- 適用場景:需要按 “組合條件” 保證唯一性的場景(如同一部門用戶名唯一、同一商品的規(guī)格組合唯一)。
方式 2:修改表時(shí)添加唯一約束(表已存在時(shí)使用)
如果表已經(jīng)創(chuàng)建完成(比如前期設(shè)計(jì)遺漏了唯一約束),可以通過ALTER TABLE語句添加唯一約束,同樣支持單列和多列場景。
2.1 給單列添加唯一約束
- 語法:ALTER TABLE 表名 ADD UNIQUE KEY [約束名] (字段名);
- SQL 示例:給已存在的sys_user表的email字段添加唯一約束
-- 方式1:不指定約束名(MySQL會(huì)自動(dòng)生成默認(rèn)約束名,不推薦) ALTER TABLE `sys_user` ADD UNIQUE KEY (`email`); -- 方式2:指定約束名(推薦,便于后續(xù)維護(hù)) ALTER TABLE `sys_user` ADD UNIQUE KEY `uq_sys_user_email` (`email`);
2.2 給多列添加聯(lián)合唯一約束
- 語法:ALTER TABLE 表名 ADD UNIQUE KEY 約束名 (字段1, 字段2, ...);
- SQL 示例:給已存在的sys_user表添加dept_id和username的聯(lián)合唯一約束
ALTER TABLE `sys_user` ADD UNIQUE KEY `uq_sys_user_dept_username` (`dept_id`, `username`);
- 適用場景:表已創(chuàng)建完成,需要補(bǔ)充唯一約束的場景(如需求迭代后新增唯一性要求)。
方式 3:創(chuàng)建唯一索引(功能等價(jià)于唯一約束)
MySQL 中,唯一約束的本質(zhì)是通過唯一索引實(shí)現(xiàn)的,創(chuàng)建唯一索引(CREATE UNIQUE INDEX)和添加唯一約束在功能上完全一致,都能保證字段值的唯一性。
- 語法:CREATE UNIQUE INDEX 索引名 ON 表名 (字段1, 字段2, ...);
- SQL 示例 1:給sys_user表的phone字段創(chuàng)建唯一索引
CREATE UNIQUE INDEX `idx_sys_user_phone_unique` ON `sys_user` (`phone`);
- SQL 示例 2:給sys_user表的dept_id和username創(chuàng)建聯(lián)合唯一索引
CREATE UNIQUE INDEX `idx_sys_user_dept_username_unique` ON `sys_user` (`dept_id`, `username`);
- 適用場景:更偏向 “索引優(yōu)化” 場景(比如需要通過唯一索引提升查詢效率,同時(shí)保證數(shù)據(jù)唯一性),實(shí)習(xí)生了解即可,優(yōu)先掌握前兩種方式。
四、唯一約束的核心特性
- 對(duì) NULL 值的處理:唯一約束允許字段存儲(chǔ)多個(gè)
NULL值(因?yàn)?MySQL 中NULL不等于任何值,包括它自身)。 - 與主鍵(PRIMARY KEY)的區(qū)別:
| 特性 | 唯一約束(UNIQUE) | 主鍵(PRIMARY KEY) |
|---|---|---|
| 唯一性 | 保證字段值唯一 | 保證字段值唯一 |
| 非空性 | 允許 NULL 值(單列) | 不允許 NULL 值 |
| 一個(gè)表數(shù)量 | 可以有多個(gè)唯一約束(單列 / 多列) | 一個(gè)表只能有一個(gè)主鍵(可聯(lián)合主鍵) |
| 索引類型 | 唯一索引 | 聚簇索引 |
約束的刪除:如果需要?jiǎng)h除唯一約束,可通過約束名 / 索引名刪除:
-- 語法:ALTER TABLE 表名 DROP INDEX 約束名/索引名; ALTER TABLE `sys_user` DROP INDEX `uq_sys_user_phone`;
加分項(xiàng)
- 結(jié)合項(xiàng)目舉例:“我在實(shí)訓(xùn)項(xiàng)目的用戶注冊(cè)模塊中,給手機(jī)號(hào)phone字段添加了唯一約束,避免同一手機(jī)號(hào)重復(fù)注冊(cè);同時(shí)給部門 IDdept_id和用戶名username添加了聯(lián)合唯一約束,保證同一部門內(nèi)用戶名不重復(fù)”;
- 區(qū)分場景選擇方式:“創(chuàng)建表時(shí)我會(huì)直接添加唯一約束,表已存在時(shí)用ALTER TABLE補(bǔ)充,需要提升查詢效率時(shí)會(huì)創(chuàng)建唯一索引”;
- 注意 NULL 值特性:“我知道唯一約束允許多個(gè) NULL 值,所以如果手機(jī)號(hào)是必填項(xiàng),我會(huì)同時(shí)給phone字段加NOT NULL和唯一約束,避免出現(xiàn)空值重復(fù)問題”。
踩坑點(diǎn)
- 混淆唯一約束和主鍵:比如認(rèn)為 “一個(gè)表只能有一個(gè)唯一約束”,或給需要非空的字段只加唯一約束不加NOT NULL;
- 忽略多列聯(lián)合唯一的邏輯:比如誤以為多列聯(lián)合唯一是 “每個(gè)字段都唯一”,而不是 “組合值唯一”;
- 不指定約束 / 索引名:創(chuàng)建唯一約束時(shí)不指定名稱,后續(xù)需要?jiǎng)h除 / 修改時(shí)無法快速定位(依賴 MySQL 默認(rèn)生成的復(fù)雜名稱)。
舉一反三
1、“唯一約束和主鍵有什么區(qū)別?如果我想讓手機(jī)號(hào)既非空又唯一,該怎么設(shè)置?”(答案:給phone字段同時(shí)添加NOT NULL和UNIQUE約束);
2、“我 插入一條username為‘zhangsan’、dept_id為 1 的記錄后,還能插入username為‘zhangsan’、dept_id為 2 的記錄嗎?為什么?”(答案:可以,因?yàn)槭锹?lián)合唯一約束,組合值不同即可);
3、“如何刪除sys_user表中uq_sys_user_phone這個(gè)唯一約束?”(答案:ALTER TABLE sys_user DROP INDEX uq_sys_user_phone;)。
以上就是MySQL中給字段添加唯一約束的方式匯總的詳細(xì)內(nèi)容,更多關(guān)于MySQL字段添加唯一約束的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
mysql間隙鎖加鎖11個(gè)規(guī)則(案例分析)
這篇文章主要介紹了mysql間隙鎖加鎖11個(gè)規(guī)則?,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03
詳解Mysql之mysqlbackup備份與恢復(fù)實(shí)踐
這篇文章主要介紹了詳解Mysql之mysqlbackup備份與恢復(fù)實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
MySQL查詢指定字段不是數(shù)字與逗號(hào)的sql
今天小編遇到一個(gè)問題因?yàn)榫庉嫷牟患?xì)心不小心將關(guān)鍵詞寫到相關(guān)文章里面導(dǎo)致頁面無法生成,這里用sql語言將這些內(nèi)容獲取出來2020-02-02
MySQL創(chuàng)建數(shù)據(jù)表時(shí)設(shè)定引擎MyISAM/InnoDB操作
這篇文章主要介紹了MySQL創(chuàng)建數(shù)據(jù)表時(shí)設(shè)定引擎MyISAM/InnoDB操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
MySQL數(shù)據(jù)xtrabackup物理備份的方式
Xtrabackup是開源免費(fèi)的支持MySQL 數(shù)據(jù)庫熱備份的軟件,在 Xtrabackup 包中主要有 Xtrabackup 和 innobackupex 兩個(gè)工具,本文給大家介紹MySQL數(shù)據(jù)xtrabackup物理備份方法,感興趣的朋友跟隨小編一起看看吧2023-10-10

