資料關聯

以飲料店的商品種類為例,假設我們現在有飲料和杯子兩種資料。

飲料:

id name
1 綠茶
2 紅茶
3 青草茶

杯子:

id size
1 500
2 600
3 700

一對一(One to One)

若飲料和杯子是一對一的關係,那麼情況就類似這樣:

  • 綠茶只用 500 cc 的杯子裝

  • 紅茶只用 600 cc 的杯子裝

  • 青草茶只用 700 cc 的杯子裝

一種飲料只有一個尺寸的杯子,而且一個尺寸的杯子也只對應到一種飲料。在這種情況下要建立關聯,有下列兩種方式,擇一即可。這兩種做法在技術上效果是一樣的,不過語意解讀上可能不太一樣。

  1. 把關聯欄位加在飲料(語意上,是飲料有杯子這個屬性)

  2. 把關聯欄位加在杯子(語意上,是杯子有飲料這個屬性)

把關聯欄位加在飲料的資料表:

id name cup_id
1 綠茶 1
2 紅茶 2
3 青草茶 3

把關聯欄位加在杯子的資料表:

id size drink_id
1 500 1
2 600 2
3 700 3

一對多(One to Many)

若飲料和杯子是一對多的關係,那麼情況就類似這樣:

  • 綠茶用 500 cc、700 cc 的杯子裝

  • 紅茶只用 600 cc 的杯子裝

一種飲料有許多尺寸的杯子,而且一個尺寸的杯子只對應到一種飲料。

或者是這樣:
  • 綠茶、紅茶、青草茶都只用 500 cc 的杯子裝

一個尺寸的杯子對應到許多種飲料,而且一種飲料只有一個尺寸的杯子。

在這種情況下要建立關聯,一般會選擇加在多的那一邊。如果加在少的那一邊,在管理資料上會比較不方便。以「一種飲料有許多尺寸的杯子」為例:

加在多的那一邊(杯子資料表)

id size drink_id
1 500 1
2 600 2
3 700 1

加在少的那一邊(飲料資料表)

id name cup_id
1 綠茶 1, 3
2 紅茶 2
3 青草茶 null

加在少的那一邊,會變成要在一個格子裡塞進多筆資料(如上),或是要新增好幾個紀錄 cup_id 的欄位(如下),這種處理方式不太理想。

id name cup_id_1 cup_id_2
1 綠茶 1 3
2 紅茶 2 null
3 青草茶 null null

多對多(Many to Many)

若飲料和杯子是多對多的關係,那麼情況就類似這樣:

  • 綠茶用 500 cc、600 cc 的杯子裝

  • 紅茶用 600 cc、700 cc 的杯子裝

  • 青草茶用 500 cc、700 cc 的杯子裝

一種飲料有許多尺寸的杯子,而且一個尺寸的杯子對應到許多種飲料。

在這種情況下要建立關聯,一般會選擇新增一張 join table,以免面臨「在一個格子裡塞進多筆資料」或「新增好幾個欄位」的資料管理困境。

join table

id drink_id cup_id
1 1 1
2 1 2
3 2 2
4 2 3
5 3 1
6 3 3

join table 中的一筆紀錄,只對應到飲料資料表中的一筆紀錄,而飲料資料表中的一筆紀錄,對應到 join table 中的多筆紀錄,所以 join table 和飲料資料表之間是一對多關係。

join table 中的一筆紀錄,只對應到杯子資料表中的一筆紀錄,而杯子資料表中的一筆紀錄,對應到 join table 中的多筆紀錄,所以 join table 和杯子資料表之間是一對多關係。

換句話說,join table 的原理,其實就是把多對多關係,拆成兩個一對多關係。

參考資料

Comments

Popular posts from this blog

shop_platform - 建立多對多關聯:Association Object

[計算機概論] SR Flip-Flop

git 指令