約束
什么是約束?
約束對(duì)應(yīng)的英語(yǔ)單詞:constraint
在創(chuàng)建表的時(shí)候,我們可以給表中的字段加上一些約束,來(lái)保證這個(gè)表中數(shù)據(jù)的完整性、有效性?。?!約束的作用就是為了保證:表中的數(shù)據(jù)有效!!
約束的分類(lèi)
- 非空約束
not null
- 唯一性約束
unique
- 主鍵約束
primary key
- 外鍵約束
foreign key
- 檢查約束
check
(mysql不支持,oracle支持)
使用語(yǔ)法:
在創(chuàng)建表的時(shí)候
create table 表名(
字段名1 類(lèi)型1 約束,
字段名2 類(lèi)型2 約束,
字段名3 類(lèi)型3 約束
);
非空約束
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) not null
);
insert into t_vip(id,name) values(1,'zhangsan');
insert into t_vip(id,name) values(2,'lisi');
對(duì)于批量化執(zhí)行SQL語(yǔ)句,我們可以使用執(zhí)行sql腳本的方法。
- 創(chuàng)建
.sql
文件 - 將語(yǔ)句寫(xiě)入文件
- source 腳本路徑
mysql> source D:\mysql_learning\mysql_learning\document\vip.sql
Query OK, 0 rows affected, 1 warning (0.01 sec)
Query OK, 0 rows affected (0.02 sec)
Query OK, 1 row affected (0.00 sec)
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_vip;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | lisi |
+------+----------+
由于給字段name
加了非空約束,因此每次添加數(shù)據(jù)的時(shí)候,如果沒(méi)有添加name
字段的數(shù)據(jù),就會(huì)報(bào)錯(cuò),這樣就保證了數(shù)據(jù)的可行性和完整性。
mysql> insert into t_vip(id) values(123);
ERROR 1364 (HY000): Field 'name' doesn't have a default value
唯一性約束
唯一性約束unique
約束的字段不能重復(fù),但是可以為null
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) unique,
email varchar(255)
);
insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');
insert into t_vip(id,name,email) values(2,'lisi','lisi@123.com');
insert into t_vip(id,name,email) values(3,'wangwu','wangwu@123.com');
select * from t_vip;
這個(gè)時(shí)候加上name重復(fù)的信息,就會(huì)報(bào)錯(cuò)。
mysql> insert into t_vip(id,name,email) values(4,'wangwu','wangwu@sina.com');
ERROR 1062 (23000): Duplicate entry 'wangwu' for key 't_vip.name'
新需求:name和email兩個(gè)字段聯(lián)合起來(lái)具有唯一性?。。。?/p>
也就是說(shuō),一條新的數(shù)據(jù),與表中的數(shù)據(jù)進(jìn)行比較,name或者email字段有一個(gè)可以重復(fù),但是如果和某一個(gè)數(shù)據(jù)比較,發(fā)現(xiàn)name和email字段的信息都重復(fù)了,就會(huì)報(bào)錯(cuò)。
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) unique, // 約束直接添加到列后面的,叫做列級(jí)約束。
email varchar(255) unique
);
這種創(chuàng)建方式不能滿(mǎn)足我們的新要求,因?yàn)檫@樣是分別對(duì)兩個(gè)字段進(jìn)行唯一性約束,兩個(gè)字段,各自唯一。
如果
insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');
insert into t_vip(id,name,email) values(2,'zhangsan','zhangsan@sina.com');
這樣插入新的數(shù)據(jù)就會(huì)報(bào)錯(cuò),因?yàn)閚ame字段重復(fù)了,我們的需求就是有可能會(huì)有重名的人出現(xiàn),但是email是不一定一樣的。
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255),
email varchar(255),
unique(name,email) // 約束沒(méi)有添加在列的后面,這種約束被稱(chēng)為表級(jí)約束。
);
表級(jí)約束,多個(gè)字段聯(lián)合起來(lái)進(jìn)行唯一性約束,與一行數(shù)據(jù)進(jìn)行比較,如果兩個(gè)字段名都重復(fù)了,就會(huì)報(bào)錯(cuò)了。
# 但是這樣是不會(huì)報(bào)錯(cuò)的
insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');
insert into t_vip(id,name,email) values(2,'zhangsan','zhangsan@sina.com');
表級(jí)約束一般用在需要給多個(gè)字段聯(lián)合起來(lái)添加某一個(gè)約束的時(shí)候,需要使用表級(jí)約束:例如允許重名的情況出現(xiàn),但是不允許同時(shí)email也重復(fù)了。
unique
和not null
可以聯(lián)合起來(lái)進(jìn)行約束
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) not null unique
);
在mysql當(dāng)中,如果一個(gè)字段同時(shí)被not null和unique約束的話(huà),該字段自動(dòng)變成主鍵字段。(注意:oracle中不一樣!)
not null
沒(méi)有表級(jí)約束,只能用列級(jí)約束
主鍵約束
primary key
簡(jiǎn)稱(chēng)pk
主鍵字段:在字段上加上主鍵約束,該字段就是主鍵字段。
主鍵值:主鍵上的每個(gè)值就是主鍵值。
主鍵是每一行記錄的唯一標(biāo)識(shí),是一種類(lèi)似身份證的存在??!
每張表都應(yīng)該有主鍵約束,如果沒(méi)有主鍵約束,表就無(wú)效了。
主鍵的特征:not null + unique(主鍵值不能是NULL,同時(shí)也不能重復(fù)?。?/strong>
列級(jí)約束:
create table t_vip(
id int primary key, //列級(jí)約束
name varchar(255)
);
insert into t_vip(id,name) values(1,'zhangsan');
insert into t_vip(id,name) values(2,'lisi');
insert into t_vip(id,name) values(2,'wangwu');# 報(bào)錯(cuò),id為2,重復(fù)了
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
insert into t_vip(name) values('zhaoliu');# 報(bào)錯(cuò),id為null,不能為null
ERROR 1364 (HY000): Field 'id' doesn't have a default value
表級(jí)約束:
create table t_vip(
id int,
name varchar(255),
primary key(id) // 表級(jí)約束
);
表級(jí)約束是用來(lái)對(duì)多個(gè)字段進(jìn)行聯(lián)合添加約束:
create table t_vip(
id int,
name varchar(255),
email varchar(255),
primary key(id,name) # id和name字段聯(lián)合起來(lái)作為主鍵約束
);
insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');
insert into t_vip(id,name,email) values(1,'lisi','lisi@123.com');# 這樣是正確的,不會(huì)報(bào)錯(cuò)
insert into t_vip(id,name,email) values(1,'lisi','lisi@123.com');# 錯(cuò)誤,報(bào)錯(cuò),1-lisi同時(shí)重復(fù)
ERROR 1062 (23000): Duplicate entry '1-lisi' for key 'PRIMARY'
一個(gè)字段的主鍵約束被稱(chēng)作單一主鍵,多個(gè)字段聯(lián)合作為主鍵被稱(chēng)作復(fù)合主鍵,不推崇復(fù)合主鍵。
同時(shí),一張表只能有一個(gè)主鍵約束。
作為主鍵約束的字段一般是int
bigint
char
類(lèi)型,一般都是定長(zhǎng)的,不建議varchar
類(lèi)型
主鍵除了:?jiǎn)我恢麈I和復(fù)合主鍵之外,還可以這樣進(jìn)行分類(lèi)?
自然主鍵:主鍵值是一個(gè)自然數(shù),和業(yè)務(wù)沒(méi)關(guān)系。
業(yè)務(wù)主鍵:主鍵值和業(yè)務(wù)緊密關(guān)聯(lián),例如拿銀行卡賬號(hào)做主鍵值。這就是業(yè)務(wù)主鍵!在實(shí)際開(kāi)發(fā)中使用業(yè)務(wù)主鍵多,還是使用自然主鍵多一些?
自然主鍵使用比較多,因?yàn)橹麈I只要做到不重復(fù)就行,不需要有意義。
業(yè)務(wù)主鍵不好,因?yàn)橹麈I一旦和業(yè)務(wù)掛鉤,那么當(dāng)業(yè)務(wù)發(fā)生變動(dòng)的時(shí)候,
可能會(huì)影響到主鍵值,所以業(yè)務(wù)主鍵不建議使用。盡量使用自然主鍵。
使用auto_increment
自動(dòng)維護(hù)主鍵值,auto_increment
表示自增,從1開(kāi)始,以1遞增!
mysql> create table t_vip(
-> id int primary key auto_increment,
-> name varchar(32)
-> );
# 之后多次插入數(shù)據(jù):
insert into t_vip(name) values('zhangsan');
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
| 2 | zhangsan |
| 3 | zhangsan |
| 4 | zhangsan |
| 5 | zhangsan |
| 6 | zhangsan |
| 7 | zhangsan |
| 8 | zhangsan |
+----+----------+
外鍵約束
當(dāng)我們要將兩個(gè)表連接的時(shí)候,各自會(huì)將一個(gè)字段值作為兩個(gè)表連接的“接口”,但是有時(shí)候這兩個(gè)表中這個(gè)字段值會(huì)有點(diǎn)出入,導(dǎo)致兩個(gè)表連接的時(shí)候會(huì)有記錄無(wú)法匹配的情況出現(xiàn),而外鍵約束則能保證這兩個(gè)表中,作為兩表接口的字段值能完全匹配上。
兩個(gè)概念:
子表和父表;
子表引用父表中的一個(gè)字段值作為外鍵約束。
順序:
刪除表的順序?
先刪子,再刪父。
創(chuàng)建表的順序?
先創(chuàng)建父,再創(chuàng)建子。
刪除數(shù)據(jù)的順序?
先刪子,再刪父。
插入數(shù)據(jù)的順序?
先插入父,再插入子。
foreign key(cno) references t_class(classno)
drop table if exists t_student;
drop table if exists t_class;
create table t_class( # 父表
classno int primary key,
classname varchar(255)
);
create table t_student( # 子表
no int primary key auto_increment,
name varchar(255),
cno int,
foreign key(cno) references t_class(classno)# 參照t_class中的classno對(duì)cno進(jìn)行外鍵約束
);
insert into t_class(classno, classname) values(100, '北京市大興區(qū)亦莊鎮(zhèn)第二中學(xué)高三1班');
insert into t_class(classno, classname) values(101, '北京市大興區(qū)亦莊鎮(zhèn)第二中學(xué)高三1班');
insert into t_student(name,cno) values('jack', 100);
insert into t_student(name,cno) values('lucy', 100);
insert into t_student(name,cno) values('lilei', 100);
insert into t_student(name,cno) values('hanmeimei', 100);
insert into t_student(name,cno) values('zhangsan', 101);
insert into t_student(name,cno) values('lisi', 101);
insert into t_student(name,cno) values('wangwu', 101);
insert into t_student(name,cno) values('zhaoliu', 101);
select * from t_student;
select * from t_class;
mysql> select * from t_student;
+----+-----------+------+
| no | name | cno |
+----+-----------+------+
| 1 | jack | 100 |
| 2 | lucy | 100 |
| 3 | lilei | 100 |
| 4 | hanmeimei | 100 |
| 5 | zhangsan | 101 |
| 6 | lisi | 101 |
| 7 | wangwu | 101 |
| 8 | zhaoliu | 101 |
+----+-----------+------+
8 rows in set (0.00 sec)
mysql> select * from t_class;
+---------+---------------------------------------------------+
| classno | classname |
+---------+---------------------------------------------------+
| 100 | 北京市大興區(qū)亦莊鎮(zhèn)第二中學(xué)高三1班 |
| 101 | 北京市大興區(qū)亦莊鎮(zhèn)第二中學(xué)高三1班 |
+---------+---------------------------------------------------+
2 rows in set (0.00 sec)
這個(gè)時(shí)候如果在外鍵約束之外添加字段cno
的字段值
mysql> insert into t_student(name,cno) values('kuku',110);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`bjpowernnode`.`t_student`, CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`cno`) REFERENCES `t_class` (`classno`))
就會(huì)報(bào)錯(cuò)。
外鍵引用父表中的某個(gè)字段,該字段應(yīng)該至少有unique唯一性約束,但不一定是主鍵文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-696325.html
外鍵值可以是null。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-696325.html
到了這里,關(guān)于MySql學(xué)習(xí)筆記06——約束介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!