【问题标题】:SQL Many-to-many Combination TableSQL多对多组合表
【发布时间】:2012-06-26 09:13:48
【问题描述】:

我遇到了一个有趣的数据库设计问题,它的解决方案还不令人满意。

我有一个车站表格,其中包含以下字段:
- key_station(主键)
- 站名
- 信息

然后我有一个职位表
- key_position(主键)
- 位置编号
- 信息
- key_station(站点的外键)

设置表
- key_setup(主键)
- 设置号码
- 信息
- key_station(站点的外键)

现在,Positions 表列出了一个站点的所有插槽号,而 Setups 表列出了一个站点的所有可能的不同设置。我需要的是一张桌子,根据设置在每个位置都有不同的部分。有些职位可能是空的。比如……

设置 1
位置 1 - AA
位置2 - BB
Position3 - NULL

设置 2
Position1 - NULL
位置 2 - CC
Position3 - NULL

所以我创建了一个表名Settings,其中包含以下字段:
- key_setting(主键)
- key_position(外键)
- key_setup(外键)
- 部分

这里的问题是我必须确保 Settings 始终具有引用表的组合。因此,当我在示例中插入一个新位置时,它必须在设置中插入 2 条记录(每个设置一个),或者当我插入一个新设置时,它必须在设置中插入 3 条记录(每个位置一个),其中 NULL 部分用户可以稍后填写。为什么?因为每个设置中的位置都不会改变,只会改变它们分配的部分。

我目前所做的是使用两个 SQL 语句在表 Positions and Settings(或 Setups and Settings)中插入和删除。不幸的是,我遇到了插入位置或设置的问题,而表设置中没有相应的记录,因为我没有注意操作的原子性。

所以我想知道对于中间表必须具有该关系的所有组合的多对多关系的最优雅和正确的解决方案是什么。我需要什么样的标准化?或者我可以在 SQL Server 中添加什么样的约束?此问题是否有特定名称,以便我进行更多搜索?

【问题讨论】:

    标签: sql sql-server database-design many-to-many normalization


    【解决方案1】:

    • ON UPADE CASCADE ON DELETE CASCADE配置FKs

    • 插入新的StationSlotStationSetup 后运行此


    insert into StationConfiguration (StationID, StationSlotNo, StationSetupNo)
    select
          a.StationID
        , b.StationSlotNo
        , a.StationSetupNo
    from StationSetup as a
    join StationSlot  as b on b.StationID = a.StationID
    where not exists (
         select 1 
         from StationConfiguration as xx
         where xx.StationID      = a.StationID
           and xx.StationSlotNo  = b.StationSlotNo
           and xx.StationSetupNo = a.StationSetupNo
         )  
    ;   
    

    • 这会插入任何新的组合,其中Part 为 NULL。

    【讨论】:

    • 谢谢,INSERT 语句看起来比我目前使用的更可靠。顺便问一下,你是用什么程序制作图形的?
    【解决方案2】:

    在 Setups 表中删除 key_station 并添加 key_position 并完全删除 Settings 表。这样,您将通过跟踪位置参考来了解给定行属于哪个站点,并将位置与其值之间的映射存储在同一个表(设置)中。

    【讨论】:

    • 谢谢 daneze。这里的问题是设置与位置无关,这就是为什么它们必须有自己的桌子。将设置视为在工作站上生产的产品。如果我切换产品,每个位置的零件都会改变,但工作站的位置仍然相同。如果我想插入新的设置(产品)怎么办?我仍然必须插入位置数的倍数。此外,如果我对 Settings 和 Setups 表进行非规范化,我在应用程序中使用的许多查询都需要有一个 DISTINCT 子句。
    猜你喜欢
    • 2017-09-18
    • 2019-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多