數(shù)據(jù)庫(kù)篇-mysql詳解之多表關(guān)系( 二 )

一 : 外鍵

現(xiàn)在有兩個(gè)表category分類(lèi)表

| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| cid   | varchar(32)  | NO   | PRI | NULL    |       |
| cname | varchar(100) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+

product商品表

+-------------+-------------+------+-----+---------+-------+
| Field       | Type        | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| pid         | varchar(32) | NO   | PRI | NULL    |       |
| pname       | varchar(40) | YES  |     | NULL    |       |
| price       | double      | YES  |     | NULL    |       |
| category_id | varchar(32) | YES  |     | NULL    |       |
+-------------+-------------+------+-----+---------+-------+

其中在product表中的字段category_id存放的是 category表中cid(主鍵)的信息列稱(chēng)為外鍵. 此時(shí)分類(lèi)稱(chēng)為主表,'cid'稱(chēng)為主鍵,product稱(chēng)為從表,category_id稱(chēng)為外鍵,通過(guò)主表的主鍵和從表的外鍵來(lái)描述主外鍵關(guān)系,呈現(xiàn)就是一對(duì)多的關(guān)系.

外鍵的特點(diǎn) :
  • 從表外鍵的值是對(duì)主表主鍵的引用.
  • 從表外鍵類(lèi)型,必須與主表主鍵類(lèi)型一致.
聲明外鍵約束
alter table 從表 add [constraint][外鍵名稱(chēng)] foreign key (從表字段名) references 主表(主表的主鍵)

外鍵名稱(chēng) 用于刪除外鍵約束的,一般建議_fk結(jié)尾

alter table 從表 drop foregin key 外鍵名稱(chēng)

使用外鍵目的是為了保證數(shù)據(jù)的完整性,刪除的時(shí)候會(huì)有約束.

對(duì)例子進(jìn)行外鍵約束

alter table product add foreign key(category_id) references category(cid);

從表不能夠添加(更新),主表中不存在的數(shù)據(jù).
主表不能夠刪除(更新),從表中已經(jīng)使用的數(shù)據(jù).

二 : 多表之間的關(guān)系

表與表數(shù)據(jù)之間的關(guān)系.

  • 一對(duì)多關(guān)系 :

產(chǎn)品與產(chǎn)品類(lèi)別, 一個(gè)產(chǎn)品對(duì)應(yīng)一種類(lèi)別,一個(gè)產(chǎn)品類(lèi)別包含多種產(chǎn)品,舉一個(gè)例子來(lái)說(shuō), 《蟻人》只屬于漫威系列,《雷神》也只屬于漫威系列,但是漫威宇宙還包含很多很多系列電影.

  • 多對(duì)多關(guān)系 :

大學(xué)老師與學(xué)生的關(guān)系,一個(gè)學(xué)生可以從不同老師那里學(xué)習(xí)到知識(shí),相對(duì)的一個(gè)老師可以教多個(gè)學(xué)生.

多對(duì)多關(guān)系建表原則 : 需要?jiǎng)?chuàng)建第三張表,中間表中至少兩個(gè)字段,這兩個(gè)字段分別作為外鍵指向各自一方的主鍵,也就是將一個(gè)多對(duì)多拆分成兩個(gè)一對(duì)多.

  • 一對(duì)一關(guān)系:

在實(shí)際開(kāi)發(fā)中應(yīng)用不多,一對(duì)一可以用一張表完成.
外鍵唯一 : 主表的主鍵和從表的外鍵( 唯一 ),形成主外鍵關(guān)系,unique
外鍵是主鍵 : 主表的主鍵和從表的主鍵,形成主外鍵關(guān)系.

三 : 多表查詢

建立多對(duì)多,訂單表商品表

訂單表

create table orders(
    oid varchar(32) primary key,
    totalprice double
);

訂單項(xiàng)表

create table orderitem(
    oid varchar(50),
    pid varchar(50)
);

聯(lián)合主鍵

alter table orderitem add primary key(oid,pid);

訂單表和訂單項(xiàng)表主外鍵關(guān)系

alter table orderitem add constraint orderitem_orders_fk foreign key(oid) references orders(oid);

商品表和訂單項(xiàng)表的主外鍵關(guān)系

alter table orderitem add constraint orderitem_product_fk foreign key(pid) references product(pid);

