最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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值),當(dāng)值為FALSE時,約束就被違反,產(chǎn)生的效果與執(zhí)行的語句有關(guān)
  • 可選的執(zhí)行子句標(biāo)識約束是否需要被強制:
    當(dāng)未指定或指定為: ENFORCED時,約束被創(chuàng)建且生效
    當(dā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),也依賴嚴(yán)格SQL模式是否生效
  • 如果約束表達式所需的數(shù)據(jù)類型與聲明的列類型不一致,數(shù)據(jù)將參考MySQL的類型轉(zhuǎn)換規(guī)則被隱式的轉(zhuǎn)換
約束表達式在不同的SQL模式下,可能返回不同的結(jié)果

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

建議使用CHECK約束的場景

復(fù)雜業(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),比如:年齡不允許為負(fù)數(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出現(xiàn)Host is not allowed to connect to this MySQL server 解決方法詳解

    連接MySQL出現(xiàn)Host is not allowed to con

    這篇文章主要給大家介紹了連接MySQL出現(xiàn)Host is not allowed to connect to this MySQL server 解決方法,文中有詳細(xì)的解決步驟,需要的朋友可以參考下
    2023-08-08
  • 詳解如何在阿里云服務(wù)器安裝Mysql數(shù)據(jù)庫

    詳解如何在阿里云服務(wù)器安裝Mysql數(shù)據(jù)庫

    這篇文章主要介紹了詳解如何在阿里云服務(wù)器安裝Mysql數(shù)據(jù)庫,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 如何通過配置自動實現(xiàn)ValueList中hql語句的整型參數(shù)轉(zhuǎn)換

    如何通過配置自動實現(xiàn)ValueList中hql語句的整型參數(shù)轉(zhuǎn)換

    本篇文章是對通過配置自動實現(xiàn)ValueList中hql語句的整型參數(shù)轉(zhuǎn)換進行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • MySQL常用客戶端工具的用途和詳細(xì)說明

    MySQL常用客戶端工具的用途和詳細(xì)說明

    MySQL是一個廣泛使用的開源關(guān)系數(shù)據(jù)庫管理系統(tǒng)(RDBMS),它為開發(fā)者和數(shù)據(jù)庫管理員提供了一套完整的客戶端工具和功能,這篇文章主要介紹了MySQL常用客戶端工具的用途和詳細(xì)說明的相關(guān)資料,需要的朋友可以參考下
    2025-09-09
  • MySQL中使用load data命令實現(xiàn)數(shù)據(jù)導(dǎo)入的方法

    MySQL中使用load data命令實現(xiàn)數(shù)據(jù)導(dǎo)入的方法

    MySQL支持load data命令的數(shù)據(jù)導(dǎo)入,該方式比直接的insert的效率要高,按照官方的說法是要比insert語句快上20倍
    2013-10-10
  • Mysql批量插入數(shù)據(jù)時該如何解決重復(fù)問題詳解

    Mysql批量插入數(shù)據(jù)時該如何解決重復(fù)問題詳解

    之前寫的代碼批量插入遇到了問題,原因是有重復(fù)的數(shù)據(jù)(主鍵或唯一索引沖突),所以插入失敗,下面這篇文章主要給大家介紹了關(guān)于Mysql批量插入數(shù)據(jù)時該如何解決重復(fù)問題的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • MySQL的時間差函數(shù)(TIMESTAMPDIFF、DATEDIFF)、日期轉(zhuǎn)換計算函數(shù)(date_add、day、date_format、str_to_date)

    MySQL的時間差函數(shù)(TIMESTAMPDIFF、DATEDIFF)、日期轉(zhuǎn)換計算函數(shù)(date_add、day、da

    這篇文章主要介紹了MySQL的時間差函數(shù)(TIMESTAMPDIFF、DATEDIFF)、日期轉(zhuǎn)換計算函數(shù)(date_add、day、date_format、str_to_date),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • ktl工具實現(xiàn)mysql向mysql同步數(shù)據(jù)方法

    ktl工具實現(xiàn)mysql向mysql同步數(shù)據(jù)方法

    在本篇內(nèi)容里我們給大家介紹了用ktl工具實現(xiàn)mysql向mysql同步數(shù)據(jù)的具體步驟,有需要的朋友們跟著學(xué)習(xí)參考下。
    2019-03-03
  • MySQL啟動方式之systemctl與mysqld的對比詳解

    MySQL啟動方式之systemctl與mysqld的對比詳解

    MySQL 是當(dāng)今最流行的開源關(guān)系型數(shù)據(jù)庫之一,其性能、可靠性和易用性讓它廣泛應(yīng)用于各種場景,如何正確啟動 MySQL 服務(wù)可能并不是一件簡單的事情,本文將聚焦兩種常用的 MySQL 啟動方式:通過 systemctl 啟動和直接使用 mysqld 啟動,需要的朋友可以參考下
    2024-11-11
  • 簡述MySQL主鍵和外鍵使用及說明

    簡述MySQL主鍵和外鍵使用及說明

    MySQL通過外鍵約束來保證表與表之間的數(shù)據(jù)的完整性和準(zhǔn)確性,本文主要介紹了簡述MySQL主鍵和外鍵使用及說明,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評論

莱州市| 中方县| 乳源| 临桂县| 汤阴县| 三明市| 灵山县| 太湖县| 株洲市| 邯郸县| 湘潭县| 黄冈市| 神池县| 灌南县| 固镇县| 井冈山市| 丹寨县| 温宿县| 吕梁市| 阳泉市| 宁晋县| 阳高县| 陕西省| 阿尔山市| 武强县| 依兰县| 双柏县| 连城县| 尉犁县| 万安县| 嘉定区| 岳池县| 河间市| 自治县| 大悟县| 乌拉特后旗| 蓬安县| 邯郸县| 高淳县| 南丹县| 顺昌县|