iT邦幫忙

0

Database design 資料庫設計 intermediary table 的必要性問題

Rick 2021-11-18 15:05:241406 瀏覽
  • 分享至 

  • xImage

各位前輩大家好, 我目前在學習 數據庫設計, 關於兩表的聯結1對1,1對多,多對多 的關係有一些淺淺的了解, 但對於"中介表" 就時常不知道該不該使用,

目前我在練習設計一個的ER圖 ,發票上會有折扣的欄位,此欄位中的數據生成方式希望是經由所有商品的價錢加總後x折扣%數, 不是每項商品都先經過折扣後才顯示在發票上, 我查了許多別人分享的經驗, 在設計database 關於折扣時 都是把折扣表 和商品表 做聯結, 但我的構想是因為在聖誕節,母親節,父親節 所以商品加總後才給折扣, 所以想把 促銷表 和發票表 做聯結.

我設計了 發票表 跟 促銷表, 促銷表中 有一欄為 折扣%數, 若用促銷ID當作外鍵 用到發票表之中, 這樣我需要在 發票表中建立一個欄位為 促銷代碼, 這樣同時會有"折扣欄"和"促銷代碼欄", 總覺得這樣有點多餘或是雜亂@@?
所以我在想是不是需要一個 中介表 來放在 促銷 跟 發票中間, 如下圖所示
https://ithelp.ithome.com.tw/upload/images/20211118/20135894kARibK8ofY.png//)
還是這樣其實也是多此一舉?
可以直接在INVOICE table中 Discount欄 改為PromotionCode (FK)就可以呢?

謝謝您耐心看完我的發問, 第一次發問加上不熟悉數據庫設計,有點不知道如何清楚表達出我的問題所在,如有需要進一步說明清楚的地方 請告知我,還請多多包涵 謝謝!!

*我有時候在構想時都會想依照真實發票上面會顯示出的東西來設計欄位, 但又會想到主要是要依照在打QUERY時而設計, 然後就在這之中打結,不知道業界上大家主流都怎麼做 關於設計折扣的部分,謝謝

看更多先前的討論...收起先前的討論...
froce iT邦大師 1 級 ‧ 2021-11-18 15:24:46 檢舉
整單折扣你的1張發票只會對到1種折扣,應該是1(發票)對多(折扣選擇)。
理論上不需要用到中介表。
或許在發票中加一個外鍵去記載折扣的ID就行了。

不過實務上還是要看你系統所需的彈性有多大,這沒有正確答案。
fillano iT邦超人 1 級 ‧ 2021-11-18 15:28:29 檢舉
n:m才需要中介表,1:n不需要。如果是要儲存當時的promotion狀態,那要儲存的東西可以放在發票表,但還是留著fk。(因為怕promotion有些條件被改,然後東西對不起來)
froce iT邦大師 1 級 ‧ 2021-11-18 15:36:00 檢舉
>(因為怕promotion有些條件被改,然後東西對不起來)

對喔,忘記promotion會改變。
不過這種涉及金額的通常我會直接複製當時promotion的狀態過去。
Rick iT邦新手 5 級 ‧ 2021-11-18 15:40:40 檢舉
Hi @Force , 謝謝您的分享解說, 我原先構想是想要一張訂單只能有一種扣優惠, 但如同您說的 的確是會有可能一個時期有多中優惠可以供顧客選擇要使用哪種優惠, 但發票上最終還是只會出現一種優惠,
因次需要將關係從1:1改成 "發票1: n 促銷表" 嗎 ?
Rick iT邦新手 5 級 ‧ 2021-11-18 15:43:06 檢舉
Hi @Filano , 感謝您的回答. 您的意思是 我在INVOICE tabl中 加上PromotionCode (FK) 即可以嗎?
froce iT邦大師 1 級 ‧ 2021-11-18 15:47:24 檢舉
發票最終只有一種優惠的話那就是1對1了。
折扣可疊加才會是1對N。
你的promotion那張表只是選項而已,並沒有直接實際關連到發票,必須等顧客送出訂單才能確認關聯性,而其中的關聯是 一張發票:一種實際折扣/多種實際折扣,這就要看你的實際狀況才能決定了。
froce iT邦大師 1 級 ‧ 2021-11-18 15:52:10 檢舉
講白了就是我會設計三張表
1. 促銷選項
2. 訂單
3. 實際折扣

