欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mysql中的CHECK約束特性詳解

 更新時間:2022年08月08日 08:41:46   作者:GreatSQL  
這篇文章主要介紹了Mysql中的CHECK約束特性詳解的相關(guān)資料,講解的十分淺顯易懂,這里推薦給大家,需要的朋友可以參考下

功能說明

在MySQL 8.0.16以前, CREATE TABLE允許從語法層面輸入下列CHECK約束,但實際沒有效果:

CHECK (expr)

在 MySQL 8.0.16,CREATE TABLE添加了針對所有存儲引擎的表和列的CHECK約束的核心特性。CREATE TABLE允許如下針對表或列的約束語法:

[CONSTRAINT [symbol]] CHECK (expr) [[NOT] ENFORCED]
  • 可選的symbol指定了約束的名稱,如果省略,MySQL會自動生成一個類似:${table_name}_check_${seq_num}的約束名稱,約束名稱是大小寫敏感的,且最長可以到64個字符
  • expr設(shè)定了一個返回值為boolean類型的約束條件,表達式對所有的數(shù)據(jù)行評估的結(jié)果值為:TRUE或UNKNOWN(對 NULL值),當值為FALSE時,約束就被違反,產(chǎn)生的效果與執(zhí)行的語句有關(guān)
  • 可選的執(zhí)行子句標識約束是否需要被強制:
    當未指定或指定為: ENFORCED時,約束被創(chuàng)建且生效
    當指定為: NOT ENFORCED時,約束被創(chuàng)建但未生效
  • 一個CHECK約束可以被指定為表約束或列約束
    表約束不會出現(xiàn)在列定義內(nèi),可以引用任意多個或一個列,且允許引用后續(xù)定義的表列
    列約束出現(xiàn)在列定義內(nèi),僅允許引用該列

示例如下:

CREATE TABLE t1
(
? CHECK (c1 <> c2),
? c1 INT CHECK (c1 > 10),
? c2 INT CONSTRAINT c2_positive CHECK (c2 > 0),
? c3 INT CHECK (c3 < 100),
? CONSTRAINT c1_nonzero CHECK (c1 <> 0),
? CHECK (c1 > c3)
);

以上示例包含了列約束和表約束,命名和未命名的格式:

  • 第一個約束是一個不包含在任何列定義內(nèi)的表約束,所以允許引用任意列,且引用了后續(xù)定義的列,同時沒有給出約束名稱,所以MySQL會給該約束生成一個名字
  • 后續(xù)的3個約束是包含在列定義內(nèi)的列約束,所有指定引用所在的列
  • 最后的兩個是表約束

如果想查看上述命令所生成的約束名,可以輸入以下SHOW CREATE TABLE命令:

