MySQL連表操作之一對多


引入

當我們在數據庫中創建表的時候,有可能某些列中值內容量很大,而且重復。

例子:創建一個學生表,按學校年紀班級分,表的內容大致如下:

id name partment
1 xxx x學校x年級x班級
2 ooo x學校x年級x班級
3 zzz z學校x年級x班級
4 ddd y學校x年級x班級

我們看出來對應的partment對應的值很長,而且重復量很大,這樣就很不合適。

 

因此我們考慮將復雜重復的部分單獨拿出來分成2個表:

第一張表:

id caption
1 x學校x年級x班級
2 y學校x年級x班級
3 z學校x年級x班級

第二張表在之前的基礎上修改的:

id name partment
1 xxx 1
2 ooo 2
3 zzz 3
4 ddd 1

這樣看起來就很簡潔了,我們將很長的且重復的部分拿出來,然后規定編號,創建學生表的時候,學生對應的partment只需要取學校對應的id便可,這樣同時這2張表也就會關聯起來。

說明:

1、他們的關聯關系;表2中的partment和表1的id聯系再一起。

2、表一的數據會對應表2中的多條數據,這就叫一對多

問題:此時,兩張表是相對獨立的,都可以各自插入自己的數據,這樣做很合適的,並沒實質行的關聯?

因此,必須要將其限制。表二的partment數據必須是表一中有的,不然,就不讓其增加。

這里(partment)就引入了一個名詞 —- 外鍵

外鍵

說明:
1、外鍵:一個表接收另一個表的主鍵。
2、partment外鍵的是表一中的nid。
3、當我們創建了外鍵,則系統變默認會為我們添加,相應的約束,如:表二中的partment數據必須是表一中nid有的;表二和表一就關聯起來了。

Navicat創建外鍵

創建part表:

1481267881120

創建person表:

1481267949167

外鍵的創建注意點:
創建外鍵時,互相對應的表中的數據類型必須一樣

創建外鍵

1、首先在要創建外鍵的表上右鍵,選設計表。
2、進入設計表,在右邊顯示表行信息,然后點擊外鍵:

1481268565436

3、選擇字段,會出現一個選擇框,選擇你要設置外鍵的列;

1481268675355

4、選擇參考表,選擇要外鍵要關聯的表,

1481268768575

說明:
參數數據庫:因為兩個數據庫在同意目錄下,所以這里可以不用選擇;默認是同目錄下的。

5、選擇參考字段;選擇參考表中要設為外鍵的列;

1481268901706

注意:
外鍵的創建,連個表中關聯的列的數據類型必須一樣,不然不能成功。

6、保存CTRL + S

 

使用外鍵

此時part中沒有數據,如果此時你在person中添加數據,結果:

 

1481269064394

 

在part中添加數據,結果:

 

1481269148396

 

此時再在,person中添加數據:

 

1481269219718

注意:

這里不能輸入part中nid沒有的值,不然也會報錯。

1481269304129

SQL命令創建外鍵

創建part:

create table part(
	nid int not null auto_increment primary key,
	caption varchar(32) not null
)
part

創建person:

create table person(
  nid int not null auto_increment,
  name varchar(32) default null,
  email varchar(32) default null,
  part_nid int,
  primary key(nid),
  constraint fk_person_part foreign key (part_nid) references part(nid)
)
person

創建完之后外鍵對應代碼的關系:

image

分析:
1、從名字可以看出代碼對應的是什么位置的。
2、圖中名(C對應代碼中的CONSTRAINT)這行可以不用設,系統會默認幫我設置,但是最好設置,如果要刪除外鍵的時候,就可以通過這個名字進行相應的操作

代碼刪除外鍵

alter table person1 drop foreign key fk_person1_part1;

代碼增加外鍵

alter table person1 add constraint fk_p1_t1 foreign key (part1_nid) references part1(nid);

通過外鍵進行數據操作

part表:

 

1481274072447

 

person表:

1481274100625

 

需求:要找出person表中屬於x學校的人?

1、之前學的辦法:

  • 1、先去part中獲取x對應的nid
  • 2、然后再通過這個nid與parson中part_id對用的關系,查找出對應的name
select name from person where part_id in (select nid form part where caption = "x")

2、鏈表方法 left join

left join

使用連表提供的方法,left join操作代碼:

select * from person left join part on person.part_id = part.nid

結果顯示:

1481274965703

分析:
left join:相當於將part表匹配的部分直接移動到person的列后面,組合起來顯示。

既然內容都合並了,那么此時我們再加上判斷,就可以將要的數據獲取了。

代碼1:

select * from person left join part on person.part_id = part.nid where part.caption = "x"

結果:

1481275260873

說明:

之前我們用的 * 獲取的是全部的信息,如果我們獲取指定的信息,可以將其修改。

如:只獲取person的name代碼:

select person.name from person left join part on person.part_id = part.nid where part.caption = "x"

結果:

1481275364629

注意:
join連接的條件,使用 on 進行對接的,條件寫在on后面。

A left join B on a.xx = b.xx

left join的特點:
1、以A為主
2、將A中的所有數據羅列
3、B則只顯示與A相對應的數據

問題:驗證我們說的誰在前就誰為主,誰的數據就全部顯示,我們將person和part換個位置?

select * from part left join person on person.part_id = part.nid;

結果:

1481292040108

right join

在誰顯示所有數據的上來看,他和left join剛好相反,以后面的表為主,顯示其所有的數據。

 

inner join

會將沒有建立關系的數據忽略掉。不管誰在前,結果都是一樣。

select * from person inner join part on person.part_id = part.nid;

結果:

1481292750984

總結:
1、這幾個join可以寫多個的,意思就是一個表可以同時有多個外鍵。

2、當選擇的列名是所有表中唯一的話,可以不用寫前綴的表名。如:person.part_id就可以直接寫成part_id.

3、上面的part表,有個別名叫,字典表


免責聲明!

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



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