文章目錄
- 前言
- 1. 空屬性
- 2. 默認值
- 3. 列描述
- 4. zerofill
- 5. 主鍵
- 6. 自增長
- 7. 唯一鍵
- 8. 外鍵
前言
??真正約束字段的是數據類型,但是數據類型約束很單一,需要有一些額外的約束,更好的保證數據的合法性,從業務邏輯角度保證數據的正確性。比如有一個字段是email,要求是唯一的。
??表的約束很多,這里主要介紹如下幾個: null/not null,default,comment,zerofill,primary key,auto_increment,unique key 。
??約束的本質是通過技術手段,倒逼程序員加入正確的數據。反過來站在MySQL的視角,凡是插入進來的數據,都是符合數據約束的。約束的最終目標:保證數據的完整性和預期性。
1. 空屬性
- 兩個值:null(默認的)和not null(不為空)
- 數據庫默認字段基本都是字段為空,但是實際開發時,盡可能保證字段不為空,因為數據為空沒辦法參與運算。
??實例:
2. 默認值
??默認值:某一種數據會經常性的出現某個具體的值,可以在一開始就指定好,在需要真實數據的時候,用戶可以選擇性的使用默認值。
??默認值的生效:數據在插入的時候不給該字段賦值,就使用默認值。
3. 列描述
??列描述:comment,沒有實際含義,專門用來描述字段,會根據表創建語句保存,用來給程序員或DBA來進行了解。
??列描述同desc是看不到的,但是可以通過show create table 表名 \G 查看。
4. zerofill
??剛開始學習數據庫時,很多人對數字類型后面的長度很迷茫。通過show看看tt3表的建表語句:
??可以看到int(10),這個代表什么意思呢?整型不是4字節碼?這個10又代表什么呢?其實沒有zerofill這個屬性,括號內的數字是毫無意義的。a和b列就是前面插入的數據,如下:
mysql> insert into tt3 values(1,2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from tt3;
+------+------+
| a | b |
+------+------+
| 1 | 2 |
+------+------+
??但是對列添加了zerofill屬性后,顯示的結果就有所不同了。修改tt3表的屬性:
mysql> alter table tt3 change a a int(5) unsigned zerofill;
??對a列添加了zerofill屬性,再進行查找,返回如下結果:
mysql> select * from tt3;
+-------+------+
| a | b |
+-------+------+
| 00001 | 2 |
+-------+------+
??這次可以看到a的值由原來的1變成00001,這就是zerofill屬性的作用,如果寬度小于設定的寬度(這里設置的是5),自動填充0。要注意的是,這只是最后顯示的結果,在MySQL中實際存儲的還是1。為什么是這樣呢?我們可以用hex函數來證明。
mysql> select a, hex(a) from tt3;
+-------+--------+
| a | hex(a) |
+-------+--------+
| 00001 | 1 |
+-------+--------+
??可以看出數據庫內部存儲的還是1,00001只是設置了zerofill屬性后的一種格式化輸出而已。
??zerofill的作用就是將數據設置成等寬的長度,不夠的會在前面補零。
alter table 表名 modify a int(5) unsigned zerofill;
??括號中的寬度可以自己隨意設置。
5. 主鍵
??主鍵:primary key用來唯一的約束該字段里面的數據,不能重復,不能為空,一張表中最多只能有一個主鍵;主鍵所在的列通常是整數類型。
-
主鍵約束:主鍵對應的字段中不能重復,一旦重復,操作失敗。
-
當表創建好以后但是沒有主鍵的時候,可以再次追加主鍵
alter table 表名 add primary key(字段列表)
- 刪除主鍵:
alter table 表名 drop primary key;delete from 表名 where 屬性=具體值; --- 刪除表中的某一個數據
- 復合主鍵
??在創建表的時候,在所有字段之后,使用primary key(主鍵字段列表)來創建主鍵,如果有多個字段作為主鍵,可以使用復合主鍵。
??對于復合主鍵,比如下面的例子,對于插入的數據,課程號是可以一樣的,在這里看主鍵時需要將id和course一起看,只有當兩個數據同時其他數據重復時才會報錯(比如,插入了id=1和course=1,然后又插入了id=1和course=1就會報錯,如果插入的是id=1和course=2,是不會報錯的。)
6. 自增長
??auto_increment:當對應的字段,不給值,會自動的被系統觸發,系統會從當前字段中已經有的最大值+1操作,得到一個新的不同的值。通常和主鍵搭配使用,作為邏輯主鍵。
??自增長的特點:
- 任何一個字段要做自增長,前提是本身是一個索引(key一欄有值)
- 自增長字段必須是整數
- 一張表最多只能有一個自增長
??它會選取最大的值進行遞增。
??自增長也可以在創建表的時候進行設置:
create table 表名(id int,name varchar(20)
)auto_increment=100;
??在插入后獲取上次插入的 AUTO_INCREMENT 的值(批量插入獲取的是第一個值):
mysql > select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 1 |
+------------------+
??索引:
??在關系數據庫中,索引是一種單獨的、物理的對數據庫表中一列或多列的值進行排序的一種存儲結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的數據頁的邏輯指針清單。索引的作用相當于圖書的目錄,可以根據目錄中的頁碼快速找到所需的內容。
??索引提供指向存儲在表的指定列中的數據值的指針,然后根據您指定的排序順序對這些指針排序。數據庫使用索引以找到特定值,然后順指針找到包含該值的行。這樣可以使對應于表的SQL語句執行得更快,可快速訪問數據庫表中的特定信息。
7. 唯一鍵
??一張表中有往往有很多字段需要唯一性,數據不能重復,但是一張表中只能有一個主鍵:唯一鍵就可以解決表中有多個字段需要唯一性約束的問題。
??唯一鍵的本質和主鍵差不多,唯一鍵允許為空,而且可以多個為空,空字段不做唯一性比較。
??關于唯一鍵和主鍵的區別:
??我們可以簡單理解成,主鍵更多的是標識唯一性的。而唯一鍵更多的是保證在業務上,不要和別的信息出現重復。乍一聽好像沒啥區別,我們舉一個例子:
??假設一個場景(當然,具體可能并不是這樣,僅僅為了幫助大家理解)
??比如在公司,我們需要一個員工管理系統,系統中有一個員工表,員工表中有兩列信息,一個身份證號碼,一個是員工工號,我們可以選擇身份號碼作為主鍵。
??而我們設計員工工號的時候,需要一種約束:而所有的員工工號都不能重復。
具體指的是在公司的業務上不能重復,我們設計表的時候,需要這個約束,那么就可以將員工工號設計成為唯一鍵。
??一般而言,我們建議將主鍵設計成為和當前業務無關的字段,這樣,當業務調整的時候,我們可以盡量不會對主鍵做過大的調整。
??主鍵不能為空,唯一鍵可以為空,空字段不做唯一性比較。
8. 外鍵
??外鍵用于定義主表和從表之間的關系:外鍵約束主要定義在從表上,主表則必須是有主鍵約束或unique約束。當定義外鍵后,要求外鍵列數據必須在主表的主鍵列存在或為null。
??語法:
foreign key (字段名) references 主表(列)
??案例:
??創建班級:
??向學生表中插入對應班級的學生:
??我們并沒有創建班級號 id 為3的班級,當我們插入一個班級id為3的學生時,就會報錯,這就是外鍵的作用。如果我們沒有設置外鍵,那么對于學生表就可以隨意插入,即使班級號不存在,我們也可以插入。
??當沒有外鍵時,就可以將它們看成兩個單獨的表,插入一些非法數據,比如插入一個班級不存在的學生,也是可以成功的。但是加入外鍵時,就必須遵守一些約束了。
??如何理解外鍵約束:
??首先我們承認,這個世界是數據很多都是相關性的。
??理論上,上面的例子,我們不創建外鍵約束,就正常建立學生表,以及班級表,該有的字段我們都有。
??此時,在實際使用的時候,可能會出現什么問題?
??有沒有可能插入的學生信息中有具體的班級,但是該班級卻沒有在班級表中?
??因為此時兩張表在業務上是有相關性的,但是在業務上沒有建立約束關系,那么就可能出現問題。
??解決方案就是通過外鍵完成的。建立外鍵的本質其實就是把相關性交給mysql去審核了,提前告訴mysql表之間的約束關系,那么當用戶插入不符合業務邏輯的數據的時候,mysql不允許你插入。