mysql中的CONSTRAINT關(guān)鍵詞的用法

在 MySQL 中,CONSTRAINT 關(guān)鍵字用于定義數(shù)據(jù)完整性約束,確保表中數(shù)據(jù)符合特定規(guī)則。通過(guò) CONSTRAINT,你可以顯式命名約束,使其更易管理和維護(hù)。以下是詳細(xì)用法和示例:


一、CONSTRAINT 的作用

  1. 顯式命名約束:為約束規(guī)則指定名稱,方便后續(xù)修改或刪除。
  2. 數(shù)據(jù)完整性:強(qiáng)制數(shù)據(jù)滿足業(yè)務(wù)規(guī)則(如唯一性、關(guān)聯(lián)性、范圍限制等)。
  3. 統(tǒng)一管理:在多列約束或跨表關(guān)聯(lián)時(shí),命名約束更清晰。

二、核心約束類型及用法

1. 主鍵約束(PRIMARY KEY)

  • 作用:唯一標(biāo)識(shí)每行數(shù)據(jù),不允許重復(fù)或 NULL。
  • 語(yǔ)法
    CREATE TABLE 表名 (
        列1 數(shù)據(jù)類型,
        列2 數(shù)據(jù)類型,
        CONSTRAINT 約束名 PRIMARY KEY (列1, 列2) -- 復(fù)合主鍵
    );
    
  • 示例
    CREATE TABLE students (
        student_id INT,
        course_id INT,
        grade DECIMAL(5,2),
        CONSTRAINT pk_student_course 
            PRIMARY KEY (student_id, course_id) -- 復(fù)合主鍵
    );
    

2. 外鍵約束(FOREIGN KEY)

  • 作用:確保兩表之間的數(shù)據(jù)關(guān)聯(lián)有效。
  • 語(yǔ)法
    CREATE TABLE 表名 (
        列1 數(shù)據(jù)類型,
        列2 數(shù)據(jù)類型,
        CONSTRAINT 約束名 FOREIGN KEY (外鍵列)
            REFERENCES 主表名 (主表列)
            ON DELETE 級(jí)聯(lián)操作
            ON UPDATE 級(jí)聯(lián)操作
    );
    
  • 示例
    CREATE TABLE orders (
        order_id INT PRIMARY KEY,
        user_id INT,
        CONSTRAINT fk_user
            FOREIGN KEY (user_id)
            REFERENCES users(user_id)
            ON DELETE CASCADE   -- 主表刪除時(shí),級(jí)聯(lián)刪除從表數(shù)據(jù)
            ON UPDATE SET NULL -- 主表更新時(shí),從表外鍵設(shè)為 NULL
    );
    

3. 唯一約束(UNIQUE)

  • 作用:確保某列(或列組合)的值唯一,允許 NULL
  • 語(yǔ)法
    CREATE TABLE 表名 (
        列1 數(shù)據(jù)類型,
        列2 數(shù)據(jù)類型,
        CONSTRAINT 約束名 UNIQUE (列1, 列2) -- 復(fù)合唯一約束
    );
    
  • 示例
    CREATE TABLE employees (
        emp_id INT PRIMARY KEY,
        email VARCHAR(100),
        CONSTRAINT uc_email 
            UNIQUE (email) -- 確保郵箱唯一
    );
    

4. 檢查約束(CHECK)

  • 作用:限制列值必須滿足條件(MySQL 8.0+ 支持)。
  • 語(yǔ)法
    CREATE TABLE 表名 (
        列1 數(shù)據(jù)類型,
        列2 數(shù)據(jù)類型,
        CONSTRAINT 約束名 CHECK (條件)
    );
    
  • 示例
    CREATE TABLE products (
        product_id INT PRIMARY KEY,
        price DECIMAL(10,2),
        CONSTRAINT chk_price 
            CHECK (price > 0) -- 價(jià)格必須大于 0
    );
    

5. 默認(rèn)值(DEFAULT)

  • 作用:插入數(shù)據(jù)時(shí),未指定列值時(shí)使用默認(rèn)值。
  • 語(yǔ)法
    CREATE TABLE 表名 (
        列1 數(shù)據(jù)類型 DEFAULT 默認(rèn)值
    );
    
  • 示例
    CREATE TABLE orders (
        order_date DATE DEFAULT CURRENT_DATE -- 默認(rèn)當(dāng)前日期
    );
    

