1

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

4

4 回答 4

1

您的业​​务规则可能只规定一对多,但实际上人员和公司可以是多对多的关系。一个人可以有很多电话号码(家庭、手机等),而一个电话号码可以与很多人相关(我自己、我的另一半等)。同样,公司号码和我的公司号码可以相同 - 您只需使用分机号码直接联系我。

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

于 2010-03-01T19:31:01.287 回答
0

我会在客户和公司表中使用身份列,然后在电话号码表中按照你说的做,并保持一个为空,另一个填充。我做了类似的事情,只要你验证数据,它就可以正常工作,这样它就不会在两个值都为空的情况下进入。对于更优雅的解决方案,您可以有两列:一列是 id,另一列是类型标识符。假设 1 代表客户,2 代表公司,这样您就不必担心空数据或大量额外列。

于 2010-03-01T19:31:06.260 回答
0

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

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

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

于 2010-03-01T19:31:16.217 回答
0

我对模式最接近的事情如下——任何两个具有多对多关系的实体都需要它们之间的关联实体(交叉引用表),就像这样(假定代理键):

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

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

    • 客户有家庭电话号码
    • 客户有一个白天的电话号码
    • 客户有一个传真电话号码
    • 客户有手机号码
于 2010-03-01T20:29:54.037 回答