代码之家  ›  专栏  ›  技术社区  ›  Jagmag

数据库设计-如何对具有代理键的表强制执行外键约束

  •  0
  • Jagmag  · 技术社区  · 14 年前

    我的表架构是这样的

    1主表:子句

    1. ClauseCode=nvarchar用户指定值
    2. Class=nvarchar FK到主类表

    ClauseCode+Class=此表的候选键

    2主表:GroupClause

    1. GroupClauseCode=nvarchar用户指定值
    2. 等。。。

    GroupClauseCode+Class=此表的候选键

    :此表将每个group子句映射到多个单独的子句

    1. GroupClauseID=FK到GroupClause PK

    要求: 每个Group子句只能映射到与其属于同一类的子句

    :上表中的设计并未在DB级别强制执行该要求。

    一种可能的解决方案: 表*GroupClause\u Clause\u Mapping*有列

    1. 克劳塞科
    2. 分组密码

    其中我可以创建ClauseCode+Class作为FK to子句表,也可以创建GroupClauseCode +类作为FK到GroupClause表。

    但是,如果我这样做, .

    我使用代理密钥的设计有问题吗?

    关于如何使用代理键并在DB级别强制执行约束,有什么建议吗?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Damien_The_Unbeliever    14 年前

    如果代码本身很大/笨拙,那么您可能仍然希望使用代理项(如果可用)。

    因为您只想强制类匹配,所以您的映射表可以是

    ClauseID,
    GroupClauseID,
    Class (or possibly ClassID)
    

    我的一个数据库中也有类似的设置(想想调查系统):

    CREATE TABLE [dbo].[DataItems](
        [DataItemID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
        [TypeRequired] [varchar](10) NOT NULL,
        [Name] [varchar](50) NOT NULL,
        /* Other Columns */
     CONSTRAINT [PK_DataItems] PRIMARY KEY NONCLUSTERED 
    (
        [DataItemID] ASC
    ),
     CONSTRAINT [UX_DataItems_ClientAnswerFKTarget] UNIQUE CLUSTERED 
    (
        [DataItemID] ASC,
        [TypeRequired] ASC
    ),
     CONSTRAINT [UX_DataItems_Name] UNIQUE NONCLUSTERED 
    (
        [Name] ASC
    )
    )
    
    CREATE TABLE [dbo].[ClientAnswers](
        [ClientAnswersID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
        [ClientID] [uniqueidentifier] NOT NULL,
        [DataItemID] [uniqueidentifier] NOT NULL,
        [TypeRequired] [varchar](10) NOT NULL,
        [BoolValue] [bit] NULL,
        [IntValue] [int] NULL,
        [CharValue] [varchar](6500) NULL,
        [CurrencyValue] [int] NULL,
        [DateValue] [datetime] NULL,
        /* Other Columns */
     CONSTRAINT [PK_ClientAnswers] PRIMARY KEY CLUSTERED 
    (
        [ClientID] ASC,
        [DataItemID] ASC
    )
    )
    GO
    ALTER TABLE [dbo].[ClientAnswers] ADD  CONSTRAINT [FK_ClientAnswers_DataItems] FOREIGN KEY([DataItemID],)
    REFERENCES [dbo].[DataItems] ([DataItemID])
    ON UPDATE CASCADE
    GO
    ALTER TABLE [dbo].[ClientAnswers] ADD  CONSTRAINT [FK_ClientAnswers_DataItems_TypesMatch] FOREIGN KEY([DataItemID],TypeRequired)
    REFERENCES [dbo].[DataItems] ([DataItemID],TypeRequired)
    GO
    

    然后,我更进一步,并有更多的约束,以确保类型列匹配非空*值列

        2
  •  0
  •   nvogel    14 年前

    “如果我这样做,那么代理身份密钥就没用了,我不妨扔掉它们。”

    没错。这是使用自然键而不是代理项的一个原因:当您需要使用自然键值实现一些额外的约束或逻辑时。