代码之家  ›  专栏  ›  技术社区  ›  Mark S. Rasmussen

外键引用复合表

  •  2
  • Mark S. Rasmussen  · 技术社区  · 17 年前

    我有一个表结构,我不确定如何创建最佳方式。

    基本上我有两个表,tblSystemItems和tblClientItems。我有第三个表,其中有一列引用“Item”。问题是,此列需要引用系统项或客户机项—不管是哪一个。系统项的键在1..2^31范围内,而客户端项的键在-1..-2^31范围内,因此不会发生任何冲突。

    因此,从最佳角度来说,我希望将外键引用作为视图的结果,因为视图将始终是两个表的并集,同时保持ID的唯一性。但我不能这样做,因为我不能引用视图。

    现在,我可以放下外键,一切都好了。然而,我真的希望有一些引用检查和级联的delete/setnull功能。除了触发器,还有什么方法可以做到这一点吗?

    6 回复  |  直到 17 年前
        1
  •  1
  •   Mark S. Rasmussen    17 年前

    对不起,我的回答太晚了,我被一个严重的周末炎所困扰。

    至于使用第三个表来包含来自客户端和系统表的PK,我不喜欢这样,因为这会使同步过于复杂,并且仍然需要我的应用程序知道第三个表。

    出现的另一个问题是,我有第三个表需要引用一个项——不管是系统还是客户端,都无所谓。将表分开基本上意味着我需要有两个列,一个ClientItemID和一个SystemItemID,每个列对其每个表都有一个可为空的约束,这相当难看。

    我最终只创建了一个表,即Items。Items有一个名为“SystemItem”的bit列,它定义了显而易见的。在我的开发/系统数据库中,我将PK作为int标识(1,1)。在客户端数据库中创建表后,标识键更改为(-1,-1)。这意味着客户端项目处于负值,而系统项目处于正值。

    对于同步,我基本上忽略了(SystemItem=1)的任何内容,而使用IDENTITY INSERT ON同步其余内容。因此,我能够在完全忽略客户端项和避免冲突的同时进行同步。我还能够引用一个“Items”表,该表包含客户端和系统项。要记住的唯一一件事是修复标准的聚集键,使其下降,以避免在客户端插入新项目时出现各种页面重组(客户端更新与系统更新的比例为99%/1%)。

        2
  •  0
  •   Miguel Ping    17 年前

    您可以为引用项的表创建一个唯一id(db generated-sequence、autoinc等),并创建两个附加列( tblClientItemsFk )其中您分别引用系统项和客户端项- 一些 可空 .

    如果您使用的是ORM,您甚至可以仅基于列信息轻松区分客户机项和系统项(这样您就不需要使用否定标识符来防止ID重叠)。

    再加上一点背景/背景,可能更容易确定最佳解决方案。

        3
  •  0
  •   Vincent Ramdhanie    17 年前

    您可能需要一个表,比如tblItems,它只存储两个表的所有主键。插入项目需要两个步骤,以确保在将项目输入tblSystemItems表时,PK已输入tblItems表。

    然后,第三个表有一个FK到tblItems。在某种程度上,tblItems是其他两个items表的父级。要查询项,需要在tblItems、tblSystemItems和tblClientItems之间创建联接。

    [编辑下面的评论]如果tblSystemItems和tblClientItems控制他们自己的PK,那么您仍然可以允许他们。您可能会先插入tblSystemItems,然后再插入tblItems。当您使用Hibernate之类的工具实现继承结构时,您将得到如下结果。

        4
  •  0
  •   Charles Bretana    17 年前

    然后在引用项的第三个表中,只需让它的FK约束引用这个额外(项)表中的itemId。。。

    如果使用存储过程来实现插入,只需让插入项的存储过程先将新记录插入项表,然后使用该表中自动生成的PK值将实际数据记录作为同一存储过程调用的一部分插入SystemItems或ClientItems(取决于它是哪一个),使用系统插入到Items表ItemId列中的自动生成(标识)值。

    这称为“子类化”

        5
  •  0
  •   Phil_Factor Phil_Factor    17 年前

        6
  •  0
  •   Mike Shepard    17 年前