我应该有2个相同的表格吗?

时间:2015-02-07 15:59:01

标签: sql database

我需要在同一个表上使用2种不同类型的连接(比如ADDRESSUSER)。我可以制作2个表(BILLING_ADDRESSSHIPPING_ADDRESS),它们都有3列(IDUSER_IDADDRESS_ID),或者我可以创建一个表格(CUSTOMER_ADDRESS)包含类型列(IDUSER_IDADDRESS_IDADDRESS_TYPE)。

对于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,我必须使用单表。业界对此有何看法?

3 个答案:

答案 0 :(得分: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将是一种不太有用的语言,可能不会在任何地方使用。

答案 1 :(得分:0)

单个表格允许更多灵活性。例如,将来您可能决定允许客户存储备用送货地址,并在下订单时选择一个。然后,您可以添加address_type = 'Alternate Shipping Address',您不必添加另一张整张表。

此设计应该对性能影响很小。 user_id上的索引会将查询范围缩小到需要扫描所需地址类型的几行。

答案 2 :(得分:0)

如果满足您的所有需求,单个表会好得多,在这种情况下,您提到的两个方案都会redundant data查看normalization以获取更多信息,在这种情况下我认为如果您有一个表ADDRESS (ID, USER_ID, SHIPPING_ADDRESS_ID, BILLING_ADDRESS_ID).比地址的拖车表更加坚固,在这种情况下,您无法到达forth normal form