1. 程式人生 > 實用技巧 >MySQL資料庫建立原則

MySQL資料庫建立原則

建資料庫原則

通常情況下,一個專案/應用建一個數據庫

多表之間的建表原則

  1. 一對多 : 商品和分類
    建表原則: 在多的一方新增一個外來鍵,指向一的一方的主鍵 ​
  2. 多對多: 老師和學生, 學生和課程
    建表原則: 建立一張中間表,將多對多的關係,拆分成一對多的關係,中間表至少要有兩個外來鍵,分別指向原來的那兩張表。

  1. 一對一: 班級和班長, 公民和身份證, 國家和國旗
    建表原則: 將一對一的情況,當作是一對多情況處理,在任意一張表新增一個外來鍵,並且這個外來鍵要唯一,指向另外一張表

一對一在資料庫中並沒有任何意義,因為可以直接將兩張表合併成一張表。但實際中也有使用,那就是拆表操作。
建表原則: 將兩張表的主鍵建立起連線,讓兩張表裡面主鍵相等

例如一個相親網站的個人資訊包括: 姓名,性別,年齡,身高,體重,三圍,興趣愛好,年收入, 特長,學歷, 職業, 擇偶目標,要求 等

將個人資訊分為常用資訊和不常用資訊,減少表的臃腫。

案例分析

  • 使用者表 (使用者的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