MySQL資料庫建立原則
建資料庫原則
通常情況下,一個專案/應用建一個數據庫
多表之間的建表原則
- 一對多 : 商品和分類
建表原則: 在多的一方新增一個外來鍵,指向一的一方的主鍵 - 多對多: 老師和學生, 學生和課程
建表原則: 建立一張中間表,將多對多的關係,拆分成一對多的關係,中間表至少要有兩個外來鍵,分別指向原來的那兩張表。
- 一對一: 班級和班長, 公民和身份證, 國家和國旗
建表原則: 將一對一的情況,當作是一對多情況處理,在任意一張表新增一個外來鍵,並且這個外來鍵要唯一,指向另外一張表
一對一在資料庫中並沒有任何意義,因為可以直接將兩張表合併成一張表。但實際中也有使用,那就是拆表操作。
建表原則: 將兩張表的主鍵建立起連線,讓兩張表裡面主鍵相等
例如一個相親網站的個人資訊包括: 姓名,性別,年齡,身高,體重,三圍,興趣愛好,年收入, 特長,學歷, 職業, 擇偶目標,要求 等
將個人資訊分為常用資訊和不常用資訊,減少表的臃腫。
案例分析
-
使用者表 (使用者的ID,使用者名稱,密碼,手機)
create table user( uid int primary key auto_increment, username varchar(31), password varchar(31), phone varchar(11) ); insert into user values(1,'zhangsan','123','13811118888');
-
訂單表 (訂單編號,總價,訂單時間 ,地址,外來鍵使用者的ID)
create table orders( oid int primary key auto_increment, sum int not null, otime timestamp,//時間戳 address varchar(100), uno int, foreign key(uno) references user(uid) ); insert into orders values(1,200,null,'黑馬前臺旁邊小黑屋',1); insert into orders values(2,250,null,'黑馬後臺旁邊1702',1);
-
商品表 (商品ID, 商品名稱,商品價格,外來鍵cno)
create table product( pid int primary key auto_increment, pname varchar(10), price double, cno int, foreign key(cno) references category(cid) ); insert into product values(null,'小米mix4',998,1); insert into product values(null,'錘子',2888,1); insert into product values(null,'阿迪王',99,2); insert into product values(null,'老村長',88,3); insert into product values(null,'勁酒',35,3); insert into product values(null,'小熊餅乾',1,4); insert into product values(null,'衛龍辣條',1,5); insert into product values(null,'旺旺大餅',1,5);
-
訂單項: 中間表(訂單ID,商品ID,商品數量,訂單項總價)
create table orderitem( ono int, pno int, foreign key(ono) references orders(oid), foreign key(pno) references product(pid), ocount int, subsum double ); --給1號訂單新增商品 200塊錢的商品 insert into orderitem values(1,7,100,100); insert into orderitem values(1,8,101,100); --給2號訂單新增商品 250塊錢的商品 () insert into orderitem values(2,5,1,35); insert into orderitem values(2,3,3,99);
-
商品分類表(分類ID,分類名稱,分類描述)
create table category( cid int primary key auto_increment, cname varchar(15), cdesc varchar(100) ); insert into category values(null,'手機數碼','電子產品,黑馬生產'); insert into category values(null,'鞋靴箱包','江南皮鞋廠傾情打造'); insert into category values(null,'香菸酒水','黃鶴樓,茅臺,二鍋頭'); insert into category values(null,'酸奶餅乾','娃哈哈,蒙牛酸酸乳'); insert into category values(null,'饞嘴零食','瓜子花生,八寶粥,辣條');
外來鍵的使用
在JAVA開發中到底要不要使用外來鍵呢?在阿里的JAVA規範中也有下面這一條
【強制】不得使用外來鍵與級聯,一切外來鍵概念必須在應用層解決。
但是為什麼呢?
很多人會說:“每次做DELETE 或者UPDATE都必須考慮外來鍵約束,會導致開發的時候很痛苦,測試資料極為不方便。”
- 外來鍵的優點
一、資料一致性
由資料庫自身保證資料一致性、完整性會更可靠,程式很難100%保證資料的一致性、完整性
二、ER圖可靠性
有主外來鍵的資料庫設計可以增加ER圖的可讀性
- 外來鍵的缺點
一、級聯問題
阿里巴巴的開發手冊中,就曾指出強制要求不允許使用外來鍵,一切外來鍵概念必須在應用層解決。 因為每次級聯delete或update的時候,都要級聯操作相關的外來鍵表,不論有沒有這個必要,由其在高併發的場景下,這會導致效能瓶頸
二、增加資料庫壓力
外來鍵等於把資料的一致性事務實現,全部交給資料庫伺服器完成,並且有了外來鍵,當做一些涉及外來鍵欄位的增,刪,更新操作之後,需要觸發相關操作去檢查,而不得不消耗資源
三、死鎖問題
若是高併發大流量事務場景,使用外來鍵還可能容易造成死鎖
四、開發不方便
有外來鍵時,無論開發還是維護,需要手工維護資料時,都不太方便,要考慮級聯因素
- 總結
一、如是單機且低併發,也不需要效能調優,再或者不能用程式保證資料的一致性,完整性,可以使用外來鍵。
二、如果為了高併發,分散式,使系統性能更優,以及更好維護,則一定不能使用外來鍵
https://blog.csdn.net/qq_22136439/article/details/103714369
https://zhuanlan.zhihu.com/p/62020571