上節回顧: 1.建表語法: 註意點: 2.數據類型: 今日內容 1.表之間的關係 多對一,多對多,一對一 2.複製表 分表: 為什麼要分表? 一個表中 要存儲個人信息又要存儲部門信息 會導致大量的數據冗餘 所有數據存放在同一個表中 將導致以下幾個問題 1.浪費空間 不致命 2.結構混亂 3.修改數據 ...
上節回顧:
1.建表語法:
註意點:
2.數據類型:
今日內容
1.表之間的關係
多對一,多對多,一對一
2.複製表
分表:
為什麼要分表?
一個表中 要存儲個人信息又要存儲部門信息 會導致大量的數據冗餘
所有數據存放在同一個表中 將導致以下幾個問題
1.浪費空間 不致命
2.結構混亂
3.修改數據時 如果有一百個員工 那就要該一百次 擴展性極差
通過分表來解決
分表又造成新的問題 如何再將數據對應起來?
為什麼需要對應起來是因為兩張表的數據具備這某種關係
到底是什麼關係呢?
多對一的關係
分析關聯關係
如何確定表之間的關係 需要從實際需求中分析
第一步:
從員工的角度來考慮
多個員工是不是可以屬於同一個部門?
員工的多條記錄是否對應部門的一條記錄?
如果是 則可以確定 員工與部門是多對一
第二步:
從部門的角度來考慮
多個部門是不是可以有同一個員工?
員工部門多條記錄是否對應員工的一條記錄?
都不是 而是一個部門對應多個員工
也就是 部門與員工之間是一對多
最終我們發現 多個員工對應一個部門 一個部門對應多個員工
稱之為單向多對一
如何在資料庫中表示這種關係?
我們可以員工表中保存部門表的編號
外鍵約束
問題:此時 我們的表之間存在關聯但是是邏輯上的關聯 並沒有物理上的關聯
換句話說 員工中可以插入不存在的部門編號
如何使其具備物理關聯(硬性的關聯)?
方案:
使用外鍵 foreign key
語法:
#創建表時:
create table dept(id,xxxxx);
create table emp(id,xxxxx,dept_id,foreign key(dept_id) references dept(id));
#後期修改:
alter table student add foreign key (id) references customer(id);
主從表關係
註意要建立外鍵關聯,必須先創建主表
先有部門 後又員工 員工屬於部門 部門擁有員工 所以 主表是部門 從表是員工
約束作用:
此時我們在執行添加 更新 刪除時都會受到外鍵的約束
比如
1.員工表中添加一個不存在的部門id
2.修改某個部門的id
3.刪除某個部門的數據
以上三種操作都會報錯
1.必須已經存在的部門id才能出現在員工表中
2.無法修改 除非把員工全刪掉
3.需要先刪除員工 才能刪除部門
處理起來都非常麻煩
能不能讓主表和從表之間的更刪除同步進行?
如果你是mysql開發者 你應不應該提供這樣的功能?
必須的 這就是級聯操作
級聯操作
有兩種
1.級聯更新
指的是主表更新時 從表同步更新
2.級聯刪除
指的是主表刪除時 從表同步刪除
語法:
create table emp(id,xxxxx,dept_id)foreign key(dept_id) references dept(id) on update cascade on delete cascade;
驗證級聯操作
多對多
實例分析 什麼情況下會出現多對多的關係
學生表和老師表
多對多的關係本質上是什麼?
是雙向的多對一
如何在資料庫中表示這種關係?
使用外鍵是不行的,需要創建第三張表專門用於存儲關係
這個第三張表 如何體現關係?
在其中存儲學生和老師的id即可 並且將它們作為外鍵關聯到學生和老師表
create table t_s_relation(id int primary key auto_increment,t_id int,s_id int,foreign key(t_id) references teacher(t_id),foreign key(s_id) references stu(s_id));
為了去除重覆的關係數據 可以給關係表添加主鍵約束 聯合兩個外鍵
一對一
實例分析:
客戶表 與 學生表
一個客戶對應一個學生 或沒有成為學生
一個學生 必然只對應一個客戶
如何表示這種對應關係 ?
使用外鍵
那麼外鍵應該加到哪張表中呢?
因為是先有客戶才有學生 所以 客戶是主表 學生是從表 應該加在學生表中
我們已經知道一個學生只對應一個客戶 ,但是有可能你寫的時候寫錯了,寫了一個重覆的客戶id
此時將會造成數據錯亂 如何解決呢?
給外鍵欄位再加上 唯一性約束
三.複製表
create table table_copy select *from t1;
複製數據和表結構,但不會複製key
只想要copy表結構怎麼弄?
create table table_copy select *from t1 where 0 = 1;
給一個不成立的條件這樣的話就查不到任何數據 ,只能複製表結構
蠕蟲複製
insert into tablename(name) select name from tablename;