繁体   English   中英

如何在2个不同的表中强制使用不同的主键?

[英]How to enforce different primary keys in 2 different tables?

我可能在这里错过了一些简单的东西,但似乎找不到答案。

我有两个从另一个继承的实体,我想强制要求子实体在数据库中不能具有彼此相同的键,而不能与查询具有相同的键。

例如,我希望信用卡或贝宝具有与付款相同的主键,但是我只希望它既包含信用卡又包含贝宝,而不是同时存在于两者中。 因此,付款是信用卡或支付宝,但不能同时使用两者。

我虽然是简单的约束,但类似:

check (cc.transaction != pp.transaction)

但这在mysql工作台中似乎不起作用。 有任何想法吗?

我发现实际上检查在mySQL中根本不起作用,因此我需要使用触发器,但是没有办法只取消插入操作,因此必须抛出错误才能退出。 我正在使用支持触发器的mySQL Workbench,但不接受我尝试的任何触发器,例如:

CREATE DEFINER = CURRENT_USER TRIGGER `ddi`.`tcredit_card_BEFORE_INSERT` 
BEFORE INSERT ON `tcredit_card` FOR EACH ROW
BEGIN   
    IF EXISTS (SELECT Paypal_ID FROM tPaypal WHERE Paypal_ID = NEW.Card_ID) THEN 
    SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Cannot have multiple payments.';
    END IF;
END;

无论我做什么,它总是说存在和错误,包括尝试更改定界符,这也会出现错误。 现在,除了砸碎旋转的珍妮,使用纸质记录和一匹马车之外,肯定有某种方法可以起作用吗? (无需更改数据库架构)

您可以在数据库中具有超类型和子类型的排列,将它们分开很容易。 只需将子类型声明为超级键的一部分,然后在子表中强制使用类型值即可。

只要有可能,就让底层系统中内置的约束和检查强制实施您实现的任何设计。

create table Super(
    ID  int not null auto_increment,
    SubType char( 1 ) not null check( SubType in( 'A', 'B' ) ),
    ...
    constraint PK_Super primary key( ID, SubType )
);

create table subA(
    SubAID  int not null,
    SubType char( 1 ) not null default 'A' check( SubType = 'A' ),
    ... -- data specific to Type = A
    constraint PK_SubA primary key( SubAID, SubType ),
    constraint FK_SubA_Super foreign key( SubAID, SubType )
        references Super( ID, SubType )
);

create table subB(
    SubBID  int not null,
    SubType char( 1 ) not null default 'B' check( SubType = 'B' ),
    ... -- data specific to Type = B
    constraint PK_SubB primary key( SubBID, SubType ),
    constraint FK_SubB_Super foreign key( SubBID, SubType )
        references Super( ID, SubType )
);

将Super.SubType包含在PK中似乎是多余的,因为Super.ID本身就是代理密钥,但请看您得到了什么。

  • 超级表包含所有子类型(交易日期,类型(贷方/借方),金额等)通用的数据。
  • 在适当的约束下(您可以使用具有定义的子类型的另一个表),在Super中不能输入不是正确定义的子类型的条目。
  • 子类型值告诉您哪个子表包含特定于类型的数据。
  • 不能在超级表中未首先创建的子表中进行任何输入。 并且,一旦定义了子类型,就无法更改-A中的条目在SubType字段中只能有“ A”。 一旦建立FK连接,Super中的“ A”条目也不能更改为“ B”,反之亦然。

如果要在数据库中强制执行此逻辑,则可能需要另一个表。

如果我了解您的问题,该怎么办:

  • 付款(paymentID,日期,金额)
  • paymentType(paymentTypeID,paymentID)
  • creditCardPaymentType(creditCardPaymentTypeID,paymentTypeID,cc#,CVV2,到期)
  • paypalPaymentType(paypalPaymentTypeID,paymentTypeID,paypalname,paypalotherinfo等等)

然后使paymentType(paymentID)唯一。

但是在应用程序中执行逻辑可能会更有性能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM