MySQL無效資料的約束

2021-09-01 10:08:44 字數 1776 閱讀 5990

在mysql 5.0.2之前,mysql對非法或不當值並不嚴厲,而且為了資料輸入還會強制將它們變為合法值。在mysql 5.0.2和更高版本中,保留了以前的預設行為,但你可以為不良值選擇更傳統的處理方法,從而使得伺服器能夠拒絕並放棄出現不良值的語句。本節介紹了mysql的預設行為(寬大行為),新的嚴格的sql模式,以及它們的區別。

如果你未使用嚴格模式,下述情況是真實的。如果將「不正確」的值插入到列,如將null值插入非null列,或將過大的數值插入數值列,mysql會將這些列設定為「最可能的值」,而不是生成錯誤資訊。

· 如果試圖將超範圍的值儲存到數值列,mysql伺服器將儲存0(最小的可能值)取而代之,或最大的可能值。

· 對於字串,mysql或儲存空字串,或將字串盡可能多的部分儲存到列中。

· 如果打算將不是以數值開頭的字串儲存到數值列,mysql將儲存0。

· mysql允許將特定的不正確日期值儲存到date和datetime列(如「2000-02-31」或「2000-02-00」)。其觀點在於,驗證日期不是sql伺服器的任務。如果mysql能儲存日期值並準確檢索相同的值,mysql就能按給定的值儲存它。如果日期完全不正確(超出伺服器能儲存的範圍)將在列中儲存特殊的日期值「0000-00-00」取而代之。

· 如果試圖將null值儲存到不接受null值的列,對於單行insert語句,將出現錯誤。對於多行insert語句或insert into ... select語句,mysql伺服器會儲存針對列資料型別的隱含預設值。一般情況下,對於數值型別,它是0,對於字串型別,它是空字串(''),對於日期和時間型別是「zero」。

· 如果insert語句未為列指定值,如果列定義包含明確的default子句,mysql將插入預設值。如果在定義中沒有這類default子句,mysql會插入列資料型別的隱含預設值。

採用前述規則的原因在於,在語句開始執行前,無法檢查這些狀況。如果在更新了數行後遇到這類問題,我們不能僅靠回滾解決,這是因為儲存引擎可能不支援回滾。中止語句並不是良好的選擇,在該情況下,更新完成了「一半」,這或許是最差的情況。對於本例,較好的方法是「僅可能做到最好」,然後就像什麼都未發生那樣繼續。

在mysql 5.0.2和更高版本中,可以使用strict_trans_tables或strict_all_tables sql模式,選擇更嚴格的處理方式。

strict_trans_tables的工作方式:

· 對於事務性儲存引擎,在語句中任何地方出現的不良資料值均會導致放棄語句並執行回滾。

· 對於非事務性儲存引擎,如果錯誤出現在要插入或更新的第1行,將放棄語句。(在這種情況下,可以認為語句未改變表,就像事務表一樣)。首行後出現的錯誤不會導致放棄語句。取而代之的是,將調整不良資料值,並給出告警,而不是錯誤。換句話講,使用strict_trans_tables後,錯誤值會導致mysql執行回滾操作,如果可以,所有更新到此為止。

要想執行更嚴格的檢查,請啟用strict_all_tables。除了非事務性儲存引擎,它與strict_trans_tables等同,即使當不良資料出現在首行後的其他行,所產生的錯誤也會導致放棄語句。這意味著,如果錯誤出現在非事務性表多行插入或更新過程的中途,僅更新部分結果。前面的行將完成插入或更新,但錯誤出現點後面的行則不然。對於非事務性表,為了避免這種情況的發生,可使用單行語句,或者在能接受轉換警告而不是錯誤的情況下使用strict_trans_tables。要想在第1場合防止問題的出現,不要使用mysql來檢查列的內容。最安全的方式(通常也較快)是,讓應用程式負責,僅將有效值傳遞給資料庫。

有了嚴格的模式選項後,可使用insert ignore或update ignore而不是不帶ignore的insert或update,將錯誤當作告警對待。

MySQL中CHECK約束無效

今天才知道在mysql中check約束是無效的,例如下面一段 在建立表table1時新增了check約束,要求field1欄位的值大於零,隨後向field1欄位插入 1,這明顯違反check約束,但這段 在mysql中卻可以執行成功。create table table1 field1 int,ch...

MySQL的check約束無效怎麼辦?

1.check約束mysql可以使用check約束,但check約束對資料驗證沒有任何作用。create table temp id int auto increment primary key id name varchar 20 age int,check約束 check age 20 上面ch...

mysql 延遲約束 mysql資料約束

1,預設值 create table student id int,name varchar 20 address varchar 20 default 山東淄博 預設值 drop table student 當欄位沒有插入值的時候,mysql自動給該字段分配預設值 insert into stud...