是否有必要在关联实体中使用所有3个外键作为主键?

时间:2018-06-16 09:51:50

标签: database postgresql database-design constraints primary-key

Relational Model

我想打破SalesManCustomer与新实体Sale之间的多对多关系。 我想在idSalesMan中使用idCustomerSale作为主键,但SalesMan的外键也在Sale实体中。 我是否需要将所有3个外键用作主键,或者idSalesManidCustomer是否足够?

以下是脚本的外观(使用Postgres):

CREATE TABLE Company(
    idCompany SERIAL PRIMARY KEY,
    name VARCHAR(45) NOT NULL
);

CREATE TABLE SalesMan(
    idSalesMan SERIAL PRIMARY KEY,
    name VARCHAR(45),
    wage DOUBLE NOT NULL,
    Company_idCompany INT REFERENCES Company ON DELETE CASCADE
);

CREATE TABLE Customer(
    idCustomer SERIAL PRIMARY KEY,
    name VARCHAR(45) NOT NULL
);

CREATE TABLE Sale(
    SalesMan_idSalesMan INT REFERENCES SalesMan ON DELETE CASCADE,
    SalesMan_Company_idCompany INT REFERENCES Company ON DELETE CASCADE,
    Customer_idCustomer INT REFERENCES Customer ON DELETE CASCADE,
    PRIMARY KEY (SalesMan_idSalesMan, Customer_idCustomer 
    /*,SalesMan_Company_idCompany?*/)
);

2 个答案:

答案 0 :(得分:1)

要回答拼贴中的问题:,不一定。

如果FK列的组合需要In [10]: from scipy import stats In [11]: p = 0.9978 In [12]: scale_param = 3.5666 In [13]: shape_param = 0.4936 In [14]: stats.weibull_min.ppf(p, shape_param, scale=scale_param) Out[14]: 139.97751836430132 UNIQUE,那么这样的PK才有意义。两者都不是这样的。事实上,在这个模型中强制执行唯一性似乎很奇怪。客户不允许两次从同一个推销员那里购买? (涉及同一家公司?)

您可以使用其他列来使NOT NULL中的每一行都是唯一的。一个Sale浮现在脑海中。你会有,但它通常不会使销售独特。两次购买可能同时发生。如果没有可靠的自然密钥,请使用代理PK ,例如timestampserial列。

我会在 任何 的情况下执行此操作,即使FK列的集合恰好定义为IDENTITYUNIQUE。我会在适用的情况下创建NOT NULL约束或索引另外(以及UNIQUE约束)。 (或者在大多数情况下至少是性能的简单索引。)除了非常简单的情况,只有两个小的FK列可以形成PK,并且表本身不被FK约束引用,并且不太可能在以后改变。对于其他任何事情,代理PK更简单,更快速,更可靠,并使以后的更改更容易。

此外,与Mureinik explained一样,FK列NOT NULL通常是多余的,应该删除:它由销售人员决定。 除非,否则您的模型允许以某种方式涉及独立公司的客户和销售人员之间的销售。

我还会重新考虑显示的命名约定。更多:

答案 1 :(得分:0)

根据规范化最佳做法,您在npm i --save body-parser中甚至不应该有SalesMan_Company_idCompany列。有关公司的信息保存在Sale表中,如果您需要SalesMan,则应该加入Sale表。