mysql> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
? ? ? ?Table: t1
Create Table: CREATE TABLE `t1` (
? `c1` int(11) DEFAULT NULL,
? `c2` int(11) DEFAULT NULL,
? `c3` int(11) DEFAULT NULL,
? CONSTRAINT `c1_nonzero` CHECK ((`c1` <> 0)),
? CONSTRAINT `c2_positive` CHECK ((`c2` > 0)),
? CONSTRAINT `t1_chk_1` CHECK ((`c1` <> `c2`)),
? CONSTRAINT `t1_chk_2` CHECK ((`c1` > 10)),
? CONSTRAINT `t1_chk_3` CHECK ((`c3` < 100)),
? CONSTRAINT `t1_chk_4` CHECK ((`c1` > `c3`))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

SQL規(guī)范要求:所有約束(包括:PRIMARY KEY, UNIQUE,F(xiàn)OREIGN KEY, CHECK)屬于同一個命名空間(NAMESPACE),在MySQL實現(xiàn)中,所有的約束類型在每個schema (database)內(nèi)有自己的命名空間。所以,CHECK約束的名稱在SCHEMA內(nèi)必須唯一,也就是說不允許有兩張表使用同一個CHECK約束名稱。(例外:一個臨時表可能使用與非臨時表一樣的約束名稱)

CHECK的條件表達式必須遵守以下規(guī)則,如果包含不允許的結(jié)構(gòu),將會觸發(fā)錯誤:

  • 非生成列和生成列允許被添加到表達式,但包含AUTO_INCREMENT屬性的列和其他表的列不允許被加入
  • 字面量和確定性(deterministic)的內(nèi)置函數(shù)以及操作符允許被添加到表達式,確定性的含義是:同樣的數(shù)據(jù)不同用戶的多次調(diào)用的結(jié)果是一致的,非確定性的函數(shù)包括:CONNECTION_ID(),CURRENT_USER(),NOW()
  • 存儲函數(shù)和用戶自定義函數(shù)不被允許
  • 存儲過程不被允許
  • 變量:系統(tǒng)變量、用戶自定義變量和存儲過程的本地變量均不被允許使用
  • 子查詢不應(yīng)許被使用
  • 外鍵參考動作,如:ON UPDATE, ON DELETE被禁止在包含CHECK約束的列使用,相應(yīng)的,CHECK約束也被禁止在使用外鍵參考動作的列使用
  • CHECK約束在插入、更新、替換(REPLACE)和LOAD DATA/XML語句的時候被評估,如果評估結(jié)果是FALSE將觸發(fā)錯誤,如果錯誤發(fā)生,已經(jīng)提交的數(shù)據(jù)的處理與對應(yīng)存儲引擎是否支持事務(wù)有關(guān),也依賴嚴格SQL模式是否生效
  • 如果約束表達式所需的數(shù)據(jù)類型與聲明的列類型不一致,數(shù)據(jù)將參考MySQL的類型轉(zhuǎn)換規(guī)則被隱式的轉(zhuǎn)換
約束表達式在不同的SQL模式下,可能返回不同的結(jié)果

另外,在INFORMATION_SCHEMA的CHECK_CONSTRAINTS表中存放著所有表中定義的CHECK約束的信息。

建議使用CHECK約束的場景

復雜業(yè)務(wù)場景下的約束,從架構(gòu)角度看,允許有不同的實現(xiàn)方式:

放在數(shù)據(jù)庫表中,通過約束實現(xiàn),但不支持子查詢

放在數(shù)據(jù)庫中,通過觸發(fā)器(TRIGGER)實現(xiàn)

放在應(yīng)用程序的邏輯中,在提前數(shù)據(jù)庫前檢查

一般性的,選擇不同方式的原則如下:

如果CHECK約束可以實現(xiàn),且約束比較穩(wěn)定,一般用CHECK約束實現(xiàn),比如:年齡不允許為負數(shù),不允許>150等,比如:

CREATE TABLE Departments (
? ? ID int NOT NULL,
? ? PID int NOT NULL,
? ? Name varchar(255) NOT NULL Default '',
? ? CHECK (ID>=1)
);
-- add check separately
ALTER TABLE Departments
ADD CONSTRAINT CHK_PID CHECK (ID>=1 AND PID >=0);
-- remove check
ALTER TABLE Departments
DROP CHECK CHK_PID;

如果屬于數(shù)據(jù)庫邏輯,比如:審計,外鍵可以使用觸發(fā)器

CREATE TABLE IF NOT EXISTS `department` (
? `id` int NOT NULL AUTO_INCREMENT,
? `pid` int COMMENT 'parent id',
? `name` varchar(100) NOT NULL,
? PRIMARY KEY (`id`)
? ) ENGINE = InnoDB;


CREATE TRIGGER pid_insert_check?
BEFORE INSERT ON department?
FOR EACH ROW?
BEGIN
? IF (NEW.pid <> 0 AND NEW.pid NOT IN (select id from department)) THEN
? ? signal sqlstate '45000'
? ? set message_text = 'department parent id has to be chosen from id';
? END IF;
END


CREATE TRIGGER pid_delete_check?
BEFORE DELETE ON department?
FOR EACH ROW?
BEGIN
? IF (OLD.id < 0 OR OLD.id IN (select pid from department)) THEN
? ? signal sqlstate '45000'
? ? set message_text = 'department parent id has to be chosen from id';
? END IF;
END

如果屬于業(yè)務(wù)邏輯,建議放在應(yīng)用層處理,方便開發(fā)者:理解和維護,但是:也需要通過強化業(yè)務(wù)管理,避免特權(quán)用戶偶發(fā)操作引起對數(shù)據(jù)完整性的破壞

到此這篇關(guān)于Mysql中的CHECK約束特性詳解的文章就介紹到這了,更多相關(guān)Mysql中CHECK約束內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mysql如何查詢鎖表

    Mysql如何查詢鎖表

    這篇文章主要介紹了Mysql如何查詢鎖表問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • mysql更新一個表里的字段等于另一個表某字段的值實例

    mysql更新一個表里的字段等于另一個表某字段的值實例

    下面小編就為大家?guī)硪黄猰ysql更新一個表里的字段等于另一個表某字段的值實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • MySQL表的CURD操作(數(shù)據(jù)的增刪改查)

    MySQL表的CURD操作(數(shù)據(jù)的增刪改查)

    數(shù)據(jù)庫本質(zhì)上是一個文件系統(tǒng),通過標準的SQL語句對數(shù)據(jù)進行CURD操作,下面這篇文章主要給大家介紹了關(guān)于MySQL表的CURD操作的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • MySQL數(shù)據(jù)庫閉包Closure Table表實現(xiàn)示例

    MySQL數(shù)據(jù)庫閉包Closure Table表實現(xiàn)示例

    本文主要介紹了MySQL數(shù)據(jù)庫閉包Closure Table表實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01
  • MySQL數(shù)據(jù)入庫時特殊字符處理詳解

    MySQL數(shù)據(jù)入庫時特殊字符處理詳解

    本文是對MySQL數(shù)據(jù)入庫時特殊字符的處理進行了詳細的介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2013-11-11
  • MySQL中JSON字段數(shù)據(jù)類型詳解

    MySQL中JSON字段數(shù)據(jù)類型詳解

    JSON我相信大家都已經(jīng)很熟悉了,但在 MySQL中,直至 5.7 版本中,才正式引入 JSON數(shù)據(jù)類型,下面這篇文章主要給大家介紹了關(guān)于MySQL中JSON字段數(shù)據(jù)類型的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • MySQL和Oracle的元數(shù)據(jù)抽取實例分析

    MySQL和Oracle的元數(shù)據(jù)抽取實例分析

    MySQL和Oracle雖然在架構(gòu)上有很大的不同,但是如果從某些方面比較起來,它們有些方面也是相通的,下面這篇文章主要給大家介紹了關(guān)于MySQL和Oracle元數(shù)據(jù)抽取的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • MyCAT上新增一個庫及MyCAT報錯1184的問題及解決

    MyCAT上新增一個庫及MyCAT報錯1184的問題及解決

    這篇文章主要介紹了MyCAT上新增一個庫及MyCAT報錯1184的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • mysql手動刪除BINLOG的方法

    mysql手動刪除BINLOG的方法

    用于刪除列于在指定的日志或日期之前的日志索引中的所有二進制日志。這些日志也會從記錄在日志索引文件
    2013-03-03
  • 詳解mysql數(shù)據(jù)庫中文亂碼問題

    詳解mysql數(shù)據(jù)庫中文亂碼問題

    這篇文章主要介紹了詳解mysql數(shù)據(jù)庫中文亂碼問題的相關(guān)資料,需要的朋友可以參考下
    2017-10-10

最新評論