【问题标题】:Exclusice Arc and multiple many to many relationships db design issue独家弧和多个多对多关系数据库设计问题
【发布时间】:2012-06-07 05:07:03
【问题描述】:

我有一个现有的应用程序,在数据库中有以下实体

  • 客户
  • 发票组
  • 销售组

一个客户可以是多个组的一部分。目前这是通过以下方式映射的

Customer table
 - cid (Pk)
 - fname
 - surname
 ----
 ---
 - invgrpdid (Fk)
 - salesid (Fk)

Invoicegroup table
 - invgrpid (Pk)
 - name
 - type
 ---
 ----

Salesgroup table
 - salesid (Pk)
 - name
 - desc
 -----
 -----

我现在需要添加一个新的实体广告系列。一个客户可以是多个活动的一部分。为由以下人员创建的客户组部署了活动 - 选择个人客户(自定义)或 - 选择现有的发票组(发票)或 - 选择现有的销售组(销售)

广告系列客户列表应为 - 可重复使用,即可用于多个活动 - 动态的,即如果从发票/销售组创建,则在发票和销售组之间发生变化 应反映到活动客户列表中

我在设计动态需求时遇到了困难。我提出了以下设计,但它具有专有弧,即一个键引用多个外键,这不是推荐的方法。考虑过超类型和子类型,但是对于多对多关系的设计我不是很清楚。

campaign
 - campaignid(Pk)
 - name
 - startdate
 - status
 ------

campaignlist
 - listid(Pk)
 - listname
 - listtype - Invoice, Sales, Custom
 - typeid (Fk) - Refers to invoicegroupid or salesgroupid depending on listtype
 -----

customercampaign
  - listid (Fk)
  - customerid (Fk)
  - status
  - dateupdated
  -------------

考虑到参照完整性和规范化,有什么更好的设计方法。 每天多次运行的最频繁查询是检索客户的所有活动信息。所以需要注意多个表和连接。

【问题讨论】:

  • 当你说“我不清楚设计多对多关系”时,你说的是什么多对多关系?
  • @Catcall - 我的意思是客户和活动表以及发票组和活动以及销售组和活动的多对多关系。正如 Eric Smith 建议的那样,我曾考虑为每个表单独连接表,但想知道是否还有其他方法。

标签: database postgresql database-design many-to-many


【解决方案1】:

在第一次尝试时,我会这样做:

CampaignList
    - ID (PK)
    - Name

CustomerCampaignList
    - CampaignListID (FK to CampaignList.ID)
    - CustomerID (FK)
      UNIQUE (CampaignListID, CustomerID)

SalesGroupCampaignList
    - CampaignListID (PK,FK to CampaignList.ID)
    - SalesGroupID (FK)
      UNIQUE (CampaignListID, SalesGroupID)

InvoiceGroupCampaignList
    - CampaignListID (PK,FK to CampaignList.ID)
    - InvoiceGroupID (FK)
      UNIQUE (CampaignListID, InvoiceGroupID)

即使用表继承。这是一个相当规范化的设计,在我看来,这是在您尚未了解具体要求时采用的方法。或者,您可以通过将CampaignListTypeID 放入CampaignList 表中来使您的生活更轻松。但是,在这种情况下,如果不在触发器中编写逻辑,就很难保持数据模型的完整性。

我假设您永远不必进行有趣的组合组,例如 2 x 销售组 + 发票组 + 一组客户。

【讨论】:

  • 有趣的组合属于自定义类别,其中您存储对客户而不是组的引用。所以 customercampaignlist 表会处理这种情况。对于您的第一种方法,所有 3 个表可能是多对多关系,这意味着我不能使用第二种方法,因为列表可以包含一个或多个组,但不会包含组的组合和个人客户。有没有办法使用超类型/子类型来实现这一点?
  • 我正在处理您提供的定义,即:“为通过以下方式创建的客户组部署活动 - 选择单个客户(自定义)或 - 选择现有发票组(发票)或- 选择一个现有的销售组(销售)”。我的解释是这三个选项是相互排斥的......您可以选择根据个人客户定义您的活动,根据销售组,或 i> 就发票组而言,但不是三者的组合。
  • 你是对的,它们是互斥的(至少在某种程度上),但是可以根据 1+ 个销售组或 1+ 个发票组来定义一个活动,其中单独的表格方案可以工作.一个活动不会被定义为销售组和发票组或销售组和个人客户等的组合。还有一个重要的要求,我错过了,每天多次运行的最频繁查询是找出所有活动客户所属的。所以我想,我也需要注意连接。我已编辑问题以包含要求。
  • @Angela,这是最规范的设计 IMO。我同意,实用很重要,但要注意过早的优化。使用该设计构建一些东西,然后测试您关于复杂连接的性能影响的理论。
  • 我接受了您的回答 Eric,但是我们采用了稍微不同的设计,但我可以说它的灵感来自您为 salesgroup 和 invoicegroup 设计的不同表格。我们的salesgroupcampaign 表是campaignid 和salesgroupid 之间的映射,而不是listid 和salesgroupid。如果它是由来自不同组的客户组成的自定义列表,我们只会存储一个单独的 customercampaignlist。这样可以更轻松地检索特定客户的广告系列。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 2011-05-03
  • 2015-01-20
  • 2011-05-01
相关资源
最近更新 更多