我应该规范化还是为每个表添加FK

时间:2015-01-21 10:05:51

标签: sql database join foreign-keys normalization

我一直怀疑我正在处理的项目中使用的数据库设计。我有三个表:EventProductEventsProductProductEventsEventProduct之间的关联表。 EventProduct都具有相同的外键。

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

考虑到规范化规则,我应该只考虑连接选项。但是,对于这个问题,还有一个背景故事。我们有其他表格,例如HouseInterior其中Interior的FK为HouseHouseEstate的鉴别符,包含大约1000万条记录。 Interior包含几千万条记录。直到最近我们才被迫将鉴别器添加到Interior表中,因为连接变得太重,而且速度很慢,即使我们确保结果集尽可能小。

此问题的最佳/常见做法是什么?在每个表中都有一个共同的鉴别器,或者坚持使用连接更好吗?

ERD scetch

1 个答案:

答案 0 :(得分:0)

您可以根据自然键或技术ID设计数据库。对于后者,你得到(主键以粗体显示):

  • 遗产( estate_id ,estate_no,名称......)
  • 产品( product_id ,product_no,estate_id,name,...)
  • 事件( event_id ,event_code,estate_id,name,...)
  • ProductEvents( productevents_id ,product_id,event_id,...)

以下是自然键:

  • 遗产( estate_no ,姓名......)
  • 产品( estate_no,product_no ,名称,......)
  • 活动( estate_no,event_code ,名称,...)
  • ProductEvents( estate_no,product_no,event_code ,...)

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

  1. pro:自然键只在一个地方。如果您决定使用产品编号'AX123'而不是'AE123',那么在一个地方更改它就完成了。
  2. pro:对数据结构的更改很容易。如果事件不再属于遗产,而是现在属于遗产组,与基于自然密钥的数据库中所需的更改相比,这是一个微小的变化。
  3. con:访问数据通常涉及许多表,从给定的自然键到所需的技术ID。
  4. con:dbms无法保证数据的一致性。
  5. 关于最后一点:尽管数据库是规范化的(顺便说一下这两种模型都是这种情况),但ID设计可能会有一个引用两个不同的庄园的ProductEvents(一个通过Event,另一个通过产品)。 DBMS无法确保只能在ProductEvents中组合同一产业的产品和事件。使用自然键,因为ProductEvents具有Event(estate_no,event_code)和Product(estate_no,product_no)的外键,并且ProductEvents中只有一个estate_no。

    与两者合作后,我更喜欢大型数据库的自然键设计。然而,人们甚至可以混合两者。是的,您甚至可以将estate_id添加到ProductEvents。它不再是您拥有的纯ID设计,而是有助于更快地访问数据,您可以将外键添加到Event(event_id,estate_id)和Product(product_id,estate_id)以增强数据一致性检查。我甚至不认为这是非标准化的(但我可能错了)。