1是沒關聯的,只是提供資訊,等到實際要開訂單的時候,複製一份資料到3(為啥要用複製的,因為有時候促銷選項會變,所以建議保留促銷當時的狀態),並且設定外鍵給2,一對一或一對多就看你的邏輯。
Rick iT邦新手 5 級 ‧ 2021-11-19 03:15:48 檢舉
Hi Force,
我明白了, 非常感謝您的解說 : )
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
海綿寶寶
iT邦大神 1 級 ‧ 2021-11-19 09:22:01

單純就「你的設計」調整如下:

https://ithelp.ithome.com.tw/upload/images/20211119/20001787dOwAzrEQYA.png

依此設計
回答問題如下:

在 發票表中建立一個欄位為 促銷代碼, 這樣同時會有"折扣欄"和"促銷代碼欄

不用

可以直接在INVOICE table中 Discount欄 改為PromotionCode (FK)就可以呢?

這名字有點令人混淆(是Column還是Key?),如果 Discount 指的是
DiscountPercentage:在每次查詢發票時需不需要也知道這資訊,要就保留
PromotionCode:不用

業界上大家主流都怎麼做 關於設計折扣的部分

各行各業有自己的遊戲規則
就像你自己說的「折扣是跟著商品而有不同比例」
除了電商平台/職棒總冠軍的便利店
印象中沒看過你這種「全館xx折」的打折法

看更多先前的回應...收起先前的回應...
Rick iT邦新手 5 級 ‧ 2021-11-20 06:53:23 檢舉

哈囉 @海綿寶寶 謝謝您的回答 :)
關於 在INVOICE table 裡的Discount, 我當時發問時 是希望可以在每次查詢可以看到當時折扣了多少金額就好,而不是PromotionCode 或是 DiscountPercentage,
但在發問後看到@FORCE 的解惑幫助後, 我發現應該也要可以查詢到為什麼會有這樣的折扣金額 是因為用到了哪一個PromotionCodea, 這樣promotion talbe 才有辦法跟INVOICE table做到連結。
(所以我改成以下這樣,沒加上ORDER table 是因為我 練習的背景設定是 只給客服部門使用查詢過往發票紀錄跟過網友的折扣活動)

https://ithelp.ithome.com.tw/upload/images/20211120/201358942JueRWclw2.png

依我的理解,要知道多少金額的話,需要知道當時用了什麼PromotionCode 因而知道多少DiscountPercentage然後在乘上總價,才會得到總共的折扣金額,所以會想要把INVOICE table 和 PROMOTION table 可以做連結。
但我同時又感覺我自己這樣想是錯誤的,因為在查詢時只是要做出查到資料, 計算多少折扣金額的部分應該是另外有關於order的部分(也就是不再我目前設計的範圍內), 但我不確定我哪個想法才是正確的... 請問哪一個想法才是正確的呢?

(因為之前在練習query時 都會練習到計算, 例如:算整個部門平均薪資, 可能這樣因此讓我自己搞混了設計時的重點的)

關於設計折扣的部分, 謝謝您的分享~

關於「要不要定義欄位/定在另一個table」,提供你三點參考:
1.查詢時要不要知道(例:promotioncode,你想知道而我不在乎)
2.跟發票號碼是一對一或是一對多的關係(例:promotioncode,我想預留一張發票對應多個promotioncode的彈性)
3.把「新增/刪除/修改/查詢」四種情境都拿來驗證一遍,都寫得出來就OK了

「對我而言」,promotioncode只有在「新增發票計算金額時」才用得到,只是拿來參考的表,算出發票金額(記錄折扣比例)後就用不到了,所以我就不記錄在 invoice 表裡

最重要的一點
資料庫分析/系統分析是很主觀的行為
只要能寫出使用者的需求就可以了

比起大多數人都在問 UI 的問題
你問這種資料庫定義的「基礎」問題(不是簡單,是重要)
我要給你按個/images/emoticon/emoticon12.gif

Rick iT邦新手 5 級 ‧ 2021-11-30 07:44:45 檢舉

謝謝您更進一步的詳細回答 /images/emoticon/emoticon41.gif
(抱歉 前陣子忙期中考, 現在才回來答謝)

其實你不說我也知道這不是商業系統而只是練習
(所以我一開始就強調,回答是就「你的設計」而非一般情形)

因為在設計商業系統時
大部份的問題都會在「訂單」「庫存管理」
發票這個末端步驟,多半是接收訂單轉過來的資料,沒什麼好考慮的

是說你人都來了
如果問題解決的話
請選最佳解答以結案

我要發表回答

立即登入回答