2015-02-07 51 views
0

我需要在同一個表上的兩種不同類型的連接(可以說ADDRESSUSER)。我可以使2個表(BILLING_ADDRESSSHIPPING_ADDRESS)在都具有3列(IDUSER_IDADDRESS_ID),或我可以使一個單一的表(CUSTOMER_ADDRESS)與一種類型的柱(IDUSER_IDADDRESS_IDADDRESS_TYPE)。我應該有2個相同的表

對於DRY編碼實踐我只想着單個表,但這意味着當我編譯2個列表時,我將不得不執行全表掃描兩次。

select address.* from customer_addresses, address where user_id = 1 and address_type = 'Billing' 

select address.* from customer_addresses, address where user_id = 1 and address_type = 'Shipping' 

都依賴於customer_addresses表的全表掃描。

如果我們有1000個客戶地址,這意味着已掃描2000條記錄以查找該客戶的所有地址。

如果我做了2個不同的表,則僅1000客戶地址進行掃描,因爲shipping_addresses表僅持有800地址/客戶記錄,以及billing_addresses表持有其他200

所以對於性能我想不得不說2個不同的表格。對於DRY,我將不得不使用單桌。對此有什麼行業的想法?

+0

你在辯論2n和1n之間的時間複雜性。在這種情況下,這並不重要。 – 2015-02-07 16:04:39

+1

它不應該要求全表掃描。 'user_id'上的一個索引會將其過濾爲只有2行,然後只需掃描這兩行就可以找到具有正確'address_type'的行。 – Barmar 2015-02-07 16:04:46

回答

2

送貨地址和賬單地址可能是不同的東西。例如,帳單郵寄地址可能是郵政信箱,但郵寄地址通常不能。同樣,送貨地址可能包含其他信息,例如聯繫人姓名,聯繫電話和送貨說明。我只是提到這一點,因爲您需要確定差異是否足夠重要,以創建單獨的實體,或只是在地址表中包含幾個單獨的字段。

這只是爲了讓您知道可能還有其他字段。

我覺得這是你建議的查詢(與join語法固定):

select a.* 
from customer_addresses ca join 
    address a 
    on ca.address_id = a.address_id 
where ca.user_id = 1 and ca.address_type = 'Billing'; 

這並不需要一個完整的表,智能數據設計掃描。正如Barmar在評論中指出的那樣,您應該在這些表格上有適當的索引。在這種情況下,您需要的索引是customer_address(user_id, address_type)address(address_id)。如果數據庫僅對SELECT查詢執行全表掃描,則SQL將是一種不太有用的語言,可能不會在任何地方使用。

+0

通過將它們放在單獨的表格中指出的靈活性說服了我將它們放在不同的表格中。 – 2015-02-07 21:59:31

0

單個表格允許更多的靈活性。例如,將來您可能會決定允許客戶存儲替代送貨地址,並在下訂單時選擇一個。你可以添加address_type = 'Alternate Shipping Address',你不需要添加另一個整個表。

這個設計應該沒有什麼性能影響。 user_id上的索引將查詢範圍縮小爲僅需掃描所需地址類型的幾行。

0

一個表,如果它滿足您的所有需求要好很多,在這種情況下,你提到的這兩種情況下都會有redundant data看到normalization更多信息,在這種情況下,我認爲,如果你有一個表ADDRESS (ID, USER_ID, SHIPPING_ADDRESS_ID, BILLING_ADDRESS_ID).是遠遠內特有兩個地址表,在這種情況下,你不能達到forth normal form

相關問題