mysql - 如何在两个不同的表中强制执行不同的主键?

标签 mysql sql mysql-workbench

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

我有两个从另一个实体继承的实体,我想强制子实体不能在数据库中(而不是查询中)具有相同的 key 。

例如,我希望信用卡或 Paypal 具有与付款相同的主键,但我只希望它位于信用卡或 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;

无论我做什么,它总是说有错误,包括尝试更改分隔符,这也会出现错误。现在除了砸碎珍妮纺纱机、使用纸质记录和马车之外,肯定有办法让它发挥作用吗? (不更改数据库架构)

最佳答案

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

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

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 表包含所有子类型通用的数据(交易日期、类型(贷方/借方)、金额等)。
  • 通过适当的约束(您可以使用另一个已定义子类型的表),Super 中不可能存在未正确定义子类型的条目。
  • 子类型值告诉您哪个子表包含特定于类型的数据。
  • 如果子表中没有首先在父表中创建的条目,则不能在子表中创建任何条目。而且,一旦定义,子类型就无法更改 - A 中的条目只能在 SubType 字段中包含“A”。一旦建立 FK 连接,Super 中的“A”条目也不能更改为“B”,反之亦然。

关于mysql - 如何在两个不同的表中强制执行不同的主键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27386866/

相关文章:

Python:MySQLdb 库编码问题

没有数据库连接的 PHP SQL 查询生成器

php - 需要根据相对于同一列/表中其他日期的日期来过滤 MySQL 结果

mysql - 如何根据当前时间段更新MySQL中的日期?

MySQL Workbench 在 EER 建模中加入架构

mysql - 重置 Mysql workbench root 密码

mysql - 通过表进行多个联接的查询优化

sql - 数据库中已经有一个名为 '#columntable' 的对象

MySQL - 获取两天之间最接近的下一天

MySQL Workbench——第一个连接 "Internal Error"