我想打破SalesMan
和Customer
与新实体Sale
之间的多对多关系。
我想在idSalesMan
中使用idCustomer
和Sale
作为主键,但SalesMan
的外键也在Sale
实体中。
我是否需要将所有3个外键用作主键,或者idSalesMan
和idCustomer
是否足够?
以下是脚本的外观(使用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?*/)
);
答案 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 ,例如timestamp
或serial
列。
我会在 任何 的情况下执行此操作,即使FK列的集合恰好定义为IDENTITY
和UNIQUE
。我会在适用的情况下创建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
表。