我可能在这里遗漏了一些简单的东西,但我似乎找不到答案。
我有两个从另一个实体继承的实体,我想强制子实体不能在数据库中(而不是查询中)具有相同的 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/