1. 程式人生 > 其它 >05--mysql約束條件 ; 表之間的關係 ; 修改表、複製表

05--mysql約束條件 ; 表之間的關係 ; 修改表、複製表

目錄

一、約束條件

約束條件與資料型別的寬度一樣,都是可選引數

作用:用於保證資料的完整性和一致性
主要分為:

not null與defaultdefault預設值

是否可空,null表示空,非字串
not null ->不可空
null -> 可空

預設值,建立列時可以指定預設值,當插入資料時如果未主動設定,則自動新增預設值
create table t1(id int,name char(16));
insert t1(name id) values('egon',1);

create table t2(id int not null,name char(16),gender enum('male','female','others')default 'male');

unique唯一

# 單列唯一
create table t3(id int unique,name char(16));
insert t3 values(1,'egon'),(1,'jason');
insert t3 values(1,'egon'),(2,'jason');

# 聯合唯一
ip和port 單個都可以重複,但是載入一起必須是唯一的
create table t4(id int,ip char(16),port int,unique(ip,port));
insert t4 values(1,'127.0.0.1','8080');
insert t4 values(2,'127.0.0.1','8081');
insert t4 values(3,'127.0.0.2','8080');
insert t4 values(4,'127.0.0.1','8080'); #報錯

primary key主鍵

1,單單從約束效果上來看primary key 等價於 not null + unique非空且唯一!!!
create table t5(id int primary key);
insert t5 values(null); # 報錯
insert t5 values(1),(1); #報錯
insert t5 values(1),(2); 
2,它除了有約束效果之外,它還是innodb儲存引擎組織資料的依據
innodb儲存引擎在建立表的時候必須要有primary key
因為它類似於書的目錄,能夠幫助提示查詢效率並且也是建表的依據
# 1,一張表中有且只有一個主鍵,如果你沒有設定主鍵,那麼他會從上往下搜尋直到遇到一個非空且唯一的欄位將它自動升級為主鍵
create table t6(id int,name char(16),age int not all unique,addr char(32) not null unique);
# 2,如果表中沒有主鍵也沒有其他任何的非空且唯一欄位,那麼innodb會採用自己內部提供的一個隱藏欄位作為主鍵,隱藏意味著你無法使用它,就無法提示查詢速度
# 3,一張表中通常都應該有一個主鍵欄位,並且通常將id/uid/sid欄位作為主鍵
#單個欄位主鍵
create table t5(id int primary key,name char(16));
# 聯合主鍵(瞭解)
create table t4(id int,ip char(16),port int,primary key(ip,port));
···也就意味著以後我們在建立表的時候id欄位一定要加primary key

auto_increment自增

當編號特別多的時候 人為的去維護太麻煩
create table t8(id int primary key auto_increment,name char(16));
insert t8(name) values('egon'),('lili'),('jason');
# 注意auto_increment通常加在key主鍵上 不能給普通欄位加

結論

以後在建立表的id(資料的唯一標識id,uid,sid)欄位的時候要寫
id int primary key auto_increment

補充:

delete from 在刪除表中資料的時候,主鍵的自增不會停止
truncate t1 清空表資料並且重置主鍵

二、表與表之間建立關係

定義一張員工表,表中有很多欄位
id name gender dep_name dep_desc
# 1 該表的組織結構不是很清晰(可忽視)
# 2 浪費硬碟空間(可忽視)
# 3 資料的擴充套件性極差(無法忽視)
#    如何優化?(類似於將所有的程式碼寫在了一個py檔案中)
拆分表

外來鍵

外來鍵就是用來幫助我們建立表與表之間關係的
foregin key

1.表與表的關係

一對多

判斷表與表之間關係的時候,前期不熟悉的情況下,一定要換位思考,分別站在2張表的角度考慮
員工表與部門表為例
先站在員工表,思考一個員工能否對應多個部門(一條員工資料能否對應多條部門資料) 不能!
再站在部門表,思考一個部門能否對應多個員工(一個部門資料能否對應多條員工資料) 能!
得出結論:員工表與部門表是單向的一對多,所以關係就是一對多(不能說多對一,也沒有多對一)
1,一對多表關係 外來鍵欄位在多的一方
2,在建立表的時候,一定要先建被關聯表
3,在錄入資料的時候,也必須先錄入被關聯表
foregin key
# sql語句建立表關係、
#多對一例項學生與班級的關係

##建立被關聯表->班級表
create table class(
id int primary key auto_increment,
name varchar(20),
room int
);

##建立關聯表->學生表
create table student(
id int primary key auto_increment,
name varchar(16),
age int,
gender enum("male","female"),
class_id int,
foreign key(class_id) references class(id)    #設定外來鍵
on update cascade  #級聯更新
on delete cascade  #級聯刪除
);

##被關聯表錄入資料	
insert class(name,room) values
("py1期",403),
("linux1",503),
("linux2",603);

##關聯表錄入資料
insert student(name,age,gender,class_id) values
("egon",18,"male",1),
("tom",19,"male",1),
("jack",20,"male",1),
("lili",19,"female",2),
("lxx",20,"female",2);
	
	
insert student(name,age,gender,class_id) values
("kk",21,"female",4444);    # 被關聯表沒有4444的id,因此報錯
	
insert student(name,age,gender,class_id) values
("kk",21,"female",3);   # 正確的加入學生資訊

多對多

#多對多:必須建立中間表,雙向的fk
##建立多對多,作者與書本的例項

##建立書本表
create table book(
id int primary key auto_increment,
name varchar(20)
);
##建立作者表
create table author(
id int primary key auto_increment,
name varchar(16)
);
#這張表就存放作者表與書表的關係,即查詢二者的關係查這表就可以了
create table book2author(
id int primary key auto_increment,
book_id int,
author_id int,
foreign key(book_id) references book(id) on delete cascade on update cascade,
foreign key(author_id) references author(id) on delete cascade on update cascade
);

#記錄插入四個作者,id依次排開
insert into author(name) values('aaa'),('bbb'),('ccc'),('ddd');

#每個作者與自己的代表作如下
1 aaa: 
      1 九陽神功
      2 九陰真經
      3 九陰白骨爪
      4 獨孤九劍
      5 降龍十巴掌
      6 葵花寶典


2 bbb: 
      1 九陽神功
      6 葵花寶典

3 ccc:
      4 獨孤九劍
      5 降龍十巴掌
      6 葵花寶典

4 ddd:
      1 九陽神功
#!此步驟插入書本名字記錄省略
#共同表的記錄寫入:
insert into author2book(author_id,book_id) values
(1,1),
(1,2),
(1,3),
(1,4),
(1,5),
(1,6),
(2,1),
(2,6),
(3,4),
(3,5),
(3,6),
(4,1)
;
#中間那一張存放關係的表,對外關聯的欄位可以聯合唯一

一對一

# 如果一個表的欄位特別多,每次查詢又不是所有的欄位都能用到,將表一分為二
# 一對一 外來鍵欄位建在任意一方都可以,但是推薦建在查詢頻率比較高的表中
#例項
兩張表:學生表和客戶表
一對一:一個學生是一個客戶,一個客戶有可能變成一個學生,即一對一的關係
關聯方式:foreign key+unique
#建立客戶表
create table customer(
id int primary key auto_increment,
name varchar(20),
tel int
);
#建立學生表
create table student(
id int primary key auto_increment,
class varchar(10),
customer_id int unique,
foreign key(customer_id) references customer(id) on update cascade on delete cascade
);
	

2.修改表

mysql對大小寫是不敏感的
1,修改表名
	alter table 表名 rename 新表名;
	
2,增加欄位
	alter table 表名 add 欄位名 欄位型別(寬度) 約束條件;
	alter table 表名 add 欄位名 欄位型別(寬度) 約束條件 first; # 欄位在表前
	alter table 表名 add 欄位名 欄位型別(寬度) 約束條件 after; # 欄位在表尾
例: alter table t1 add name varchar(20) not null,add age int not nll;
	alter table t1 add haha varchar(9) after id; #把haha欄位加在id欄位後面
	
3,刪除欄位
	alter table 表名 drop 欄位名;
	
4,修改欄位
	alter table 表名 modify 欄位名 欄位型別(寬度) 約束條件;
	alter table 表名 change 舊欄位名 新欄位名 欄位型別(寬度)約束條件;
例: alter table t1 change name new_name varchar(20) not null;

3.複製表

我們sql語句查詢的結果其實也是一張虛擬表
create table 表名 select * from 舊錶; # 其不能複製主鍵、外來鍵..
create table new_dep2 select * from dep where id>3; #可以新增條件
#例項1
只複製表結構
mysql> select * from service where 1=2;        //條件為假,查不到任何記錄
Empty set (0.00 sec)
mysql> create table new1_service select * from service where 1=2;  
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
#例項2
1.先建立庫db01,表t1
create database db01;
use db01;
create table t1(
id int primary key auto_increment,
name varchar(15),
email varchar(30),
age int,
born_year time,
reg_time datetime
);
insert test1(name,age,email,born_year,reg_time) values
("xx",18,"[email protected]",1993,now()),
("yy",28,"[email protected]",2001,now());

2.建立庫db02,表t2
create database db02;
use db02;
create table t2( 
id int primary key auto_increment,
name varchar(15),
email varchar(30),
reg_time datetime
);
#複製記錄
insert db02.test2(id,name,email,reg_time) select id,name,email,reg_time from db01.test1;

4.刪除表

drop table 表名;