2014-02-17 66 views
3

有一個大表products。我需要將布爾標誌disabled添加到我的產品型號中。通常我只是在現有的表中添加一個新的字段。但是這個屬性將很少使用,並且考慮到表中的記錄數量,這個新字段將會對性能和磁盤空間產生不必要的影響。規範化一對一布爾關係

所以我決定做一種1NF規範化的一對一關係(即將此字段移動到另一個具有外鍵引用的表products;我不知道它是否真的是1NF - 這是我的問題)。但我實際上並不需要truefalse值,因爲這意味着關係的表大小將等於products的大小。所以在關係表的值域中是沒有必要的。所以我的模式是:

CREATE TABLE products (
    id INT PRIMARY KEY, 
    name VARCHAR 
); 

CREATE TABLE disabled_products (
    product_id INT NOT NULL, 
    CONSTRAINT fk_product FOREIGN KEY (product_id) REFERENCES products (id) ON DELETE CASCADE 
); 

SQLFiddle要搗鼓)。

因此,我收到了我想要的 - 只有在設置了標誌的情況下才會存儲該值。在幕後,國旗不是由表格欄表示的,而是由於在給定產品的disabled_products中出現記錄。

只想知道我是否做得對。

這樣的設計有什麼可能的缺點?

它是否適合關係模型(通過我的意思是這種規範化的一般方式和一個表,特別是單一的外鍵列)?如果是的話,你如何在RDB科學上稱這個解決方案?

+0

這不是反規範化。 –

+0

@ypercube,編輯我的問題的Jon Hanna認爲是。我認爲這是正常化。 – Hnatt

+0

是的,我沒有注意到編輯。它現在回滾到原來的狀態。 –

回答

2

人們經常問自己,他們是應該拆分一張桌子還是隻創建一張大桌子。我會講一下底層的一般邏輯。在你的情況下,它純粹是一個明確的性能計算。

優點&您的解決方案的缺點 1)CON:即使記錄很少被禁用,您需要LEFT JOIN此表需要的活動記錄每個查詢。

2)CON:空間節省是1字節,這很可能可以忽略不計,所以爲什麼要麻煩。

3)PRO:它可以幫助您避免必須更改表格,這可能會對您造成問題。

建議:鑑於上述優點和缺點,我建議您只需在表中添加一個字段。這只是一個字節。

一般來說,當甚至修改表格或者存在不同類別的記錄(每個記錄都需要一組特定的字段)或者出於性能原因希望對錶格進行分區時,人們會垂直分割表格。

+0

謝謝!另一個* contra *是我能想到的唯一的實現相對困難。向ActiveRecord模型添加新字段非常簡單,但不容易實現這種bizzare標準化。你給了我更多的理由放棄它,所以我想我會定期進行。 – Hnatt

+0

奇怪的是,你有2)作爲一個CON,而它是一個PRO。它節省了一個字節。無論價值與否,這都是另一回事。 –

+0

如果OP沒有位列,它只會保存一個字節。如果他這樣做,它會進入相同的字節。 – JNK

1

可能的缺點是顯而易見的 - 與將其存儲爲列值不同,您不能假定每行都具有disabled值(因此您必須應用一些自定義邏輯),並且不能內連接兩個表,因爲較小的表格會顯着減少結果集。此外,附加表格不包含任何重要的信息,但陳述了禁用狀態,因此純粹是多餘的,但是就「有利於性能的冗餘」而言,我覺得不知何故提醒了一個星型模式(http://en.wikipedia.org/wiki/Star_schema)。

+0

附加表格包含信息:「產品是否被禁用」。 –

+0

它每行有1位信息,那它怎麼可能是純粹的冗餘? –