數據庫的約束語句和表之間的關系


約束

約束就是一種限制,規定不能做某些事情

數據庫的約束,是對數據的安全性,完整性的保證

mysql中的約束

unique

唯一性約束,表示這個字段不能出現重復的值,用於唯一標識一條記錄

比如身份證號碼,學號等

not null

非空約束,表示這個字段的值不能為空

比如賬號,密碼

null

一些數據類型默認就是可以為空的

default

默認值,用於給某一個字段設置默認值

普通約束測試

#完整的建表語句
create table table_name(字段名稱 字段類型[(寬度)約束]) charest utf8;

#學生表具備 姓名 性別 學號
create table student(
	#非空
    name char(20) not null,
    #默認值
    gender enum('g','b') default 'b',
    #唯一
    id int unique
)
#測試
insert into student values(null,null,null);#錯誤原因是 name不能為空
insert into student values('jack',null,null);#可以插入,null也是一個特殊的值,並且id的唯一約束,也可以為null
insert into student(name,id) values('jack',null);#可以插入,當沒有給gender指定參數時,將使用默認值
alter table student modify id int unique not null;#為已經存在的字段添加約束

primary key

主鍵約束,從約束角度來看就等同於,非空+唯一

主鍵與普通的約束的區別:

create table person(
	id char(19) primary key,
    name char(20)
);
insert into person values('1','rose');#ok
insert into person values('1','jack');#主鍵唯一,不能為'1',報錯
insert into person values('2','jack');#ok
insert into person values(null,'tom');#主鍵不能為空,報錯

#從約束角度來看就等同於,非空+唯一
create table person2(
	id char(19),
    name char(20)
);

#在innodb存儲引擎中,主鍵用於組織數據(樹形結構)
#也就是說對於主鍵對於innodb引擎來說是必須要的,沒有不行!
#如果沒有手動指定主鍵,mysql會自動查找一個具備非空且唯一的字段作為主鍵
#如果也沒有這樣的字段,mysql會創建一個隱藏字段,作為主鍵
#首先明確主鍵是一種索引,unique也是,索引的作用是加速查詢
#如果我們在查詢語句中沒有使用索引字段,mysql將無法為我們加速查詢,意味着如果沒有主鍵,將無法加速查詢

總的來說,主鍵具有約束的作用,還能加快查詢速度,所以在創建表的時候應該創建一個索引字段;

如果本來業務中就存在一個非空且唯一的字段,那就把它設置為主鍵,如果沒有那就自己添加一個字段專門作為主鍵,通常將主鍵設置為int類型,是為了方便保證其唯一。

案例:

create table PC(
id int primary key,
pp char(20),
model char(10),
price float
);

mysql> insert into PC values(1,"IBM","1214SB",40000);
mysql> insert into PC values(2,"DELL","1200DSB",4000);
mysql> select *from PC;
mysql> select *from PC where id = 1;
mysql> select *from PC where pp = "DELL";

為主鍵設置自動增長

當我們創建了主鍵字段時,插入數據必須保證主鍵是唯一的不能重復,這就需要我們自己管理主鍵值,這是很麻煩的,所以mysql有一個自動增長的屬性,可以添加在整形字段上,每次插入數據時,都可以自動的插入值,並且每次加1不會沖突;

create table teacher(
	id int primary key auto_increment,
    name char(10)
);
insert into teacher values(null,'jack');#對於自動增長得字段可以給null,也會自動生成值
insert into teacher(name) values('jack');#也可以跳過這個字段

create table teacher(
	id char unique auto_increment,
    name char(10)
);

自動增長可以用在具備索引,並且是數字類型的字段上,但是通常與主鍵一起使用

表之間的關系

foreign key

外鍵約束,用於指向另一個表的主鍵字段

#創建表的時候添加外鍵
create table teacher(
	id int primary key auto_increment,
    name char(20),
    gender char(1),
    dept_id int,
    foreign key(dept_id) regerences dept(id)
);
解釋:
foreign key(dept_id) references dept(id)
dept_id表示當前表的外鍵字段
dept 表示要關聯哪個表
dept(id) id表示關聯的的普通表的id字段

主表與從表
先有主表 再有從表
先有dept 再有teacher

foreign key 帶來的約束作用:

  1. 在從表中插入一條記錄,關聯了一個主表中不存在的id, 會導致插入失敗

    必須保證部門id(外鍵的值)必須是在主表中存在的

  2. 插入數據的順序

    現插入主表記錄,再插入從表記錄

  3. 從表更新外鍵時也必須保證 外鍵的值在主表中是存在的

  4. 刪除主記錄前,要保證從表中沒有外鍵關聯被刪除的id

    delete from dept where id=1;#報錯
    #必須先刪除從表,再刪除主表
    delete from teacher where dept_id=1;
    delete from dept where id=1;
    
  5. 更新主表記錄的主鍵時,要保證從表中沒有外鍵關聯被刪除的id

  6. 必須先創建主表

  7. 刪除表必須先刪除從表

強調:foreign key就是用來保證兩張表之間的關聯是正確的

練習:班級表和學員表

主表是班級

從表是學員 外鍵加給學員

create table class(
	id int primary key auto_increment,
    name char(20)
);

create table student(
	id int primary key auto_increment,
    name char(20),
    gender char(1),
    c_id int,
    foreign key(c_id) references class(id)
);

級聯操作

當我們需要刪除主表的信息時,必須先刪除從表中關聯的數據,很麻煩

級聯操作指的就是,當操作主表時,自動的操作從表

