vek*_*tor 13 foreign-key database-design
简单的例子:有一张客户表。
create table Customers (
id integer,
constraint CustomersPK primary key (id)
)
Run Code Online (Sandbox Code Playgroud)
数据库中的所有其他数据都应该链接到 a Customer
,例如Orders
看起来像这样:
create table Orders (
id integer,
customer integer,
constraint OrdersPK primary key (customer, id),
constraint OrdersFKCustomers foreign key (customer) references Customers (id)
)
Run Code Online (Sandbox Code Playgroud)
假设现在有一个表链接到Orders
:
create table Items (
id integer,
customer integer,
order integer,
constraint ItemsPK primary key (customer, id),
constraint ItemsFKOrders foreign key (customer, order) references Orders (customer, id)
)
Run Code Online (Sandbox Code Playgroud)
我应该从Items
to添加一个单独的外键Customers
吗?
...
constraint ItemsFKCustomers foreign key (customer) references Customers (id)
Run Code Online (Sandbox Code Playgroud)
取而代之的是一张图片:我应该添加虚线/FK吗?
编辑:我已向表中添加了主键定义。我想重申我上面提出的观点:数据库基本上是由客户孤立的,作为一种正确性/安全措施。因此,所有主键都包含customer
ID。
我认为这是最初的想法。
首先要注意的是 LineItem 表上的 PK 具有三个属性{CustomerID, CustomerOrderNo, OdrerItemNo}
,而您的示例中只有两个属性。
要注意的第二件事是对id
属性使用通用名称所导致的混淆。
在CustomerOrderNo
理想情况下应(1,2,3 ......)为每一个客户和OrderItemNo
(1,2,3 ......)每个订单。
好吧,如果可能的话,这很好,但需要查询查找先前的最大值,例如
select max(CustomerOrderNo)
from Order
where CustomerID = specific_customer ;
Run Code Online (Sandbox Code Playgroud)
这在高交易量环境中通常不是首选,因此通常会看到它们被自动增量替换,基本上用于相同的目的。确实,这个自动增量现在是独一无二的,因此它可以用作密钥——但您可以选择将其视为OrderItemNo
.
因此,通过一些重命名CustomerOrderNo -> OrderNo
和OrderItemNo
->ItemNo
您可能会到达此模型
所以现在如果你看看Order
以下是独一无二的
{OrderNo} -- PK
{CustomerID, OrderNo} -- superkey, AK on the diagram.
Run Code Online (Sandbox Code Playgroud)
请注意,{CustomerID, OrderNo}
它传播到LineItem
用作 FK。
如果你眯着眼睛,这与你的例子很接近,但PKs {ItemNo} and {OrderNo}
只有 -- 而不是你的例子中的两列 PK。
现在的问题是,为什么不简化成这样呢?
这很好,但是引入了PATH DEPENDENCE——不能直接join LineItem
with Customer
,必须Order
在join中使用。
如果可能,我更喜欢第一种情况——你选择你最喜欢的。显然,在这三种情况下,不需要直接 FK from LineItem
to Customer
。
归档时间: |
|
查看次数: |
1255 次 |
最近记录: |