多對(duì)多關(guān)系構(gòu)圖

+-------------+-------------+------+-----+---------+-------+
| Field       | Type        | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| pid         | varchar(32) | NO   | PRI | NULL    |       |
| pname       | varchar(40) | YES  |     | NULL    |       |
| price       | double      | YES  |     | NULL    |       |
| category_id | varchar(32) | YES  | MUL | NULL    |       |
+-------------+-------------+------+-----+---------+-------+

1
|
|
|

+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| oid   | varchar(50) | NO   | PRI | NULL    |       |
| pid   | varchar(50) | NO   | PRI | NULL    |       |
+-------+-------------+------+-----+---------+-------+


|
|
|
1

+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| oid        | varchar(32) | NO   | PRI | NULL    |       |
| totalprice | double      | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+

準(zhǔn)備數(shù)據(jù)

+------+-----------------+-------+-------------+
| pid  | pname           | price | category_id |
+------+-----------------+-------+-------------+
| p001 | 蘋(píng)果筆記本      | 14000 | c001        |
| p002 | 蘋(píng)果手機(jī)        |  9000 | c001        |
| p003 | 手寫(xiě)板          |  5000 | c001        |
| p004 | JACK JONES      |   800 | c002        |
| p005 | 耐克            |   600 | c002        |
| p006 | 阿迪達(dá)斯        |   440 | c002        |
| p007 | 李寧            |   200 | c002        |
| p008 | 香奈兒          |   800 | c003        |
| p009 | 蘭蔻            |  1000 | c003        |
+------+-----------------+-------+-------------+
+------+-----------+
| cid  | cname     |
+------+-----------+
| c001 | 電子      |
| c002 | 服飾      |
| c003 | 化妝品    |
+------+-----------+
  • 交叉查詢

兩表之間的乘機(jī),不常用

select * from A,B;
  • 內(nèi)連查詢

隱式內(nèi)連接

select * from A,B where 條件 ; 
mysql> select * from category,product where cid = category_id;
+------+-----------+------+-----------------+-------+-------------+
| cid  | cname     | pid  | pname           | price | category_id |
+------+-----------+------+-----------------+-------+-------------+
| c001 | 電子      | p001 | 蘋(píng)果筆記本      | 14000 | c001        |
| c001 | 電子      | p002 | 蘋(píng)果手機(jī)        |  9000 | c001        |
| c001 | 電子      | p003 | 手寫(xiě)板          |  5000 | c001        |
| c002 | 服飾      | p004 | JACK JONES      |   800 | c002        |
| c002 | 服飾      | p005 | 耐克            |   600 | c002        |
| c002 | 服飾      | p006 | 阿迪達(dá)斯        |   440 | c002        |
| c002 | 服飾      | p007 | 李寧            |   200 | c002        |
| c003 | 化妝品    | p008 | 香奈兒          |   800 | c003        |
| c003 | 化妝品    | p009 | 蘭蔻            |  1000 | c003        |
+------+-----------+------+-----------------+-------+-------------+

顯示內(nèi)連接

select * from A inner join B on 條件;
mysql> select distinct cname from category c inner join product p on c.cid = p.category_id;
+-----------+
| cname     |
+-----------+
| 電子      |
| 服飾      |
| 化妝品    |
+-----------+
  • 外連接查詢

我們往 類(lèi)別表與商品表分別添加兩條數(shù)據(jù)

 insert into category(cname,cid) values('甜品',5);
 insert into product(pid,pname,price,category_id) values('p010','甜筒',14,null);

左外連接 : left outer join

select * from A left outer join B on 條件

右外連接 : right outer join

