如何正确索引表另外两个表有一对多的关系?

时间:2010-03-01 19:22:38

标签: sql indexing database one-to-many

想象一下,我有三个表,称为“客户”,“公司”和“电话号码”。客户和公司都可以拥有多个电话号码。索引phone_numbers的最佳方法是什么?同时拥有customer_id和company_id并将其中一个保留为null?如果有两个以上的表与phone_numbers有一对多的关系怎么办?

4 个答案:

答案 0 :(得分:1)

您的商家规则可能只列出一对多,但实际上是人与人之间的关系。公司可以是多对多的关系。一个人可以拥有许多电话号码(家庭,手机等),电话号码可以与很多人(我自己,我的重要人物等)有关。同样,公司编号和我的公司编号可以相同 - 您只需使用分机号码直接与我联系。

索引外键是个好主意,但要注意过早优化。根据设置,我会考虑电话号码列上的唯一约束,但我不会将电话号码列本身作为主键。

答案 1 :(得分:0)

我会在客户和公司表格中使用标识列,然后在电话号码表中按照您的说法执行,并保留一个空值,另一个填充。我做了类似于此的操作,只要您验证数据以使它不会同时使两个值为null,它就可以正常工作。对于更优雅的解决方案,您可以有两列:一列是id,另一列是类型标识符。对客户说1,对公司说2,这样你不必担心空数据或许多额外的列。

答案 2 :(得分:0)

我要在phone_numbers表中添加两列。第一个是一个索引,告诉你要关联的表(例如,1 =客户,2 =公司)。第二个是相应表的外键。

这样您可以根据需要添加任意数量的电话号码来源。

如果某个人或公司有多个电话号码,则phone_numbers表中会有多行。

答案 3 :(得分:0)

我对模式最接近的是以下内容 - 任何两个具有多对多关系的实体都需要它们之间的关联实体(交叉引用表),如此(假设代理键):< / p>

CREATE TABLE CUSTOMER_XREF_PHONE
( CUSTOMER_ID      NUMBER NOT NULL,
  PHONE_NUMBER_ID  NUMBER NOT NULL,
  CONSTRAINT       CUSTOMER_XREF_PHONE_PK 
    PRIMARY KEY      (CUSTOMER_ID, PHONE_NUMBER_ID),
  CONSTRAINT       CUSTOMER_XREF_PHONE_UK 
    UNIQUE           (PHONE_NUMBER_ID, CUSTOMER_ID),
  CONSTRAINT       CUSTOMER_XREF_PHONE_FK01
    FOREIGN KEY      (CUSTOMER_ID)
      REFERENCES       CUSTOMER (CUSTOMER_ID) ON DELETE CASCADE,
  CONSTRAINT       CUSTOMER_XREF_PHONE_FK02
    FOREIGN_KEY      (PHONE_NUMBER_ID)
      REFERENCES       PHONE_NUMBERS (PHONE_NUMBER_ID) ON DELETE CASCADE
);

这样的实现模式可以:

  • 受数据库级参照完整性约束的完全保护

  • 支持双向访问(有时您需要查看还有谁拥有该电话号码)

  • 如果您的数据库支持ON DELETE CASCADE

  • ,请进行自我清理
  • 通过使用“关系类型”属性扩展以映射实体之间的多个独立关系, 如:

    • 客户有家庭电话号码
    • 客户有白天电话号码
    • 客户有传真号码
    • 客户有手机号码