三、CONSTRAINT 的管理操作

1. 添加約束

  • 添加主鍵
    ALTER TABLE students
    ADD CONSTRAINT pk_student 
        PRIMARY KEY (student_id);
    
  • 添加外鍵
    ALTER TABLE orders
    ADD CONSTRAINT fk_user
        FOREIGN KEY (user_id) 
        REFERENCES users(user_id);
    

2. 刪除約束

  • 刪除主鍵
    ALTER TABLE students
    DROP PRIMARY KEY; -- 主鍵無(wú)需指定名稱
    
  • 刪除外鍵
    ALTER TABLE orders
    DROP FOREIGN KEY fk_user; -- 需指定外鍵名稱
    

四、實(shí)際應(yīng)用場(chǎng)景

場(chǎng)景 1:防止重復(fù)數(shù)據(jù)

-- 確保書名和作者組合唯一
CREATE TABLE books (
    isbn VARCHAR(13) PRIMARY KEY,
    title VARCHAR(100),
    author VARCHAR(50),
    CONSTRAINT uc_title_author 
        UNIQUE (title, author)
);

場(chǎng)景 2:級(jí)聯(lián)刪除關(guān)聯(lián)數(shù)據(jù)

-- 刪除用戶時(shí),自動(dòng)刪除其訂單
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    user_id INT,
    CONSTRAINT fk_user
        FOREIGN KEY (user_id)
        REFERENCES users(user_id)
        ON DELETE CASCADE
);

場(chǎng)景 3:強(qiáng)制業(yè)務(wù)規(guī)則

-- 確保員工年齡 ≥ 18 歲
CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    age INT,
    CONSTRAINT chk_age 
        CHECK (age >= 18)
);

五、注意事項(xiàng)

  1. 命名規(guī)范:使用 pk_表名、fk_表名_列名 等格式,增強(qiáng)可讀性。
  2. 存儲(chǔ)引擎:外鍵約束需使用 InnoDB,MyISAM 不支持。
  3. 性能影響:過(guò)多的約束可能降低寫入性能。
  4. 版本兼容性CHECK 約束僅 MySQL 8.0+ 完全支持。

六、完整示例

-- 主表:部門
CREATE TABLE departments (
    dept_id INT PRIMARY KEY,
    dept_name VARCHAR(50) NOT NULL UNIQUE
);

-- 從表:?jiǎn)T工(含外鍵和檢查約束)
CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    emp_name VARCHAR(50) NOT NULL,
    dept_id INT,
    salary DECIMAL(10,2),
    CONSTRAINT fk_dept 
        FOREIGN KEY (dept_id) 
        REFERENCES departments(dept_id)
        ON DELETE SET NULL,
    CONSTRAINT chk_salary 
        CHECK (salary >= 3000)
);

通過(guò)合理使用 CONSTRAINT,可以顯著提升數(shù)據(jù)的準(zhǔn)確性和一致性,是數(shù)據(jù)庫(kù)設(shè)計(jì)的核心技能之一。

以下是 15道關(guān)于 MySQL CONSTRAINT 的練習(xí)題,涵蓋主鍵、外鍵、唯一約束、檢查約束等核心用法,幫助你鞏固知識(shí)并熟練使用約束規(guī)則:


基礎(chǔ)練習(xí)(1-5)

  1. 創(chuàng)建表時(shí)定義主鍵約束
    創(chuàng)建一個(gè) students 表,包含 student_id(主鍵)、name、age,并為 student_id 顯式命名主鍵約束為 pk_student。