select * from A right outer join B on 條件
mysql> select * from category c left outer join product p on c.cid = p.category_id;
+------+-----------+------+-----------------+-------+-------------+
| cid  | cname     | pid  | pname           | price | category_id |
+------+-----------+------+-----------------+-------+-------------+
| 5    | 甜品      | NULL | NULL            |  NULL | NULL        |
| c001 | 電子      | p001 | 蘋(píng)果筆記本      | 14000 | c001        |
| c001 | 電子      | p002 | 蘋(píng)果手機(jī)        |  9000 | c001        |
| c001 | 電子      | p003 | 手寫(xiě)板          |  5000 | c001        |
| c002 | 服飾      | p004 | JACK JONES      |   800 | c002        |
| c002 | 服飾      | p005 | 耐克            |   600 | c002        |
| c002 | 服飾      | p006 | 阿迪達(dá)斯        |   440 | c002        |
| c002 | 服飾      | p007 | 李寧            |   200 | c002        |
| c003 | 化妝品    | p008 | 香奈兒          |   800 | c003        |
| c003 | 化妝品    | p009 | 蘭蔻            |  1000 | c003        |
+------+-----------+------+-----------------+-------+-------------+
10 rows in set (0.00 sec)
mysql> select * from category c right outer join product p on c.cid = p.category_id;
+------+-----------+------+-----------------+-------+-------------+
| cid  | cname     | pid  | pname           | price | category_id |
+------+-----------+------+-----------------+-------+-------------+
| c001 | 電子      | p001 | 蘋(píng)果筆記本      | 14000 | c001        |
| c001 | 電子      | p002 | 蘋(píng)果手機(jī)        |  9000 | c001        |
| c001 | 電子      | p003 | 手寫(xiě)板          |  5000 | c001        |
| c002 | 服飾      | p004 | JACK JONES      |   800 | c002        |
| c002 | 服飾      | p005 | 耐克            |   600 | c002        |
| c002 | 服飾      | p006 | 阿迪達(dá)斯        |   440 | c002        |
| c002 | 服飾      | p007 | 李寧            |   200 | c002        |
| c003 | 化妝品    | p008 | 香奈兒          |   800 | c003        |
| c003 | 化妝品    | p009 | 蘭蔻            |  1000 | c003        |
| NULL | NULL      | p010 | 甜筒            |    14 | NULL        |
+------+-----------+------+-----------------+-------+-------------+

注意觀察上面左連接與右連接的查詢結(jié)果分析其聯(lián)系.
內(nèi)連接 : 查詢兩個(gè)表交集
左外連接 : 左表全部以及兩個(gè)表的交集
右外連接 : 右表全部以及兩個(gè)表的交集

四 : 子查詢

一條select語(yǔ)句結(jié)果作為另一條語(yǔ)句的一部分(查詢條件,查詢結(jié)果,表等).

mysql> select * from product where category_id = (select cid from category where cname = '電子');
+------+-----------------+-------+-------------+
| pid  | pname           | price | category_id |
+------+-----------------+-------+-------------+
| p001 | 蘋(píng)果筆記本      | 14000 | c001        |
| p002 | 蘋(píng)果手機(jī)        |  9000 | c001        |
| p003 | 手寫(xiě)板          |  5000 | c001        |
+------+-----------------+-------+-------------+
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末齿穗,一起剝皮案震驚了整個(gè)濱河市昨凡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖重罪,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異项滑,居然都是意外死亡曙旭,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)便监,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扎谎,“玉大人,你說(shuō)我怎么就攤上這事烧董』侔校” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵逊移,是天一觀的道長(zhǎng)预吆。 經(jīng)常有香客問(wèn)我,道長(zhǎng)胳泉,這世上最難降的妖魔是什么拐叉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任岩遗,我火速辦了婚禮,結(jié)果婚禮上凤瘦,老公的妹妹穿的比我還像新娘宿礁。我一直安慰自己,他們只是感情好廷粒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布窘拯。 她就那樣靜靜地躺著,像睡著了一般坝茎。 火紅的嫁衣襯著肌膚如雪涤姊。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天嗤放,我揣著相機(jī)與錄音思喊,去河邊找鬼。 笑死次酌,一個(gè)胖子當(dāng)著我的面吹牛恨课,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播岳服,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼剂公,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了吊宋?” 一聲冷哼從身側(cè)響起纲辽,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎璃搜,沒(méi)想到半個(gè)月后拖吼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡这吻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年吊档,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唾糯。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怠硼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出移怯,到底是詐尸還是另有隱情拒名,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布芋酌,位于F島的核電站,受9級(jí)特大地震影響雁佳,放射性物質(zhì)發(fā)生泄漏脐帝。R本人自食惡果不足惜同云,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堵腹。 院中可真熱鬧炸站,春花似錦、人聲如沸疚顷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)腿堤。三九已至阀坏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間笆檀,已是汗流浹背忌堂。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酗洒,地道東北人士修。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像樱衷,于是被迫代替她去往敵國(guó)和親棋嘲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容