表的約束
? ? ? ? 在 MySQL 中,表的約束(Constraints)用于確保數據庫中數據的完整性和一致性。它們定義了對表中數據的規則和限制,防止無效或不一致的數據被插入、更新或刪除。常見的 MySQL 表約束包括主鍵約束(PRIMARY KEY)、外鍵約束(FOREIGN KEY)、唯一約束(UNIQUE)、非空約束(NOT NULL)、檢查約束(CHECK)、默認約束(DEFAULT)、自增約束(AUTO_INCREMENT)等,這些約束可以在創建表時定義,也可以使用?ALTER TABLE
?語句在已存在的表上添加或修改。合理使用約束可以大大提高數據庫中數據的質量和可靠性。
? ? ? ? 但事實上真正約束字段的是數據類型,但是數據類型約束很單一,需要有一些額外的約束,更好的保證數據的合 法性,從業務邏輯角度保證數據的正確性。 表的約束很多,這里主要介紹如下幾個: null/not null,default, comment, zerofill,primary key,auto_increment,unique key
空屬性
? ? ? ? 在 MySQL 中,空屬性(NULL/NOT NULL)?是最基礎也最常用的表約束之一,用于控制列是否允許存儲?NULL
?值(表示 "無值" 或 "未知值")。
- NULL:表示列允許存儲空值(默認行為)
- NOT NULL:強制列必須存儲具體值,不允許為空
注意:數據庫默認字段基本都是字段為空,但是實際開發時,盡可能保證字段不為空,因為數據為空沒辦 法參與運算。
如圖所示
案例:
? ? ? ? 創建一個班級表,包含班級名和班級所在的教室。
? ? ? ? 站在正常的業務邏輯中: 如果班級沒有名字,你不知道你在哪個班級 如果教室名字可以為空,就不知道在哪上課 。
? ? ? ? 所以我們在設計數據庫表的時候,一定要在表中進行限制,滿足上面條件的數據就不能插入到表中。這 就是“約束”。
如圖所示
? ? ? ? 我們創建一個名為“myclass”的表來測試一下。
? ? ? ? 然后,查看一下表的數據結構。
? ? ? ? 可以看到,我們在創建數據表的時候,定義了字段“class-name”和“class-room”為 not null,以及字段“other”為 null。然后我們來測試一下這兩個字段是否允許 null。
? ? ? ? 插入幾組數據來做測試。
? ? ? ? 通過測試可以發現字段“other”是允許為 null 的,而字段“class-name”和“class-room”是不允許為 null 的。
默認值
? ? ? ? 在 MySQL 中,默認值約束(DEFAULT)?用于為表中的列指定一個默認值。當向表中插入數據時,如果沒有為該列提供具體值,MySQL 會自動使用默認值填充。
? ? ? ? 我們創建一個名為“t13”的表來測試一下。
? ? ? ??查看一下表的數據結構。
? ? ? ? 插入幾組數據來測試一下。
? ? ? ?查看一下插入的數據。
? ? ? ?我們這時插入數據是正常插入的。
? ? ? ?假設我們只插入name這一列。
? ? ? ? 可以看出,這時其余兩項是默認插入的,并不是用戶主動插入的。
? ? ? ? 我們創建一個表再來看一下。
? ? ? ? 查看一下這張表的數據結構。
? ?我們可以看到Default
列是默認值。如果插入數據時沒有指定該列的值,會使用默認值。name
?的默認值是?NULL
,但由于?name
?不允許為?NULL
,所以插入時必須顯式指定?name
?的值。age
?的默認值是?18
。gender
?的默認值是?男。
? ? ? ? 我們不妨忽略gender和age試試。
? ? ? ? 可以看出,我們所忽略的值都是被默認插入了。
注意:
與 NOT NULL 結合:默認值通常與?
NOT NULL
?一起使用,確保列既有默認值又不允許為空sql
函數作為默認值:MySQL 支持使用某些函數作為默認值。
插入時覆蓋默認值:如果插入數據時指定了具體值,將覆蓋默認值
列描述
? ? ? ? 在 MySQL 中,“列描述” 并不是一種約束,而是用于對表中的列進行說明、注釋,方便其他開發者或自己后續了解列的含義等信息。可以通過?COMMENT
?關鍵字來為列添加描述信息。
? ? ? ? 這部分我們就來簡單了解一下。
? ? ? ? 創建一個表來進行測試并查看一下表結構。
? ? ? ? 插入幾組數據。
? ? ? ? 解釋一下,列描述:comment,沒有實際含義,專門用來描述字段,會根據表創建語句保存,用來給程序員或DBA 來進行了解。
zerofill
? ? ? ? 在 MySQL 中,ZEROFILL
?是一種針對數值類型列的特殊約束(更準確地說是一種格式屬性),用于在數值的顯示長度不足時,自動在前面補零(0)。
- 僅影響數值的顯示形式,不改變數據的實際存儲值
- 自動為列隱式添加?
UNSIGNED
?屬性(無符號,即只能存儲非負數值)
如圖所示
? ? ? ? 創建一個表,并查看一下它的表結構。
? ? ? ? ?可以看到int(10),這個代表什么意思呢?整型不是4字節碼?這個10又代表什么呢?其實沒有zerofill這個 屬性,括號內的數字是毫無意義的。
? ? ? ? 現在我們來插入幾組數據。
? ? ? ? 接著修改一下它的數據結構。
? ? ? ??但是對列添加了zerofill屬性后,顯示的結果就有所不同了。
? ? ? ??這次可以看到b的值由原來的2變成00002,這就是zerofill屬性的作用,如果寬度小于設定的寬度(這里設置的是10),自動填充0。要注意的是,這只是最后顯示的結果,在MySQL中實際存儲的還是1。為什 么是這樣呢?我們可以用hex函數來證明。