Database 是否有必要将所有3个外键用作关联实体中的主键?

Database 是否有必要将所有3个外键用作关联实体中的主键?,database,postgresql,database-design,constraints,primary-key,Database,Postgresql,Database Design,Constraints,Primary Key,我想用新实体打破销售人员和客户之间的多方面关系:销售。 我想使用idSalesMan和idCustomer作为Sale中的主键,但是sales中也有一个外键,它将位于Sale实体中。 我是否需要将所有3个外键都用作主键,或者idSalesMan和idCustomer是否足够 以下是脚本的外观(使用Postgres): 根据规范化最佳实践,您甚至不应该在Sale中有sales\u Company\u idCompany列。有关公司的信息保存在销售人员表中,如果您需要它进行销售,您应该加入销售人员表

我想用新实体打破
销售人员
客户
之间的多方面关系:
销售
。 我想使用
idSalesMan
idCustomer
作为
Sale
中的主键,但是
sales
中也有一个外键,它将位于
Sale
实体中。 我是否需要将所有3个外键都用作主键,或者
idSalesMan
idCustomer
是否足够

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


根据规范化最佳实践,您甚至不应该在
Sale
中有
sales\u Company\u idCompany
列。有关公司的信息保存在
销售人员
表中,如果您需要它进行
销售
,您应该加入
销售人员
表。

回答互动程序中的问题:,不一定

只有当FK列的组合需要是
唯一的
非空的
时,这样的PK才有意义。两者都不必如此。事实上,在这个模型中强制执行唯一性似乎很奇怪。客户不允许从同一个推销员那里购买两次?(涉及同一家公司?)

您将有额外的列使
Sale
中的每一行都是唯一的。一个
时间戳
浮现在脑海中。你会有,但它通常不会使销售独一无二。两次购买可能同时发生。如果没有可靠的自然密钥,请使用代理PK,如
序列
标识

我会在任何情况下这样做,即使FK列集恰好被定义为
UNIQUE
notnull
。在适用的情况下,我会另外创建一个
唯一的
约束或索引(以及
非空
约束)。(或者至少在大多数情况下是性能的普通索引。)可能除了非常简单的情况,只有两个小的FK列可以形成PK,并且表本身不被FK约束引用,以后不太可能更改。对于其他任何事情,代理PK都更简单、更快、更可靠,并且使以后的更改更容易

同样,FK列
saller\u Company\u idCompany
通常是多余的,应该删除:它由销售人员决定。除非你的模型允许客户和销售人员之间以某种方式涉及独立公司的销售

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


谢谢大家。MySql Workbench(我用于建模的工具)在销售中生成saller\u Company\u idCompany外键有什么原因吗?它会自动执行,如果您删除密钥,它会删除关系。@Javier:我不知道MySQL Workbench,对不起。也许不是与博士后合作的最佳工具。
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?*/)
);