0

我创建了一个包含三个表的数据库:

Restaurant
restaurant_id (autoincrement, PK)

Owner
owner_id (autoincrement, PK)
restaurant_id (FK to Restaurant)

Deal
deal_id (autoincrement)
owner_id (FK to Owner)
restaurant_id (FK to Restaurant)
(PK: deal_id, owner_id, restaurant_id)

每个餐厅可以有多个所有者。我为 Deal 选择了两个外键,因此我可以通过所有者或餐厅来引用该交易。交易表将有三个主键,两个是外键。它会有两个指向它的一对多关系。我所有的外键都是主键,我不知道我以后会不会后悔这样做。这种设计是否有意义,并且看起来对我想要实现的目标有好处?

编辑:我真正需要在这里完成的是当所有者登录并查看他们的帐户时,我希望他们能够查看和编辑与该特定餐厅关联的所有交易。而且因为每个餐厅可以有多个所有者,所以我需要能够执行类似的查询:select *from Deals where restaurant_id = restaurant_id。换句话说,如果我是所有者并且我已登录,我需要能够进行查询:获取不仅与我(所有者)相关的所有交易,而且与与关联的所有所有者相关的所有交易这家餐厅。

4

5 回答 5

4

你在术语方面遇到了一些麻烦。

一张表只能有一个主键。无法创建具有两个不同主键的表。您可以创建具有两个不同唯一索引(很像主键)的表,但只能存在一个主键。

您要问的是您是否应该拥有复合主键或复合主键;使用多个列的主键。

您的设计还可以,但正如您所写的那样,您可能不需要列 deal_id。在我看来,restaurant_id 和 owner_id 一起足以唯一标识 Deal 中的一行。(如果由于资本重组或收购另一位所有者,一位所有者可以在一家餐厅拥有两种不同的所有权股份,则这可能不正确,但您在问题陈述中没有提到类似的事情)。

在这种情况下,deal_id 很大程度上浪费了存储空间。如果您有许多具有指向 Deal 的外键的表,或者如果您有要同时向用户显示多个餐厅业主的Deals 的实例,则可能需要使用 deal_id 列.

如果其中一个论点促使您采用 deal_id 列,那么它应该是主键,并且只有它应该是主键。由于自动增量值本身是唯一的,因此包含其他两列不会添加任何内容。

于 2012-05-17T02:57:55.823 回答
1

如果你有一个唯一的字段,这应该是 PK,那将是递增的字段。
在这种特定情况下,它根本没有给你任何东西来向这个键添加更多字段,它实际上在某种程度上影响了性能(不要问我有多少,你把它放在凳子上)。

于 2012-05-17T00:46:20.317 回答
0

它没有错,它有效。但是,它不推荐。

自动增量主键在没有外键(或主键)的情况下工作

在某些数据库中,您不能将多个字段用作单个主键。

复合主键或组合主键在查询中更难处理。

复合主键查询示例:

SELECT
  D.*
FROM 
  Restaurant AS R,
  Owner AS O,
  Deal AS D
WHERE
  (1=1) AND
  (D.RestaurantKey = D.RestaurantKey) AND
  (D.OwnerKey = D.OwnerKey)

相对

单主键查询示例:

SELECT
  D.*
FROM 
  Restaurant AS R,
  Owner AS O,
  Deal AS D
WHERE
  (D.OwnerKey = O.OwnerKey)

有时,您必须将一条记录的外键值更改为另一条记录。例如,您的客户已经订购,交易记录已注册,他们决定从一张餐厅餐桌更改为另一张餐桌。因此,必须更新“所有者”和“交易”表中的数据。

+-----------+-------------+
|  OwnerKey | OwnerName   |
+-----------+-------------+
|      1    | Anne Smith  |
+-----------+-------------+
|      2    | John Connor |
+-----------+-------------+
|      3    | Mike Doe    |
+-----------+-------------+

+-----------+-------------+-------------+
|  OwnerKey |   DealKey   |     Food    |
+-----------+-------------+-------------+
|      1    |       1     | Hamburguer  |
+-----------+-------------+-------------+
|      2    |       2     |   Hot-Dog   |
+-----------+-------------+-------------+
|      3    |       3     | Hamburguer  |
+-----------+-------------+-------------+
|      1    |       3     |    Soda     |
+-----------+-------------+-------------+
|      2    |       1     | Apple Pie   |
+-----------+-------------+-------------+
|      3    |       3     |    Chips    |
+-----------+-------------+-------------+

如果使用复合主键,则必须为“Owner”创建新记录,为“Deals”创建新记录,复制其他字段,并删除以前的记录。

如果使用单键,只需要更改 Table 的外键,无需插入或删除新记录。

干杯。

于 2012-05-17T01:02:18.373 回答
0

s name 我认为它的含义就像是用来识别餐​​厅餐桌是否被客户预订,并查看您是如何设计数据库的,即使没有将餐桌指定为,您也可以识别他们预订的餐桌交易表中的外键由于使用所有者表,您将能够确定他们已经保留了哪个表,因为您将它用作所有者表上的外键,您真的必须明智地定义表之间的关系和尽可能避免冗余。:)

于 2012-05-17T01:02:42.930 回答
0

我认为这不是最好的。

首先Deal表PK应该是deal_id。没有理由向它添加额外的列 - 如果您确实想在另一个表中引用 deal_id,则必须包括 restaurant_id 和 owner_id,这不好。deal_id 是否也应该是聚集索引(也就是在此列上组织的索引)取决于数据访问模式。您的数据库中是否充满了最常用于查找的 data_id 值,或者您主要通过 owner_id 或 restaurant_id 查找交易?

此外,使用您所描述的两个单独的 FK 方式(据我所知!)将允许交易具有无效的所有者和餐厅组合(组合不属于该餐厅的所有者)。在 Deal 表中,而不是一个 FK 到 Owner 和一个 FK 到 Restaurant,如果您必须同时拥有这两个列,则应该有一个复合 FK 到 (OwnerID, RestaurantID) 上的 Owner 表,并在 Owner 表中具有相应的唯一键允许此链接。

但是,对于这样一个简单的表结构,我并没有真正看到将 RestaurantID 排除在 Deal 表之外的问题,因为 OwnerID 总是完全暗示 RestaurantID。显然,您的交易不能仅与餐厅相关联,因为这将意味着 Deal:Owner 的 1:M 关系。通过 Owner 表基于 Restaurant 进行搜索的成本应该不会那么糟糕。

于 2012-05-17T01:16:14.457 回答