[英]How to enforce different primary keys in 2 different tables?
I may be missing something simple here but I can't seem to find an answer. 我可能在这里错过了一些简单的东西,但似乎找不到答案。
I have two entities that are inherited from another and I want to enforce that the child entities cannot have the same key as each other in the database rather than with queries. 我有两个从另一个继承的实体,我想强制要求子实体在数据库中不能具有彼此相同的键,而不能与查询具有相同的键。
For example I want credit card or paypal to have the same primary key as payment, but I only want that to be in either credit card or paypal, not both. 例如,我希望信用卡或贝宝具有与付款相同的主键,但是我只希望它既包含信用卡又包含贝宝,而不是同时存在于两者中。 So a payment is a credit card or a paypal but not both.
因此,付款是信用卡或支付宝,但不能同时使用两者。
I though it would be simple constraint, something like: 我虽然是简单的约束,但类似:
check (cc.transaction != pp.transaction)
But this doesn't seem to work in mysql workbench. 但这在mysql工作台中似乎不起作用。 Any ideas?
有任何想法吗?
I have found out that in fact checks don't work at all in mySQL, and so I need to use a trigger, but there it no way to just cancel the insert so it has to throw an error to exit instead. 我发现实际上检查在mySQL中根本不起作用,因此我需要使用触发器,但是没有办法只取消插入操作,因此必须抛出错误才能退出。 I am using mySQL Workbench which supports triggers but it will not accept any I try, eg:
我正在使用支持触发器的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;
It always says there's and error no matter what I do, including attempting to change the delimiter which also come up as an error. 无论我做什么,它总是说存在和错误,包括尝试更改定界符,这也会出现错误。 Now short of smashing the spinning jenny and using paper records and a horse and cart surely there must be a way for this to work?
现在,除了砸碎旋转的珍妮,使用纸质记录和一匹马车之外,肯定有某种方法可以起作用吗? (without changing the db schema)
(无需更改数据库架构)
You can have a super-type and sub-types arrangement in the database and it's really easy to keep them separate. 您可以在数据库中具有超类型和子类型的排列,将它们分开很容易。 Just declare the subtype as part of the super key then enforce type values in the sub-tables.
只需将子类型声明为超级键的一部分,然后在子表中强制使用类型值即可。
Whenever possible, let the constraints and checks built into the underlying system enforce whatever design you implement. 只要有可能,就让底层系统中内置的约束和检查强制实施您实现的任何设计。
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 )
);
It may seem redundant to make Super.SubType part of the PK since Super.ID is a surrogate key all by itself, but look at what you get. 将Super.SubType包含在PK中似乎是多余的,因为Super.ID本身就是代理密钥,但请看您得到了什么。
If you want to enforce this logic in the database, you might need another table. 如果要在数据库中强制执行此逻辑,则可能需要另一个表。
How about this, if I've understood your problem: 如果我了解您的问题,该怎么办:
And then make paymentType(paymentID) unique. 然后使paymentType(paymentID)唯一。
But it could be more performant to enforce the logic in the application. 但是在应用程序中执行逻辑可能会更有性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.