父/子表查询模式

时间:2014-04-02 22:06:48

标签: sql design-patterns database-design

假设我的数据库中有以下父/子表关系:

TABLE offer_master( offer_id int primary key, ..., scope varchar ) TABLE offer_detail( offer_detail_id int primary key, offer_id int foreign key, customer_id int, ... )

其中offer_master.scope可以采用值

  • 个人:向特定客户提供优惠时。在这种情况下, 只要在offer_master中插入一行,就会有相应的行 添加到offer_detail的每个已扩展优惠的客户。

e.g。

INSERT INTO offer_master( 1, ..., 'INDIVIDUAL' ); INSERT INTO offer_detail( offer_detail_id, offer_id, customer_id, ... ) VALUES ( 1, 1, 100, ... ) INSERT INTO offer_detail( offer_detail_id, offer_id, customer_id, ... ) VALUES ( 2, 1, 101, ... )

  • GLOBAL :向所有客户提出要约时。在这种情况下, 可以按如下方式将新要约添加到父表:

INSERT INTO offer_master( 2, ..., 'GLOBAL' ); INSERT INTO offer_master( 3, ..., 'GLOBAL' );

但子行仅添加到offer_detail 当客户表示对报价有兴趣时。所以 情况可能是,稍后我们会有

INSERT INTO offer_detail( offer_detail_id, offer_id, customer_id, ... ) VALUES ( 4, 3, 100, ... )

鉴于这种情况,假设我们想查询数据库 获得已扩展至客户100的所有优惠; 这包括3种类型的优惠:

  • 特别针对客户100扩展的优惠。
  • 客户100表示不感兴趣的全球优惠。
  • 客户100确实对此感兴趣的全球优惠。

我看到两种方法:

  1. 使用子查询: SELECT * FROM offer_master WHERE offer_id in ( SELECT offer_id FROM offer_detail WHERE customer_id = 100 ) OR scope = 'GLOBAL'
  2. 使用UNION SELECT om.* FROM offer_master om INNER JOIN offer_detail od ON om.offer_id = od.offer_id WHERE od.customer_id = 100 UNION SELECT * FROM offer_master WHERE scope = 'GLOBAL' 注意:自全球优惠以来无法使用UNION ALL 客户对此感兴趣的内容将会重复。
  3. 我的问题是:

    1. 此查询模式是否有名称?
    2. 两种查询方法中哪一种更可取?
    3. 应该以某种方式改进数据库设计吗?

1 个答案:

答案 0 :(得分:1)

我不知道模式名称。

对我来说,第二个查询更清楚,但我认为其中任何一个都没问题。

offer_detail似乎是一个双用途表,对我来说有点红旗。您可能在单个要约中为客户提供单独的表,以及表示有兴趣的客户。