我有一个我正在尝试规范化的架构:
Component
( component_id
, component_number
, component_revision
, ...
)
Component_lot
( component_lot_id
, component_lot_number
, component_number
, component_revision
, ...
)
Component_supplier
( component_supplier_id
, component_supplier_name
, component_number
)
理想情况下,我想删除component_lot和component_supplier表中的component_number,以及component_lot表中的component_revision,并且只使用component_id。
问题在于,当组件修订版更改时,组件表中有多个条目用于相同的组件编号,我必须找到一种确定哪个修订版处于活动状态的好方法(它不是简单的1,2 ,3编号系统,我可以排序,并且可能存在新版本但尚未激活)。此外,如果我创建组件的新版本,它将获得一个新的ID,现在我必须在component_supplier中为该组件的新版本建立供应商。
我考虑在组件中创建一个isActive字段,但这似乎不是解决问题的有效方法。我还考虑将component_number保持为component_supplier中的fk,但是有些情况下组件号可能会发生变化(很少见,但可能)。
任何建议或文章链接都将不胜感激。
答案 0 :(得分:0)
从你的故事中我了解到component_number是它自己的实体,所以:
Table Component_Numbers
( component_number_id /* PK */
, component_number
)
/* UK: component_number */
Table Components
( component_id /* PK */
, component_number_id /* FK to Component_Number */
, component_revision /* Descriptive. */
)
/* UK: component_number_id + component_revision */
Table Component_Lots
( component_lot_id /* PK */
, component_id /* FK to components. */
, component_lot_number /* Descriptive. */
)
/* UK: component_lot_number */
Table Component_Suppliers
( component_supplier_id /* PK */
, component_supplier_name /* Descriptive. */
, component_number_id /* FK to component_numbers. */
)
/* UK: component_supplier_name + component_number_id */
建议:为了使列名保持简洁明了,我建议使用id
而不是component_supplier_id
等。引用后,请使用目标表的别名作为前缀,例如component_number_id
成为{ {1}} cnr_id
作为cnr
的别名。
有各种方法。最常见的是:active_flag。需要业务规则来验证每个component_number_id只能有一个有效。这可以通过客户端,数据库端使用唯一键约束(依赖于数据库平台,SQL Server和Oracle对空值和唯一键具有不同的语义)或数据库端使用触发器来完成。
替代实现是维护表components_active。当component_id出现在该表中时,它处于活动状态。 UK最多确保一个component_number_id。根据您的平台,您需要将component_number_id复制到该表中,这会引入额外的代码来维护它。