SQL - 数据库规范化

时间:2015-10-07 17:47:40

标签: sql sql-server database-normalization

我有建议的表结构来扩展数据库:

Proposed table structure

OrganisationalAssets表中。以下列可以为空:

  • Organisation_Id
  • LOCATION_ID
  • LANGUAGE_ID

我们遇到的问题是,Organisation_Id列仅对某些类型的资产可以为空。有些资产与组织有关,有些则永远不会。对于与组织相关的列,其他列,位置和语言适用。如果Organization为NULL。然后语言和位置是这些资产的冗余列。

对我来说,这听起来好像我有一张表错误地存储了两种类型的资产。内部和外部资产。内部不受组织,语言和位置的限制,而外部资产则是。

但是,我不完全确定如何更改结构以反映这一点。无论它们是内部资产还是外部资产,它们仍然可以有许多与之关联的AssetSettings。外部资产将具有一组不同的AssetSettings,这取决于Organization,Location_Id和Language_Id,而内部资产则不会。他们每个人只会有一个设置集合。

我不确定是否:

  1. 只是保持结构不变,因为它有效。虽然没有正确规范化。
  2. 尝试重组表格以允许这两种类型的资产,如果是,则如何。
  3. 示例数据 以下是一些示例数据,希望能更好地理解我的要求:

    OrganisationAssets

    +----+----------+-----------------+-------------+-------------+
    | Id | Asset_Id | Organisation_Id | Location_Id | Language_Id |
    +----+----------+-----------------+-------------+-------------+
    |  1 |        1 | 2               | 3           | 4           |
    |  2 |        1 | 2               | 3           | 999         |
    |  3 |        2 | NULL            | NULL        | NULL        |
    +----+----------+-----------------+-------------+-------------+
    

    前两行适用于AssetId 1.它属于两个不同的位置,是外部资产。 第三行是内部资产,因此其他列是多余的。

    AssetSettings

    +----+------------------------+------+--------+
    | Id | OrganisationalAsset_Id | Key  | Value  |
    +----+------------------------+------+--------+
    |  1 |                      1 | Key1 | Value1 |
    |  2 |                      1 | Key1 | Value1 |
    |  3 |                      2 | KeyA | ValueA |
    |  4 |                      3 | KeyB | ValueB |
    +----+------------------------+------+--------+
    

    在AssetSettings表中。我们可以看到Id1的资产的两个设置(即OrganisationalAsset_Id 1和2)。 我们还可以看到表格中出现的第二个资产,它只能拥有一组设置,因为它不属于任何组织,位置或语言。

2 个答案:

答案 0 :(得分:1)

嗯,正如我从结构中看到的,您已经描述了规范化数据的最佳解决方案是移动所有这3个字段( Organisation_Id Location_Id Language_Id )到[ AssetSettings ]表。在这种情况下,您将避免为不适当的资产设置NULL值,并且您始终可以随时随地引用必填字段。

您可以完全删除 OrganisationalAsset 表,并将 AssetSettings 表直接链接到资产表。

您仍然拥有一个表中的所有资源,因此您无需在两个表中拆分它们,其中最常见的问题是资产的两个 ID字段,因此您需要为包含 AssetId 的每个表保留其他 AssetType 字段。

答案 1 :(得分:0)

1)这似乎是合理的,它是冗余和简单之间的选择,理解数据,使用等将有助于你做出这个决定。

2)正如您已经确定了两种不同类型的Assets,为什么不将其建模为

Assets (Id, Name, AssetType_Id) 
    -- Id is PK

AssetTypes (Id, Name)
    -- Id is PK

InternalAssets (Id, AssetSettings_Id) 
    -- Id is PK and FK referencing Assets(Id)
    -- AssetSettings_Id is FK referencing AssetSettings

ExternalAssets (Id, Asset_Id, AssetSettings_Id, Organisation_Id, Location_Id, Language_Id)
    -- Id is PK 
    -- Asset_Id is FK referencing Assets(Id)
    -- AssetSettings_Id is FK referencing AssetSettings

AssetSettings (Id, Setting1, Setting2, Setting3)
    -- Id is PK 

您可能希望添加一个约束,使得InternalAsset不能是ExternalAsset,反之亦然。

您还可以创建OrganisationalAssets的视图,该视图将合并两个*Assets表,这可能有助于简化查询。