2015-02-07 110 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

相关问题