文章目錄
- MySQL
- 表的約束
- 1. 空屬性
- 2. 默認值
- 3. 列描述
- 4. zerofill
- 5. 主鍵
- 6. 自增長
- 7. 唯一鍵
- 8. 外鍵
MySQL
??
表的約束
??MySQL中的表的約束是一種規則,用于限制或保護表中數據的完整性和合法性。約束可以確保數據在插入、更新或刪除時滿足特定的條件,從而維護數據的正確性和一致性。
1. 空屬性
??兩個值:null
(默認的)和not null
(不為空)
??數據庫默認字段基本都是字段為空,但是實際開發時,盡可能保證字段不為空,因為數據為空沒辦法參與運算。
創建一個數據表其中的id1為NULL,id2為NOT NULL:
create table test1(id1 int null,id2 int not null);
??
查看表中的結構:
desc test1;
我們看到對于數據id1,是可以填寫NULL值的,而id2則無法填寫空值。
??
向test1插入不同的數據并且打印:
insert into test1(id1,id2) values(10,20); // 插入成功insert into test1(id2) values(20); // 插入成功,id1可以為空值insert into test1(id1) values(20); // 插入失敗,id2不可以是空值
//ERROR 1364 (HY000): Field 'id2' doesn't have a default value
??所以我們在設計數據庫表的時候,一定要在表中進行限制,滿足上面條件的數據就不能插入到表中。這就是“約束”。
??
2. 默認值
??默認值:某一種數據會經常性的出現某個具體的值,可以在一開始就指定好,在需要真實數據的時候,用戶可以選擇性的使用默認值。
??注意:not null和defalut一般不需要同時出現,因為default本身有默認值,不會為空。
創建一個表,包含不能為空的姓名,默認值為0的年齡,默認值為男的性別:
mysql> create table test2(-> name varchar(20) not null,-> age tinyint unsigned default 0,-> sex char(2) default '男'-> );
??
查看表中的結構:
desc test2;
??可以看到我們的年齡和性別都成功的設置好了默認值0和男。當我們在插入數據的時候不給該字段賦值,就使用默認值。
??
向表中插入數據并打印:
mysql> insert into test2(name,age,sex) values('張三',18,'男');
mysql> insert into test2(name,age,sex) values('小紅',20,'女');
mysql> insert into test2(name,age) values('李四',22); // 只使用sex的默認值
mysql> insert into test2(name) values('王五'); // 只填了姓名,使用age和sex的默認值
??
3. 列描述
??列描述:comment,沒有實際含義,專門用來描述字段,會根據表創建語句保存,用來給程序員或DBA來進行了解,類似注釋。
創建和上面類似的代碼同時加上列描述:
mysql> create table test3(-> name varchar(20) not null comment '姓名',-> age tinyint default 0 comment '年齡',-> sex char(2) default '男' comment '性別'-> );
??
此時不能desc查看到列描述,但是可以使用show操作:
desc test3;
show create table test3\G
??
4. zerofill
??zerofill:將自動為該列的值填充前導零,以確保該列的總寬度(包括符號位,如果有的話)與列定義中指定的顯示寬度相匹配,類似一種格式化輸出。
創建一張表,其中int類型a使用zerofill,而int類型b不加任何約束:
mysql> create table test4(-> a int(5) zerofill,-> b int(10)-> );
??
查看表的結構:
desc test4;
??
插入數據并且打印:
mysql> insert into test4(a,b) values(1,1);
mysql> insert into test4(a,b) values(10,20);
mysql> select * from test4;
??
??int既然是四個字節,那是否int(10)和int(5)是一樣的呢?
??其實沒有zerofill這個屬性,括號內的數字是毫無意義的。這個數字并不代表該列可以存儲的最大整數值或存儲大小。相反,這個數字是所謂的“顯示寬度”(display width),它主要用于控制當查詢結果返回時該列的顯示寬度。
我們使用十六進制查看a的數值:
mysql> select a,hex(a) from test4;
??所以可以看出數據庫內部存儲的還是1和10,00001和00010只是設置了zerofill屬性后的一種格式化輸出而已。
??
5. 主鍵
??主鍵:primary key用來唯一的約束該字段里面的數據,不能重復,不能為空,一張表中最多只能有一個主鍵;主鍵所在的列通常是整數類型。
創建一張表,其中包括int類型的id和varchar類型的name,其中id為主鍵:
mysql> create table test5(-> id int unsigned primary key,-> name varchar(20)-> );
??
查看表結構:
desc test5;
??其中id的Key就標記上了主鍵標志PRI。
??
向表中插入數據并且打印:
mysql> insert into test5 values(1,'張三');
mysql> insert into test5 values(2,'李四');
mysql> insert into test5 values(3,'王五');mysql> insert into test5 values(3,'趙六');
ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY'
??我們看到了當表中有id為3的數據時,此時在插入id=3的數據時就會直接報錯,這樣就很好的約束了我們表中由主鍵標記的數據是唯一的。
??
刪除主鍵(id):
mysql> alter table test5 drop primary key;
??
如果創建的表中沒有主鍵,我們可以向某一個字段(這里向id)追加主鍵:
alter table test5 add primary key(id);
??
上面,如果追加的字段有重復的字段,就無法繼續追加主鍵,需要刪除相同的字段:
??此時的表中有重復的id。
??因為有重復的id,所以添加主鍵失敗。
??刪除重復包含的id的數據。
??再次插入主鍵成功。
??
6. 自增長
??auto_increment:當對應的字段,不給值,會自動的被系統觸發,系統會從當前字段中已經有的最大值+1操作,得到一個新的不同的值。通常和主鍵搭配使用,作為邏輯主鍵。
??自增長的特點:
??(1)任何一個字段要做自增長,前提是本身是一個索引(key一欄有值);
??(2)自增長字段必須是整數;
??(3)一張表最多只能有一個自增長。
??
創建一張表,其中的id為主鍵且自增長,name為varchar類型:
mysql> create table test6(-> id int primary key auto_increment,-> name varchar(10)-> );
??
查看表結構:
desc test6;
??
插入數據并且打印:
mysql> insert into test6 values(1,'張三');
mysql> insert into test6 values(2,'李四');
mysql> insert into test6(name) values('王五');mysql> select * from test6;
??可以看到我們在沒有輸入id的時候,自增長會幫我們自動的向最大值進行+1操作。
??
7. 唯一鍵
??一張表中有往往有很多字段需要唯一性,數據不能重復,但是一張表中只能有一個主鍵:唯一鍵就可以解決表中有多個字段需要唯一性約束的問題。
??唯一鍵的本質和主鍵差不多,唯一鍵允許為空,而且可以多個為空,空字段不做唯一性比較。
??關于唯一鍵和主鍵的區別:
??我們可以簡單理解成,主鍵更多的是標識唯一性的。而唯一鍵更多的是保證在業務上,不要和別的信息出現重復。 就像我們在學校一樣,我們的學號就是我們的主鍵是唯一標識的,而學生的手機號設置為唯一鍵(可能會人沒有手機號的情況)。
??學號字段是主鍵,它保證了每個學生都有一個唯一的學號,并且學號不能為空。手機號是唯一鍵,它確保了在這個表中手機號的唯一性。因為我們不會使用每個人的手機號做區分的標識。主鍵和唯一鍵不沖突,相互補充。
??
創建表,其中的id為主鍵,phone為唯一鍵:
mysql> create table test7(-> id int primary key,-> phone int unique-> );
??
查看表結構:
desc test7;
??
插入數據并且打印:
mysql> insert into test7 values(1,111);
mysql> insert into test7 values(2,222);
mysql> insert into test7 values(3,333);mysql> insert into test7 values(4,333);
ERROR 1062 (23000): Duplicate entry '333' for key 'phone' // phone重復,直接報錯mysql> select *from test7;
??
8. 外鍵
??外鍵用于定義主表和從表之間的關系:外鍵約束主要定義在從表上,主表則必須是有主鍵約束或unique約束。當定義外鍵后,要求外鍵列數據必須在主表的主鍵列存在或為null。
??
創建主鍵表包含id和name:
create table myclass (id int primary key,name varchar(30) not null comment'班級名'
);
??
創建從表包含id,name,class_id,外連接myclass的id:
create table stu (id int primary key,name varchar(30) not null comment '學生名',class_id int,foreign key (class_id) references myclass(id)
);
??
查看兩張表的結構:
??
插入數據并且打印:
mysql> insert into myclass values(10, 'C++大牛班'),(20, 'java大神班');
mysql> insert into stu values(100, '張三', 10),(101, '李四',20);mysql> insert into stu values(102, 'wangwu',30); // 沒有這個班級,插入失敗
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`constraint_test`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `myclass` (`id`))
mysql> select* from myclass;
mysql> select* from stu;
??
笛卡爾積打印兩張表的組合:
mysql> select* from stu,myclass;
??
篩選出有關聯的數據:
mysql> select* from stu,myclass where stu.class_id=myclass.id;
??