4

次のテーブルを含むデータベース構造があります。

CREATE TABLE dbo.PaymentProvidersForEntities
(
    PaymentProviderId SMALLINT NOT NULL,
    EntityId BIGINT NOT NULL, 
    CONSTRAINT PK_PaymentProvidersForEntities 
        PRIMARY KEY (PaymentProviderId, EntityId), 
    CONSTRAINT FK_PaymentProvidersForEntities_PaymentProviders 
        FOREIGN KEY (PaymentProviderId) 
        REFERENCES PaymentProviders(PaymentProviderId) 
        ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FK_PaymentProvidersForEntities_Entities 
        FOREIGN KEY (EntityId) 
        REFERENCES Entities(EntityId) 
        ON DELETE CASCADE ON UPDATE CASCADE
)

明らかに、これは複合主キーを持つ単純な多対多のリンクテーブルです。そのテーブルを参照するが、1つのPaymentProviderのみのデータを提供する別のテーブルが必要です(つまり、PaymentProviderId =固定値)。何かのようなもの:

CREATE TABLE dbo.SpecificPaymentProviderExtraDetails
(
    EntityId BIGINT NOT NULL,
    ExtraDetails NVARCHAR(MAX) NOT NULL,
    CONSTRAINT PK_PaymentProviderExtraDetails 
        PRIMARY KEY (EntityId), 
    CONSTRAINT FK_PaymentProviderExtraDetails_PaymentProvidersForEntities 
        FOREIGN KEY (EntityId, 1) 
        REFERENCES PaymentProvidersForEntities(EntityId, PaymentProviderId) 
        ON DELETE CASCADE ON UPDATE CASCADE
)

明らかに、PaymentProvidersForEntitiesテーブルにnull許容の「ExtraDetails」フィールドを追加することもできますが、いくつかの異なるタイプの支払いプロバイダーがあり、それぞれが異なるタイプの追加の詳細を必要とするため、それほどエレガントではありません。私がやりたいことをするエレガントな方法はありますか?そうでない場合、同じことを達成するためのより良い方法は何でしょうか?

4

3 に答える 3

2

最も簡単な方法は、支払いプロバイダー ID を保存し、CHECK() 制約を使用して、それが必要なものであることを確認することです。支払いプロバイダー ID を常に 13 にしたいとします。

CREATE TABLE dbo.PaymentProviderExtraDetails
(
    PaymentProviderID SMALLINT NOT NULL DEFAULT 13 CHECK(PaymentProviderID = 13),
    EntityId BIGINT NOT NULL,
    ExtraDetails NVARCHAR(MAX) NOT NULL,
    CONSTRAINT PK_PaymentProviderExtraDetails 
        PRIMARY KEY (PaymentProviderID, EntityId), 
    CONSTRAINT FK_PaymentProviderExtraDetails_PaymentProvidersForEntities 
        FOREIGN KEY (PaymentProviderID, EntityID) 
        REFERENCES PaymentProvidersForEntities(PaymentProviderId, EntityId) 
        ON DELETE CASCADE ON UPDATE CASCADE
);

このアプローチは最小の驚きの原則に従っているため、永続化された列よりもこのアプローチを好みます。また、1 つではなく、2 つ、3 つ、または 4 つの支払いプロバイダーをサポートするように拡張する方がはるかに簡単です。

私があなたなら、テーブル名を再考します。おそらくデータを記録している単一の支払いプロバイダーにちなんで名付けられるべきです.

于 2013-01-31T17:20:51.847 に答える
1

永続化された計算列を参照列リストに追加できます。

CREATE TABLE dbo.p(i1 INT, i2 INT, CONSTRAINT p_pk PRIMARY KEY CLUSTERED (i1,i2));
CREATE TABLE dbo.c(id INT PRIMARY KEY CLUSTERED,i1 INT, i2 AS 1 PERSISTED, CONSTRAINT c_fk FOREIGN KEY (i1,i2) REFERENCES dbo.p(i1,i2));
INSERT INTO dbo.p(i1,i2)VALUES(42,1);
INSERT INTO dbo.c(id,i1)VALUES(111,42);
于 2013-01-31T16:56:15.863 に答える
-1

2 番目のテーブルの主キーが代理キーであり、必要な複合キーの部分に外部キーを作成すると、それが実行されます。

たとえば、疑似SQL

foo
bar int 主キー
foobar int 主キー

テスト
testFoo int主キー
foobar int foriengkey

必要な項目のみをテストに入れるようにしてください。本当に安全にしたい場合は、必要なfoobar値のみが含まれていることを確認することに制約を加えることができます

于 2013-01-31T16:50:43.720 に答える