CREATE TABLE students (
    student_id INT,
    name VARCHAR(50),
    age INT,
    CONSTRAINT pk_student PRIMARY KEY (student_id)
);
  1. 添加復(fù)合主鍵約束
    創(chuàng)建一個(gè) course_selection 表,包含 student_idcourse_id,要求二者的組合為主鍵,約束命名為 pk_student_course

  2. 定義唯一約束
    employees 表中,為 email 列添加唯一約束,命名為 uc_email,確保郵箱唯一。

  3. 創(chuàng)建外鍵約束
    orders 表中添加 user_id 列,并創(chuàng)建外鍵約束 fk_user,使其引用 users 表的 user_id 列,級(jí)聯(lián)刪除從表數(shù)據(jù)。

  4. 檢查約束限制數(shù)值范圍
    創(chuàng)建一個(gè) products 表,包含 price 列,要求價(jià)格必須大于 0,約束命名為 chk_price。


進(jìn)階練習(xí)(6-10)

  1. 多列唯一約束
    books 表中,為 titleauthor 列添加唯一約束 uc_title_author,確保書名和作者組合唯一。

  2. 級(jí)聯(lián)更新外鍵
    修改 orders 表的外鍵約束 fk_user,使其在主表 usersuser_id 更新時(shí),從表的 user_id 自動(dòng)更新。

  3. 刪除主鍵約束
    刪除 students 表的主鍵約束 pk_student,然后重新添加一個(gè)新的主鍵約束到 student_id 列。

  4. 檢查約束限制日期
    events 表中,添加約束 chk_event_date,確保 start_date 必須早于 end_date。

  5. 默認(rèn)值約束
    orders 表中,為 order_date 列設(shè)置默認(rèn)值為當(dāng)前日期,約束命名為 df_order_date。


實(shí)戰(zhàn)場(chǎng)景(11-15)

  1. 復(fù)合外鍵約束
    創(chuàng)建一個(gè) order_details 表,包含 order_idproduct_id,并添加外鍵約束 fk_order_product,使其同時(shí)引用 orders 表的 order_idproducts 表的 product_id。

  2. 檢查約束限制年齡
    users 表中,添加約束 chk_age,確保 age 列的值在 18 到 100 之間。

  3. 刪除外鍵約束
    orders 表中刪除外鍵約束 fk_user,然后重新添加一個(gè)允許主表更新時(shí)從表設(shè)為 NULL 的外鍵約束。

  4. 自增主鍵約束
    employees 表中,定義 emp_id 為自增主鍵,約束命名為 pk_emp。

  5. 檢查約束限制字符串格式
    users 表中,添加約束 chk_phone,確保 phone 列為 11 位數(shù)字(模擬手機(jī)號(hào)格式)。


附加挑戰(zhàn)

  • 場(chǎng)景 1:在 employees 表中,添加約束 chk_salary,確保 salary 必須大于等于 3000,且 department_id 必須存在于 departments 表中。
  • 場(chǎng)景 2:創(chuàng)建一個(gè) projects 表,包含 project_id(主鍵)、start_dateend_date,并添加約束確保 end_date 必須比 start_date 晚至少 7 天。

練習(xí)要求

  1. 每個(gè)練習(xí)需寫出完整的 SQL 語(yǔ)句。
  2. 顯式命名所有約束(如 pk_xxxfk_xxx)。
  3. 驗(yàn)證約束效果(如嘗試插入違反約束的數(shù)據(jù),觀察是否報(bào)錯(cuò))。

通過(guò)完成這些練習(xí),你將熟練掌握 CONSTRAINT 的核心用法,并能在實(shí)際項(xiàng)目中靈活應(yīng)用約束規(guī)則!


基礎(chǔ)練習(xí)答案

1. 創(chuàng)建表時(shí)定義主鍵約束

2. 添加復(fù)合主鍵約束

CREATE TABLE course_selection (
    student_id INT,
    course_id INT,
    grade DECIMAL(5,2),
    CONSTRAINT pk_student_course PRIMARY KEY (student_id, course_id)
);

3. 定義唯一約束

CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    email VARCHAR(100),
    CONSTRAINT uc_email UNIQUE (email)
);

4. 創(chuàng)建外鍵約束(級(jí)聯(lián)刪除)

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    user_id INT,
    CONSTRAINT fk_user 
        FOREIGN KEY (user_id) 
        REFERENCES users(user_id)
        ON DELETE CASCADE
);

5. 檢查約束限制數(shù)值范圍

CREATE TABLE products (
    product_id INT PRIMARY KEY,
    price DECIMAL(10,2),
    CONSTRAINT chk_price CHECK (price > 0)
);

