mysql添加枚举约束语句_mysql8 参考手册--MySQL如何处理约束
MySQL使您既可以使用允許回滾的事務表,也可以使用不允許回滾的非事務表。因此,MySQL中的約束處理與其他DBMS中的約束處理有所不同。當您在非事務處理表中插入或更新了很多行時,如果發生錯誤,則無法回滾更改,我們必須處理這種情況。
基本原理是,MySQL Server會嘗試在分析要執行的語句時對其檢測到的所有內容產生錯誤,并嘗試從執行該語句時發生的任何錯誤中恢復。在大多數情況下,我們會這樣做,但并非全部。
當發生錯誤時,MySQL具有的選項是在中間停止語句或從問題中盡可能恢復并繼續。默認情況下,服務器遵循后面的過程。例如,這意味著服務器可以將無效值強制為最接近的有效值。
有幾個SQL模式選項可用來更好地控制壞數據值的處理以及在發生錯誤時繼續執行語句還是中止。使用這些選項,可以將MySQL Server配置為以更傳統的方式運行,就像其他拒絕不正確輸入的DBMS一樣。可以在服務器啟動時全局設置SQL模式,以影響所有客戶端。各個客戶端可以在運行時設置SQL模式,這使每個客戶端可以選擇最適合其要求的行為。請參見 第5.1.11節“服務器SQL模式”。
主鍵和唯一索引約束
通常,數據更改語句(例如INSERT或 UPDATE)會發生錯誤,這些錯誤 會違反主鍵,唯一鍵或外鍵約束。如果您使用事務存儲引擎(例如) InnoDB,MySQL會自動回滾該語句。如果您使用的是非事務性存儲引擎,則MySQL會在發生錯誤的行停止處理該語句,并保留所有未處理的行。
MySQL支持的IGNORE關鍵字 INSERT, UPDATE等。如果使用它,MySQL將忽略主鍵或唯一鍵沖突,并繼續處理下一行。請參見本節中所使用的語句(第13.2.6節“ INSERT語法”, 第13.2.12節“ UPDATE語法”等)。
您可以獲得有關使用mysql_info()C API函數實際插入或更新的行數的信息 。您也可以使用該SHOW WARNINGS語句。請參見 第28.7.7.36節“ mysql_info()”和 第13.7.7.40節“ SHOW警告語法”。
InnoDB和NDB表支持外鍵。請參見 第1.8.3.2節“外鍵約束”。
外部關鍵約束
外鍵使您可以跨表交叉引用相關數據, 外鍵約束有助于保持此擴展數據的一致性。
MySQL支持ON UPDATE和ON DELETE外鍵的引用 CREATE TABLE和 ALTER TABLE聲明。可用參照動作RESTRICT, CASCADE,SET NULL,和 NO ACTION(默認值)。
SET DEFAULTMySQL服務器也支持,但目前被拒絕為無效服務器 InnoDB。由于MySQL不支持延遲約束檢查,NO ACTION因此將其視為RESTRICT。有關MySQL支持外鍵的確切語法,請參見 第13.1.20.6節“使用外鍵約束”。
MATCH FULL,,MATCH PARTIAL和MATCH SIMPLE被允許,但應避免使用它們,因為它們會導致MySQL Server忽略同一語句中使用的任何ON DELETEor ON UPDATE子句。MATCHoptions在MySQL中沒有任何其他作用,實際上會MATCH SIMPLE全時強制執行語義。
MySQL要求對外鍵列進行索引;如果創建具有外鍵約束但在給定列上沒有索引的表,則會創建一個索引。
您可以從INFORMATION_SCHEMA.KEY_COLUMN_USAGE 表中獲取有關外鍵的信息 。此處顯示了針對該表的查詢示例:
mysql> SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME
> FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
> WHERE REFERENCED_TABLE_SCHEMA IS NOT NULL;
+--------------+---------------+-------------+-----------------+
| TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME |
+--------------+---------------+-------------+-----------------+
| fk1 | myuser | myuser_id | f |
| fk1 | product_order | customer_id | f2 |
| fk1 | product_order | product_id | f1 |
+--------------+---------------+-------------+-----------------+
3 rows in set (0.01 sec)
有關InnoDB 表上外鍵的信息也可以在數據庫的INNODB_FOREIGN和 INNODB_FOREIGN_COLS表中找到 INFORMATION_SCHEMA。
InnoDB和NDB表支持外鍵。有關特定于外鍵支持的信息 ,請參見 第15.6.1.5節“ InnoDB和外鍵約束”InnoDB。
無效數據的約束
默認情況下,MySQL會接受無效或不正確的數據值,并將其強制為有效值以進行數據輸入。但是,可以啟用嚴格的SQL模式來選擇更傳統的錯誤值處理方式,以便服務器拒絕它們并中止發生錯誤的語句。請參見 第5.1.11節“服務器SQL模式”。
本節描述了MySQL的默認(寬容)行為,以及嚴格的SQL模式及其區別。
如果您未使用嚴格模式,則每當您在列中插入 “ 錯誤 ”值(例如 NULL在NOT NULL 列中插入a 或在數值列中插入太大的數值)時,MySQL都會將該列設置為“ 最佳可能值 ”而不是產生錯誤:以下規則更詳細地描述了它是如何工作的:
如果您嘗試將超出范圍的值存儲到數字列中,則MySQL Server會存儲零,最小可能值或最大可能值,以最接近無效值的那個為準。
對于字符串,MySQL存儲空字符串或該列中可以存儲的盡可能多的字符串。
如果您嘗試將不以數字開頭的字符串存儲到數字列中,則MySQL Server將存儲0。
ENUM和 SET列的 無效值如第1.8.3.4節“ ENUM和SET約束”中所述處理。
MySQL允許您將某些不正確的日期值存儲到DATE和 DATETIME列中(例如 '2000-02-31'或 '2000-02-00')。在這種情況下,如果應用程序未啟用嚴格的SQL模式,則由應用程序來驗證日期,然后再存儲它們。如果MySQL可以存儲日期值并檢索完全相同的值,則MySQL按照給定的方式存儲它。如果日期完全錯誤(服務器無法存儲),則將特殊的“ 零 ”日期值 '0000-00-00'存儲在該列中。
如果您嘗試存儲NULL到不帶NULL值的列中,則單行INSERT語句會發生錯誤 。對于多行INSERT 語句或 INSERT INTO ... SELECT語句,MySQL Server存儲列數據類型的隱式默認值。通常,這適用0于數字類型,''適用于字符串類型的空字符串(),適用于日期和時間類型的“ 零 ”值。第11.7節“數據類型默認值”中討論了隱式默認值 。
如果INSERT語句沒有為列指定任何值,則當列定義包含顯式DEFAULT子句時,MySQL將插入其默認值 。如果定義中沒有這樣的DEFAULT子句,MySQL將為列數據類型插入隱式默認值。
在非嚴格模式下使用上述規則的原因是,在語句開始執行之前,我們無法檢查這些條件。如果在更新幾行后遇到問題,我們不能僅僅回滾,因為存儲引擎可能不支持回滾。終止聲明的選擇不是那么好。在這種情況下,更新將 “ 完成一半 ”,這可能是最糟糕的情況。在這種情況下,最好“ 盡力而為 ”,然后繼續進行,好像什么也沒發生。
您可以使用STRICT_TRANS_TABLES或 STRICT_ALL_TABLESSQL模式選擇對輸入值的更嚴格處理 :
SET sql_mode = 'STRICT_TRANS_TABLES';
SET sql_mode = 'STRICT_ALL_TABLES';
STRICT_TRANS_TABLES對事務性存儲引擎以及非事務性引擎在某種程度上啟用嚴格模式。它是這樣的:
對于事務存儲引擎,語句中任何地方出現的錯誤數據值都會導致該語句中止并回滾。
對于非事務性存儲引擎,如果在要插入或更新的第一行中發生錯誤,則語句中止。(當錯誤發生在第一行時,可以中止該語句以使表保持不變,就像事務表一樣。)第一行之后的行中的錯誤不會中止該語句,因為該表已經被表更改了。第一排。相反,錯誤的數據值會被調整并導致警告而不是錯誤。換句話說, STRICT_TRANS_TABLES,錯誤的值會導致MySQL回滾到目前為止已完成的所有更新,如果可以這樣做,而無需更改表。但是一旦更改了表格,其他錯誤將導致調整和警告。
要進行更嚴格的檢查,請啟用 STRICT_ALL_TABLES。這與STRICT_TRANS_TABLES非事務性存儲引擎相同, 但即使對于第一行之后的行中的錯誤數據,錯誤也會中止該語句。這意味著,如果在非事務表的多行插入或更新過程中發生錯誤,則會導致部分更新。較早的行將被插入或更新,但是從錯誤的角度來看則不會。為避免非事務性表出現這種情況,請使用單行語句或使用 STRICT_TRANS_TABLES是否接受轉換警告而不是錯誤。首先要避免出現問題,請勿使用MySQL檢查列內容。讓應用程序確保僅將有效值傳遞給數據庫是最安全的(而且通常更快)。
無論使用哪種嚴格的模式選項,您可以通過使用引起的警告被視為錯誤 INSERT IGNORE或者UPDATE IGNORE,而不是INSERT或 UPDATE不 IGNORE。
ENUM和SET約束
ENUM和 SET列提供了一種有效的方式來定義只能包含一組給定值的列。請參見第11.4.4節“ ENUM類型”和 第11.4.5節“ SET類型”。
在啟用嚴格模式的情況下(請參見第5.1.11節“服務器SQL模式”),a ENUM或 SETcolumn 的定義將作為對輸入到該列中的值的約束。不滿足以下條件的值會發生錯誤:
ENUM值必須是列定義中列出 的值之一,或其內部等效數字。該值不能是錯誤值(即0或空字符串)。對于定義為一列 ENUM('a','b','c'),值,如'','d'或者 'ax'是無效的,并且將被拒絕。
甲SET值必須是空字符串或由僅在由逗號分隔的列定義中列出的值的值。對于定義為的列 SET('a','b','c'),諸如'd'或的 值'a,b,c,d'無效并且被拒絕。
如果使用INSERT IGNORE或,則可以在嚴格模式下抑制無效值的錯誤UPDATE IGNORE。在這種情況下,將生成警告而不是錯誤。對于 ENUM,該值將作為錯誤成員(0)插入。對于 SET,將按給定值插入,除了刪除所有無效的子字符串外。例如,'a,x,b,y'結果為 'a,b'。
總結
以上是生活随笔為你收集整理的mysql添加枚举约束语句_mysql8 参考手册--MySQL如何处理约束的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql查询总结_mysql查询总结相
- 下一篇: python 函数的定义与调用_Pyth