我有一个数据库结构,其中包括下表:

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
)

显然,这是一个带有复合主键的简单多对多链接表。我想要另一个表,该表引用该表但仅提供一个 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”字段,但我觉得这不是很优雅,因为会有几种不同类型的支付提供商,每个都需要不同类型的额外细节。有没有一种优雅的方式来做我想做的事?如果没有,那么实现相同目标的更好方法是什么?

最佳答案

最简单的方法是存储支付提供商 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
);

我更喜欢这种方法而不是持久化列,因为这种方法遵循 principle of least surprise 。扩展以支持两个、三个或四个支付提供商而不是一个支付提供商也更简单。

如果我是你,我会重新考虑表名。它可能应该以您为其记录数据的单一支付提供商命名。

关于sql - 使用外键,我可以在复合主键中引用固定值吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14630192/

10-10 14:25