mysql學習【第5篇】:資料庫之完整性約束 資料庫之完整性約束
一、介紹
約束條件與資料型別的寬度一樣,都是可選引數
作用:用於保證資料的完整性和一致性
主要分為:
PRIMARY KEY (PK) 標識該欄位為該表的主鍵,可以唯一的標識記錄 FOREIGN KEY (FK) 標識該欄位為該表的外來鍵 NOT NULL 標識該欄位不能為空 UNIQUE KEY (UK) 標識該欄位的值是唯一的 AUTO_INCREMENT 標識該欄位的值自動增長(整數型別,而且為主鍵) DEFAULT 為該欄位設定預設值 UNSIGNED 無符號 ZEROFILL 使用0填充
說明:
1. 是否允許為空,預設NULL,可設定NOT NULL,欄位不允許為空,必須賦值
2. 欄位是否有預設值,預設的預設值是NULL,如果插入記錄時不給欄位賦值,此欄位使用預設值
sex enum('male','female') not null default 'male'
age int unsigned NOT NULL default 20 必須為正值(無符號) 不允許為空 預設是20
3. 是否是key
主鍵 primary key
外來鍵 foreign key
索引 (index,unique...)
二、not null 和default
是否可空,null表示空,非字串
not null - 不可空
null - 可空
default預設值,建立列時可以指定預設值,當插入資料時如果未主動設定,則自動新增預設值
create table tb1(
id int not null defalut 2 ,
num int not null
)
三、unique約束(唯一性約束)
單列唯一
-----1.單列唯一---------
create table t2(
id int not null unique,
name char(10)
);
insert into t2 values(1,'egon');
insert into t2 values(1,'alex');
#上面建立表的時候把id設定了唯一約束。那麼在插入id=1,就會出錯了
多列唯一
-----2.多列唯一---------
#255.255.255.255
create table server(
id int primary key auto_increment,
name char(10),
host char(15), #主機ip
port int, #埠
constraint host_port unique(host,port) #constraint host_port這個只是用來設定唯一約束的名字的,也可以不設定預設就有了
);
insert into server(name,host,port) values('ftp','192.168.20.11',8080);
insert into server(name,host,port) values('https','192.168.20.11',8081); #ip和埠合起來唯一
select * from server;
四、primary key (主鍵約束)
primary key欄位的值不為空且唯一
一個表中可以:
單列做主鍵
多列做主鍵(複合主鍵)
但一個表內只能有一個主鍵primary key
1 ============單列做主鍵===============
2 #方法一:not null+unique
3 create table department1(
4 id int not null unique, #主鍵
5 name varchar(20) not null unique,
6 comment varchar(100)
7 );
8
9 mysql> desc department1;
10 +---------+--------------+------+-----+---------+-------+
11 | Field | Type | Null | Key | Default | Extra |
12 +---------+--------------+------+-----+---------+-------+
13 | id | int(11) | NO | PRI | NULL | |
14 | name | varchar(20) | NO | UNI | NULL | |
15 | comment | varchar(100) | YES | | NULL | |
16 +---------+--------------+------+-----+---------+-------+
17 rows in set (0.01 sec) 18 19 #方法二:在某一個欄位後用primary key 20 create table department2( 21 id int primary key, #主鍵 22 name varchar(20), 23 comment varchar(100) 24 ); 25 26 mysql> desc department2; 27 +---------+--------------+------+-----+---------+-------+ 28 | Field | Type | Null | Key | Default | Extra | 29 +---------+--------------+------+-----+---------+-------+ 30 | id | int(11) | NO | PRI | NULL | | 31 | name | varchar(20) | YES | | NULL | | 32 | comment | varchar(100) | YES | | NULL | | 33 +---------+--------------+------+-----+---------+-------+ 34 rows in set (0.00 sec) 35 36 #方法三:在所有欄位後單獨定義primary key 37 create table department3( 38 id int, 39 name varchar(20), 40 comment varchar(100), 41 constraint pk_name primary key(id); #建立主鍵併為其命名pk_name 42 43 mysql> desc department3; 44 +---------+--------------+------+-----+---------+-------+ 45 | Field | Type | Null | Key | Default | Extra | 46 +---------+--------------+------+-----+---------+-------+ 47 | id | int(11) | NO | PRI | NULL | | 48 | name | varchar(20) | YES | | NULL | | 49 | comment | varchar(100) | YES | | NULL | | 50 +---------+--------------+------+-----+---------+-------+ 51 rows in set (0.01 sec) 52 53 單列主鍵
1 ==================多列做主鍵================
2 create table service(
3 ip varchar(15),
4 port char(5),
5 service_name varchar(10) not null,
6 primary key(ip,port)
7 ); 8 9 10 mysql> desc service; 11 +--------------+-------------+------+-----+---------+-------+ 12 | Field | Type | Null | Key | Default | Extra | 13 +--------------+-------------+------+-----+---------+-------+ 14 | ip | varchar(15) | NO | PRI | NULL | | 15 | port | char(5) | NO | PRI | NULL | | 16 | service_name | varchar(10) | NO | | NULL | | 17 +--------------+-------------+------+-----+---------+-------+ 18 rows in set (0.00 sec) 19 20 mysql> insert into service values 21 -> ('172.16.45.10','3306','mysqld'), 22 -> ('172.16.45.11','3306','mariadb') 23 -> ; 24 Query OK, 2 rows affected (0.00 sec) 25 Records: 2 Duplicates: 0 Warnings: 0 26 27 mysql> insert into service values ('172.16.45.10','3306','nginx'); 28 ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306' for key 'PRIMARY'
五、auto_increment (自增約束)
步長increment與起始偏移量offset:auto_increment_increment,auto_increment_offset
3.--------偏移量:auto_increment_offset---------
==============沒有設定偏移量的時候
create table dep(
id int primary key auto_increment,
name char(10)
);
insert into dep(name) values('IT'),('HR'),('EFO');
select * from dep;
================設定自增的時候以10開頭
create table dep1(
id int primary key auto_increment,
name char(10) )auto_increment = 10; insert into dep1(name) values('IT'),('HR'),('EFO'); select * from dep1; ===============auto_increment_increment:自增步長 create table dep3( id int primary key auto_increment, name char(10) ); 會話:通過客戶端連到服務端(一次連結稱為一次會話) set session auto_increment_increment = 2; #會話級,只對當前會話有效 set global auto_increment_increment=2; #全域性,對所有的會話都有效 insert into dep3(name) values('IT'),('HR'),('SALE'),('Boss'); -----------檢視變數---------- show variables like '%auto_in%';#檢視變數。只要包含auto_in就都查出來了 =========auto_increment_offset:偏移量+auto_increment_increment:步長=========== 注意:如果auto_increment_offset的值大於auto_increment_increment的值, 則auto_increment_offset的值會被忽略 set session auto_increment_offset=2; set session auto_increment_increment=3; show variables like '%auto_in%'; create table dep4( id int primary key auto_increment, name char(10) ); insert into dep4(name) values('IT'),('HR'),('SALE'),('Boss');
六、foreign key (外來鍵約束)
員工資訊表有三個欄位:工號 姓名 部門
公司有3個部門,但是有1個億的員工,那意味著部門這個欄位需要重複儲存,部門名字越長,越浪費
解決方法:
我們完全可以定義一個部門表
然後讓員工資訊表關聯該表,如何關聯,即foreign key
如下圖簡單的表示了一下員工表與部門表的關係,即員工表的(dep_id)要關聯部門表的id欄位
多對一(一個表多條記錄的某一欄位關聯另一張表的唯一一個欄位):員工有部門,部門又有好多資訊,所以
分開建了一張部門表,部門表的id 和員工表裡面
的dep_id相關聯。(dep_id要關聯部門表的id欄位
(注意:1.先建被關聯的表,
2.被關聯的欄位必須唯一
3.先給被關聯的表插入記錄
)
先建張部門表(被關聯表)
create table dep(
id int not null unique,
#id int primary key auto_increment,
name varchar(50),
comment varchar(100)
);
再建張員工表(關聯表)
create table emp_info(
id int primary key auto_increment,
name varchar(20), dep_id int, constraint FK_depid_id foreign key(dep_id) references dep(id) #references :關聯 on delete cascade #關聯的表刪了,被關聯的表也刪了 on update cascade #關聯的表修改了,被關聯的表也修改了 ); #先給被關聯的表初始化記錄 insert into dep values (1,'歐德博愛技術有限事業部','說的好...'), (2,'艾利克斯人力資源部','招不到人'), (3,'銷售部','賣不出東西'); insert into emp_info values (1,'egon',1), (2,'alex1',2), (3,'alex2',2), (4,'alex3',2), (5,'李坦克',3), (6,'劉飛機',3), (7,'張火箭',3), (8,'林子彈',3), (9,'加特林',3); #修改 update dep set id =301 where id = 2; select * from dep; delect * from em_info; 如果部門解散了,員工也就走吧,就是部門表沒了, 員工表也就沒有了。
執行結果如下圖:
檢視建立的表
修改id=301
檢視被關聯表和關聯表
一、介紹
約束條件與資料型別的寬度一樣,都是可選引數
作用:用於保證資料的完整性和一致性
主要分為:
PRIMARY KEY (PK) 標識該欄位為該表的主鍵,可以唯一的標識記錄
FOREIGN KEY (FK) 標識該欄位為該表的外來鍵
NOT NULL 標識該欄位不能為空
UNIQUE KEY (UK) 標識該欄位的值是唯一的
AUTO_INCREMENT 標識該欄位的值自動增長(整數型別,而且為主鍵)
DEFAULT 為該欄位設定預設值
UNSIGNED 無符號
ZEROFILL 使用0填充
說明:
1. 是否允許為空,預設NULL,可設定NOT NULL,欄位不允許為空,必須賦值
2. 欄位是否有預設值,預設的預設值是NULL,如果插入記錄時不給欄位賦值,此欄位使用預設值
sex enum('male','female') not null default 'male'
age int unsigned NOT NULL default 20 必須為正值(無符號) 不允許為空 預設是20
3. 是否是key
主鍵 primary key
外來鍵 foreign key
索引 (index,unique...)
二、not null 和default
是否可空,null表示空,非字串
not null - 不可空
null - 可空
default預設值,建立列時可以指定預設值,當插入資料時如果未主動設定,則自動新增預設值
create table tb1(
id int not null defalut 2 ,
num int not null
)
三、unique約束(唯一性約束)
單列唯一
-----1.單列唯一---------
create table t2(
id int not null unique,
name char(10)
);
insert into t2 values(1,'egon');
insert into t2 values(1,'alex');
#上面建立表的時候把id設定了唯一約束。那麼在插入id=1,就會出錯了
多列唯一
-----2.多列唯一---------
#255.255.255.255
create table server(
id int primary key auto_increment,
name char(10),
host char(15), #主機ip
port int, #埠
constraint host_port unique(host,port) #constraint host_port這個只是用來設定唯一約束的名字的,也可以不設定預設就有了
);
insert into server(name,host,port) values('ftp','192.168.20.11',8080);
insert into server(name,host,port) values('https','192.168.20.11',8081); #ip和埠合起來唯一
select * from server;
四、primary key (主鍵約束)
primary key欄位的值不為空且唯一
一個表中可以:
單列做主鍵
多列做主鍵(複合主鍵)
但一個表內只能有一個主鍵primary key
1 ============單列做主鍵===============
2 #方法一:not null+unique
3 create table department1(
4 id int not null unique, #主鍵
5 name varchar(20) not null unique,
6 comment varchar(100)
7 );
8
9 mysql> desc department1;
10 +---------+--------------+------+-----+---------+-------+
11 | Field | Type | Null | Key | Default | Extra |
12 +---------+--------------+------+-----+---------+-------+
13 | id | int(11) | NO | PRI | NULL | |
14 | name | varchar(20) | NO | UNI | NULL | |
15 | comment | varchar(100) | YES | | NULL | |
16 +---------+--------------+------+-----+---------+-------+
17 rows in set (0.01 sec) 18 19 #方法二:在某一個欄位後用primary key 20 create table department2( 21 id int primary key, #主鍵 22 name varchar(20), 23 comment varchar(100) 24 ); 25 26 mysql> desc department2; 27 +---------+--------------+------+-----+---------+-------+ 28 | Field | Type | Null | Key | Default | Extra | 29 +---------+--------------+------+-----+---------+-------+ 30 | id | int(11) | NO | PRI | NULL | | 31 | name | varchar(20) | YES | | NULL | | 32 | comment | varchar(100) | YES | | NULL | | 33 +---------+--------------+------+-----+---------+-------+ 34 rows in set (0.00 sec) 35 36 #方法三:在所有欄位後單獨定義primary key 37 create table department3( 38 id int, 39 name varchar(20), 40 comment varchar(100), 41 constraint pk_name primary key(id); #建立主鍵併為其命名pk_name 42 43 mysql> desc department3; 44 +---------+--------------+------+-----+---------+-------+ 45 | Field | Type | Null | Key | Default | Extra | 46 +---------+--------------+------+-----+---------+-------+ 47 | id | int(11) | NO | PRI | NULL | | 48 | name | varchar(20) | YES | | NULL | | 49 | comment | varchar(100) | YES | | NULL | | 50 +---------+--------------+------+-----+---------+-------+ 51 rows in set (0.01 sec) 52 53 單列主鍵
1 ==================多列做主鍵================
2 create table service(
3 ip varchar(15),
4 port char(5),
5 service_name varchar(10) not null,
6 primary key(ip,port)
7 ); 8 9 10 mysql> desc service; 11 +--------------+-------------+------+-----+---------+-------+ 12 | Field | Type | Null | Key | Default | Extra | 13 +--------------+-------------+------+-----+---------+-------+ 14 | ip | varchar(15) | NO | PRI | NULL | | 15 | port | char(5) | NO | PRI | NULL | | 16 | service_name | varchar(10) | NO | | NULL | | 17 +--------------+-------------+------+-----+---------+-------+ 18 rows in set (0.00 sec) 19 20 mysql> insert into service values 21 -> ('172.16.45.10','3306','mysqld'), 22 -> ('172.16.45.11','3306','mariadb') 23 -> ; 24 Query OK, 2 rows affected (0.00 sec) 25 Records: 2 Duplicates: 0 Warnings: 0 26 27 mysql> insert into service values ('172.16.45.10','3306','nginx'); 28 ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306' for key 'PRIMARY'
五、auto_increment (自增約束)
步長increment與起始偏移量offset:auto_increment_increment,auto_increment_offset
3.--------偏移量:auto_increment_offset---------
==============沒有設定偏移量的時候
create table dep(
id int primary key auto_increment,
name char(10)
);
insert into dep(name) values('IT'),('HR'),('EFO');
select * from dep;
================設定自增的時候以10開頭
create table dep1(
id int primary key auto_increment,
name char(10) )auto_increment = 10; insert into dep1(name) values('IT'),('HR'),('EFO'); select * from dep1; ===============auto_increment_increment:自增步長 create table dep3( id int primary key auto_increment, name char(10) ); 會話:通過客戶端連到服務端(一次連結稱為一次會話) set session auto_increment_increment = 2; #會話級,只對當前會話有效 set global auto_increment_increment=2; #全域性,對所有的會話都有效 insert into dep3(name) values('IT'),('HR'),('SALE'),('Boss'); -----------檢視變數---------- show variables like '%auto_in%';#檢視變數。只要包含auto_in就都查出來了 =========auto_increment_offset:偏移量+auto_increment_increment:步長=========== 注意:如果auto_increment_offset的值大於auto_increment_increment的值, 則auto_increment_offset的值會被忽略 set session auto_increment_offset=2; set session auto_increment_increment=3; show variables like '%auto_in%'; create table dep4( id int primary key auto_increment, name char(10) ); insert into dep4(name) values('IT'),('HR'),('SALE'),('Boss');
六、foreign key (外來鍵約束)
員工資訊表有三個欄位:工號 姓名 部門
公司有3個部門,但是有1個億的員工,那意味著部門這個欄位需要重複儲存,部門名字越長,越浪費
解決方法:
我們完全可以定義一個部門表
然後讓員工資訊表關聯該表,如何關聯,即foreign key
如下圖簡單的表示了一下員工表與部門表的關係,即員工表的(dep_id)要關聯部門表的id欄位
多對一(一個表多條記錄的某一欄位關聯另一張表的唯一一個欄位):員工有部門,部門又有好多資訊,所以
分開建了一張部門表,部門表的id 和員工表裡面
的dep_id相關聯。(dep_id要關聯部門表的id欄位
(注意:1.先建被關聯的表,
2.被關聯的欄位必須唯一
3.先給被關聯的表插入記錄
)
先建張部門表(被關聯表)
create table dep(
id int not null unique,
#id int primary key auto_increment,
name varchar(50),
comment varchar(100)
);
再建張員工表(關聯表)
create table emp_info(
id int primary key auto_increment,
name varchar(20), dep_id int, constraint FK_depid_id foreign key(dep_id) references dep(id) #references :關聯 on delete cascade #關聯的表刪了,被關聯的表也刪了 on update cascade #關聯的表修改了,被關聯的表也修改了 ); #先給被關聯的表初始化記錄 insert into dep values (1,'歐德博愛技術有限事業部','說的好...'), (2,'艾利克斯人力資源部','招不到人'), (3,'銷售部','賣不出東西'); insert into emp_info values (1,'egon',1), (2,'alex1',2), (3,'alex2',2), (4,'alex3',2), (5,'李坦克',3), (6,'劉飛機',3), (7,'張火箭',3), (8,'林子彈',3), (9,'加特林',3); #修改 update dep set id =301 where id = 2; select * from dep; delect * from em_info; 如果部門解散了,員工也就走吧,就是部門表沒了, 員工表也就沒有了。
執行結果如下圖:
檢視建立的表
修改id=301
檢視被關聯表和關聯表