我应该将 FK 归一化还是添加到每个 table

Should I normalize or add FK to each table

我一直对我正在从事的项目中使用的数据库设计表示怀疑。我有三个 table:EventProductEventsProductProductEventsEventProduct 之间的链接 table。 EventProduct 都有相同的外键。

为了删除ProductEventstable中的记录,我没有Estate的外键,因此需要在删除前加入。现在我想知道最好的解决方案是什么:为每个需要完成的查询添加外键或加入 EventProduct table。

考虑到规范化规则,我应该只考虑连接选项。不过,这个问题还有一个背景故事。我们还有其他 tables,例如HouseInterior,其中 InteriorHouse 有外向关系。 House 有一个 Estate 的鉴别器,包含大约 1000 万条记录。 Interior 包含几亿条记录。直到最近,我们才被迫将鉴别器添加到 Interior table 中,因为连接变得太重、太慢,即使我们确保结果集尽可能小也是如此。

这个问题的best/common做法是什么?在每个 table 中有一个共同的鉴别器还是坚持连接更好?

您可以根据自然键或技术 ID 设计数据库。使用后者,您将获得(粗体主键):

  • 庄园(estate_id,estate_no,姓名...)
  • 产品(product_id、product_no、estate_id、名称、...)
  • 事件(event_id、event_code、estate_id、姓名、...)
  • ProductEvents (productevents_id, product_id, event_id, ...)

自然键也一样:

  • 房产(estate_no,姓名...)
  • 产品(estate_no、product_no、名称、...)
  • 事件(estate_no、event_code、姓名、...)
  • 产品事件(estate_no、product_no、event_code、...)

所以,是的,在使用技术 ID 时,当您想要访问特定 Estate 的 ProductEvents 时需要加入。这显示了技术 ID 设计的优点和缺点:

  1. 亲:自然键只有一个地方。如果您决定使用财产编号 'AX123' 而不是 'AE123',那么在一个地方更改它就完成了。
  2. 亲:修改数据结构很容易。如果一个事件不再属于一个产业,而是现在属于一个产业组,那么与基于自然键的数据库中所需的更改相比,这是一个很小的变化。
  3. con:访问数据通常涉及许多表,以从给定的自然键获取所需的技术 ID。
  4. con: dbms 无法保证数据的一致性。

至于最后一点:虽然数据库是规范化的(顺便说一句,两种模型都是这种情况),但 ID 设计可以让 ProductEvents 引用两个不同的资产(一个通过 Event,其他通过产品)。 DBMS 无法确保只有同一财产的产品和事件才能在 ProductEvents 中组合。它可以使用自然键,因为 ProductEvents 具有 Event(estate_no, event_code) 和 Product(estate_no, product_no) 的外键,并且只有一个 estate_no 在产品事件中。

两者都使用过,我更喜欢大型数据库的自然键设计。但是,甚至可以将两者混合。是的,您甚至可以将 estate_id 添加到 ProductEvents。它不再是你曾经的纯 ID 设计,而是有助于更快地访问数据,你可以将外键添加到 Event(event_id, estate_id) 和 Product(product_id, estate_id) 以加强数据一致性检查。我什至不认为这是非标准化的(但我对此可能是错误的)。