0

私のテーブルスキーマは次のようなものです

1.マスターテーブル:条項

  1. ClauseID =サロゲートpk(ID)
  2. ClauseCode=nvarcharユーザー指定値
  3. Class =nvarcharFKからマスタークラステーブルへ
  4. 等...

ClauseCode +Class=このテーブルの候補キー

2.マスターテーブル:GroupClause

  1. GroupClauseID =サロゲートpk(ID)
  2. GroupClauseCode=nvarcharユーザー指定値
  3. Class =nvarcharFKからマスタークラステーブルなどへ。

GroupClauseCode +Class=このテーブルの候補キー

3.トランザクション/マッピングテーブル::GroupClause_Clause_Mapping:このテーブルは、各グループ句を複数の個別の句にマッピングします

  1. GroupClauseID=FKからGroupClausePK
  2. ClauseID=FKからClausePK
  3. 等...

要件:各Group句は、それ自体と同じクラスに属する句にのみマップできます。

問題:上記のテーブルデザインは、DBレベルでその要件を強制しません。

考えられる解決策の1つ:テーブル*GroupClause_Clause_Mapping*には列があります

  1. ClauseCode
  2. GroupClauseCode
  3. クラス

ここで、ClauseCode + Class as FKtoclauseテーブルとGroupClauseCode+Class as FKtoGroupClauseテーブルを作成できます。

ただし、この方法で行うと、代理IDキーは役に立たなくなり、それらを削除した方がよい場合があります。

代理キーを使用したデザインに問題はありますか?

代理キーを使用し、DBレベルで制約を適用する方法に関する提案はありますか?

4

2 に答える 2

1

コード自体が大きくて扱いにくい場合でも、可能な場合はサロゲートを使用することをお勧めします。

クラスの一致のみを強制したいので、マッピングテーブルは次のようになります。

ClauseID,
GroupClauseID,
Class (or possibly ClassID)

マスターテーブルには、PK(ClauseID)と一意性制約(ClauseID、Class)があります。次に、FK(ClauseID、Class)だけにするか、マッピングテーブルと各マスターテーブルの間に2つのFKを置くかを決定できます(事実上、一方のFKは外部キー参照であり、もう一方はそこにあります)ルールを適用します)。

私のデータベースの1つに同様の設定があります(調査システムを考えてください):

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

次に、さらに進んで、type列がnull以外の*Value列と一致することを確認するためのより多くの制約があります

于 2010-09-30T07:02:22.030 に答える
0

「このようにすると、代理IDキーは役に立たなくなり、削除したほうがよいでしょう。」

そのとおりです。これが、サロゲートの代わりに自然キーを使用する理由の1つです。自然キーの値を使用して、追加の制約またはロジックを実装する必要がある場合です。

他のテーブルからサロゲートを参照して、サロゲートキーが引き続き役立つようにすることもできます。サロゲートをまったく使用しない場合は、ドロップするのが最善です。サロゲートキーは通常、インデックスが付けられているため、通常、特定のオーバーヘッドを意味します。これにより、挿入のパフォーマンスが低下する可能性があります。

于 2010-09-30T06:48:44.603 に答える