2009-10-21 73 views
1

我有關於非規範化或表層次關係的最佳實踐的問題。SQL/MySQL結構(非規範化或保持關係)

舉一個簡單的例子,假設我有一個應用程序允許用戶爲訂單付款。我將訂單信息保存在訂單表中,並且還有另一張名爲付款的付款表。付款具有訂單表的外鍵。

讓我們假設我可以用信用卡,支票或PayPal支付,並且我想保存關於付款的信息。

我的問題是處理不同付款數據和付款表之間這種關係的最佳方式是什麼。支付類型都有不同的數據與他們相關聯。因此,我要使支付表非常規化,將信用卡,支票和PayPal信息字段放在那裏,然後根據需要使用這些字段。或者我可以指定一種支付類型,並將信息存儲在他們自己的表中,但是接下來我將不得不在應用程序級別使用邏輯從正確的信用卡,支票或PayPal信息表中獲取數據...

+0

您需要爲每種付款類型存儲的信息有何不同?對於付款,我通常會存儲付款類型(支票,抄送,支付寶等)以及支票號碼,信用卡授權號碼,貝寶交易號碼等單一的DocumentID列。 – 2009-10-21 14:21:57

+0

付款只是一個簡單的例子。這種情況的實際使用情況要複雜得多,每種類型大約有20個獨特的列。 – Jestep 2009-10-21 14:23:53

回答

1

我會選擇保持數據庫規範化。

但我將不得不使用一個應用程序級別的邏輯來獲取數據出正確的信用卡,支票或PayPal信息表...

你必須使用邏輯(或在任何情況下都至少需要映射)。無論是從哪個表中抽取數據或訪問表中的哪些字段。

0

所以我反規格支付 表,將信用卡,支票和 貝寶信息字段在那裏和 然後只是在必要時使用字段。

是的。但這不是「反常規」。如果您將訂單信息存儲在客戶表中,那將會非規範化。添加可爲空的列以準確描述付款表中的付款不是。

+0

有些人可能會爭辯說,具有可爲空的列會代表某種程度的非規範化 – 2009-10-21 14:18:11

+0

不確定它違反了哪種規範化規則,但在支付表中包括與該付款無關的列表示某種程度的非規範化。 – 2009-10-21 14:20:38

1

如何保持非規格化,然後再次將數據重新組合起來。你得到兩全其美。 IIRC,MySQL在第5版中引入了視圖。

0

您可以像ORM工具那樣使用每個子類的表的想法。這將需要加入每個查詢對付支付表,但...

爲每種支付類型創建表,所以你將有一個creditcardpayment和checkpayment表。通用字段放在付款表中,具體字段放在子表中。子表主鍵是支付表ID的外鍵。

要添加新的付款,您必須先將通用字段插入付款表,獲取生成的ID,然後將特定字段插入到特定的子表中。

要查詢您必須加入與付款表的子表。您可以使用視圖來簡化操作。

這樣數據庫仍然正常化,並且您沒有空列。

0

它部分取決於您正在使用的框架(如果有的話)。例如:Ruby on Rails的方式通常是將支付類型存儲在支付表中,然後爲每種支付類型(貝寶,信用卡等)分別設置不同的表格。另外,如果你注意到你在許多表中重複了相同的數據,Rails有一種方法可以將所有數據存儲在同一個表中,只使用你需要的字段,但仍然允許你擁有分開的對象。例如,您將擁有一個AbstractPayment對象和一個abstract_payments表,但您也將擁有從AbstractPayment繼承的PayPalPayment和CreditCardPayment對象,並使用abstract_payments表。您需要確定付款類型是abstract_payments中的一個列,告訴您它是哪種類型(可能是一個字符串,但如果您願意,可以是一個整數)。這被稱爲STI

不管你用什麼框架/語言,同樣的想法,絕對可以申請。我認爲正確的解決方案,將取決於有多少不同類型的你有支付的,與你的數據庫,你要如何簡單進行比較。

0

儘量保持標準化。只有在完全規範化模式的性能需要非規範化以提高響應時間時才進行反規範化處理,並且僅在個案基礎上才能處理與應用程序中單個查詢相關的特定性能問題。

這些都是複雜的問題。數據庫規範化需要熟悉的領域知識,並熟練分析如何在您的應用程序中處理和利用該領域模型。爲了提高性能而非規範化要求您理解應用程序的使用模式,以便在性能問題發生之前對其進行預測(等到實際發生在生產中爲時已晚),並知道非規範化技術用來解決它們。

0

您需要加權以下因素:

  • 多少空間,如果你把所有的數據到一個表
  • 如何複雜的SQL查詢將成爲在這兩種情況下,你會浪費。

如果使用不同的表,你將不得不使用連接。如果你把所有東西都放到一張表中,你需要找到一些魔法來「忽略」那些無關緊要的行(比如說當你想查找所有的信用卡付款時:你的查詢必須忽略其他所有東西) 。當你移動的特殊數據到特殊表在更復雜的連接成本

後半部分變得更加容易。