進(jìn)階練習(xí)答案

6. 多列唯一約束

CREATE TABLE books (
    book_id INT PRIMARY KEY,
    title VARCHAR(100),
    author VARCHAR(50),
    CONSTRAINT uc_title_author UNIQUE (title, author)
);

7. 級(jí)聯(lián)更新外鍵

ALTER TABLE orders 
ADD CONSTRAINT fk_user 
    FOREIGN KEY (user_id) 
    REFERENCES users(user_id)
    ON DELETE CASCADE
    ON UPDATE CASCADE;  -- 級(jí)聯(lián)更新

8. 刪除并重新添加主鍵約束

-- 刪除主鍵
ALTER TABLE students DROP PRIMARY KEY;

-- 重新添加主鍵
ALTER TABLE students 
ADD CONSTRAINT pk_student_new PRIMARY KEY (student_id);

9. 檢查約束限制日期范圍

CREATE TABLE events (
    event_id INT PRIMARY KEY,
    start_date DATE,
    end_date DATE,
    CONSTRAINT chk_event_date CHECK (start_date < end_date)
);

10. 默認(rèn)值約束

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    order_date DATE DEFAULT (CURRENT_DATE)
);

實(shí)戰(zhàn)場(chǎng)景答案

11. 復(fù)合外鍵約束

CREATE TABLE order_details (
    order_id INT,
    product_id INT,
    quantity INT,
    CONSTRAINT fk_order_product 
        FOREIGN KEY (order_id, product_id) 
        REFERENCES orders(order_id, product_id)  -- 假設(shè) orders 和 products 有復(fù)合主鍵
);

12. 檢查約束限制年齡范圍

CREATE TABLE users (
    user_id INT PRIMARY KEY,
    age INT,
    CONSTRAINT chk_age CHECK (age BETWEEN 18 AND 100)
);

13. 刪除并重新添加外鍵約束

-- 刪除外鍵
ALTER TABLE orders DROP FOREIGN KEY fk_user;

-- 重新添加外鍵(允許更新時(shí)設(shè)為 NULL)
ALTER TABLE orders 
ADD CONSTRAINT fk_user_new 
    FOREIGN KEY (user_id) 
    REFERENCES users(user_id)
    ON DELETE SET NULL
    ON UPDATE SET NULL;

14. 自增主鍵約束

CREATE TABLE employees (
    emp_id INT AUTO_INCREMENT PRIMARY KEY,
    emp_name VARCHAR(50),
    CONSTRAINT pk_emp PRIMARY KEY (emp_id)
);

15. 檢查約束限制手機(jī)號(hào)格式

CREATE TABLE users (
    user_id INT PRIMARY KEY,
    phone VARCHAR(11),
    CONSTRAINT chk_phone CHECK (phone REGEXP '^[0-9]{11}$')
);

附加挑戰(zhàn)答案

挑戰(zhàn) 1:檢查薪資與部門關(guān)聯(lián)

CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    salary DECIMAL(10,2),
    department_id INT,
    CONSTRAINT chk_salary CHECK (salary >= 3000),
    CONSTRAINT fk_dept 
        FOREIGN KEY (department_id) 
        REFERENCES departments(dept_id)
);

挑戰(zhàn) 2:檢查項(xiàng)目日期間隔

CREATE TABLE projects (
    project_id INT PRIMARY KEY,
    start_date DATE,
    end_date DATE,
    CONSTRAINT chk_project_dates 
        CHECK (DATEDIFF(end_date, start_date) >= 7)
);

驗(yàn)證方法

  1. 插入合法數(shù)據(jù)

    INSERT INTO products (product_id, price) VALUES (1, 10.5);  -- 成功
    
  2. 插入非法數(shù)據(jù)

    INSERT INTO products (product_id, price) VALUES (2, -5);  -- 失敗,違反 chk_price
    
  3. 查看約束信息

    SHOW CREATE TABLE products;  -- 顯示所有約束定義
    

通過(guò)以上練習(xí),你可以熟練掌握 CONSTRAINT 的用法,并能在實(shí)際項(xiàng)目中靈活應(yīng)用!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容