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

时间:2014-12-09 19:07:37

标签: mysql sql mysql-workbench

我可能会遗漏一些简单的东西,但我似乎无法找到答案。

我有两个从另一个继承的实体,我想强制说明子实体在数据库中不能使用相同的密钥而不是查询。

例如,我希望信用卡或PayPal与付款具有相同的主键,但我只想要信用卡或PayPal,而不是两者。因此,付款是信用卡或贝宝,但不是两者。

我虽然这是简单的约束,例如:

check (cc.transaction != pp.transaction)

但这似乎不适用于mysql workbench。有什么想法吗?

我发现事实上检查在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;

无论我做什么,它总是说有错误,包括尝试更改分隔符,这也是错误。现在没有粉碎旋转的jenny,并且使用纸质记录和马车肯定必须有办法让它起作用吗? (不更改数据库架构)

2 个答案:

答案 0 :(得分:1)

您可以在数据库中安装超类型和子类型,并且很容易将它们分开。只需将子类型声明为超级键的一部分,然后在子表中强制执行类型值。

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

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中的条目只能包含“A' A'在SubType字段中。一旦建立了FK连接,也不能使用A'在Super中的条目被改为' B'反之亦然。

答案 1 :(得分:0)

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

如果我理解你的问题怎么样:

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

然后使paymentType(paymentID)唯一。

但是在应用程序中强制执行逻辑可能更有效。