兩種級聯操作

  1. 級聯的刪除

    當刪除主表時自動刪除從表中的相關數據

  2. 級聯更新

    當主表的主鍵更新時自動更新的更新關聯的從表數據

案例:

drop table if exists class;
# 如果這表存在 才執行刪除  可以避免報錯  if exists
# if not exists  如果不存在才執行
create table class(
        id int primary key auto_increment,
        name char(20)
	);
insert into class values(null,"py9");
insert into class values(null,"py10");

#創建表的時候指定級聯操作 
drop table if exists student;
create table student(
        id int primary key auto_increment,
        name char(20),
        gender char(1),
        c_id int,
    	foreign key(c_id) references class(id)
         on update cascade
   	 	on delete cascade
	);
# 級聯操作可以單獨使用 也可以一起使用   空格隔開即可 
insert into student values(null,"jack","m",1);
insert into student values(null,"rose","m",1);
insert into student values(null,"tom","m",2);

外鍵的使用

什么時候使用外鍵:

表之間存在關聯關系:

多對一(一對多)

老師和部門的關系 
老師的角度看
	一個老師應該對應有一個部門 
	一個老師可以對應對多個部門?  不行 一個老師只能屬於一個部門 (要看具體業務要求)!
	多個老師可以對應一個部門 
	多對一
部門的角度看
	一個部門可以對應多個老師
	一個部門可以對應一個老師
	多個部門可以對應一個老師? 不行 
	一對多 
如何處理一對多(多對一)?
	在老師表中存儲 部門id
	即多的一方存儲 一的一方的id

處理方式

在一的一方即teacher表中保存相應的部門(多的一方)的編號;

案例:

#部門
create table dept(
	id int primary key auto_increment,
    name char(20),
    job char(50),
    manager char(19),
);
#老師表
create table teacher(
	id int primary key auto_increment,
    name char(20),
    gender char(1),
    dept_id int,
    foreign key(t_id) references teacher(id),
);

多對多

如何確定多對多關系

例如:老師表和學生表

老師表角度:一個老師可以對應多個學生 一對多

學生表角度:一個學生可以對應多個老師 一對多

如果雙方都是一對多的,那么兩者都是多對多關系

處理方式

建立一個中間表,用於存儲關系,至少具備兩個字段分別指向老師和學生的主鍵,兩個字段都是外鍵,如下:

create table t_s_r(
	id int primary key auto_increment,
    t_id int,
    s_id int,
    foreign key(t_id) reference teacher(id),
    foreign key(s_id) regerence student(id),
    unique key(t_id,s_id)
);

上表中id是可選的,問題是如何保證沒有重復干關系?

方式1:
給兩個字段設置為唯一+非空
#假設表已經存在了
alter table t_s_r add unique key(t_id,s_id);
#創建表時指定,多字段聯合唯一
create table t_s_r2(t_id int,s_id int,unique key(t_id,s_id));
方式2:
#推薦 將中間的關系表 兩個id 作為聯合主鍵 同時具備了 唯一且非空約束
create table t_s_r3(t_id int ,s_id int,primary key(t_id,s_id));

處理多對多關系:
1. 創建兩個主表 如學生和老師
2. 創建關系表 包含兩個字段 分別設置外鍵 指向對應的表
3. 將兩個字段 作為聯合外鍵

案例

create table student(id int primary key auto_increment,name char(19));
create table teacher(id int primary key auto_increment,name char(10));
create table t_s_r(
	t_id int ,
    s_id int ,
    foreign key(t_id) references teacher(id),
    foreign key(s_id) references student(id),
    primary key(t_id,s_id)
);
#先插入 學生表或者老師表都可以 但是關系表一定是最后添加的
insert into teacher values(null,'bgon'),(null,'nike')

insert into student values(null,'老王'),(null,'老李')

#老王被bgon教過
insert into t_s_r values(1,1)
#nike教過老李
insert into t_s_r values(2,2)
#nike教過老王
insert into t_s_r values(2,1)


已知老師名為egon 請找出他教過的學生
1. 通過名字獲取 bgon的id
2. 拿着id取關系表中拿到一堆學生的id
3. 通過學生的id取出學生的信息
select id from teacher where name='bgon';
select s_id from t_s_r where t_id=1;
selsct * from student where id=1;

#子查詢方式 把一條語句的結果作為另一條語句的條件
select * from student where id=(select s_id from t_s_r where t_id=(select id from teacher where name='bgon'));


已知學生名為老李 請查詢出 哪些老師教過他
1.通過名字獲取老李id
select id from student where name='老李';
2.拿着id去關系表,找到老師id
select t_id from t_s_r where t_id=2;
3.通過老師的id取出老師的信息
select * from teacher where id=x;

#子查詢方式
select name form teacher where id=(select t_id form t_s_r where s_id=(select id from student where name='老李'))

一對一關系

如一個身份證對應一個公民

粘在兩邊都是一對一的關系

處理方式:

確定先后順序,將先存在的數據作為主表,后存在的作為從表

使兩個表的id保持一一對應

​ 方法一:從表的id 即是主表又是外鍵

​ 方法二:從表的id設置為外鍵,並保證唯一

案例:

#人員表
create table person(
	id int primary key auto_increment,
    name char(10),
    age int
);
#詳情表
create table person_info(
	id int primary key,
    height float,
    weight float,
    foreign key(id) references person(id)
);
#在這樣的關系中 必須先插入主表即person 拿到一個id 在添加詳情表的數據
#將一條完整數據拆分到不同表中,可以提高查詢效率,上述方法稱之為垂直分表


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM