这对于你的问题来说并不是一个很好的答案。另外,我从未使用过 Doctrine 或 Doctrine2。但我花了一些时间环顾四周,最后几乎得到了前三个参考文献:
学说多重复合外键 https://stackoverflow.com/q/15763093,一个问题,虽然它没有显示 XML 映射,并且可能是偏离基础的,但至少它看起来是关于 FK 中的多列。并回答根据答案被忽略的 Doctrine2 的某些方面。
Doctrine2 使用复合外键映射实体... https://stackoverflow.com/q/19008582这个问题没有太多价值,但至少可以作为一个受骗候选人纳入您的问题中。
XML映射 http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/xml-mapping.htmlDoctrine2 XML 映射文档。它对文本搜索没有任何价值multi
但搜索composite
说:
对于复合键,您可以指定多个 id 元素,但是
建议将代理键与原则 2 一起使用。
这让我想到了这一点维基百科 https://en.wikipedia.org/wiki/Surrogate_key代理的定义指出:
代理是系统内部生成的,是不可见的
给用户或应用程序。
And 自然与代孕 http://www.databasejournal.com/features/mssql/article.php/3922066/SQL-Server-Natural-Key-Verses-Surrogate-Key.htm。讨论两者之间的选择。
回到您的模型,按独立性降序排列:
CREATE TABLE `groups` (
`groupId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`someMoreData` VARCHAR(32),
PRIMARY KEY (`groupId`)
) ENGINE=InnoDB;
CREATE TABLE `domains` (
`domainId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`groupId` int(10) unsigned NOT NULL,
`someOtherData` varchar(32) DEFAULT NULL,
PRIMARY KEY (`domainId`),
KEY `key_domains_groupId` (`groupId`),
CONSTRAINT `fk_domains_groups` FOREIGN KEY (`groupId`) REFERENCES `groups` (`groupId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `users` (
`userId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`groupId` int(10) unsigned NOT NULL,
`domainId` int(10) unsigned NOT NULL,
`someData` varchar(32) DEFAULT NULL,
PRIMARY KEY (`userId`),
KEY `key_users_groupId_domainId` (`groupId`,`domainId`),
CONSTRAINT `fk_users_domains` FOREIGN KEY (`groupId`, `domainId`) REFERENCES `domains` (`groupId`, `domainId`),
CONSTRAINT `fk_users_groups` FOREIGN KEY (`groupId`) REFERENCES `groups` (`groupId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
一些临时工作:
truncate table groups; -- disallowed
delete from groups;
alter table groups auto_increment 1; -- reset, after running delete from.
insert groups(someMoreData) values ('group0001'),('group0002');
select * from groups;
insert domains(groupId,someOtherData) values
(1,'sod'),(1,'sod'),(1,'sod'),
(2,'sod'),(2,'sod');
select * from domains; -- AI 1 to 5 above
insert users(groupId,domainId,someData) values (1,1,'sd'); -- success
insert users(groupId,domainId,someData) values (1,3,'sd'); -- success
insert users(groupId,domainId,someData) values (1,4,'sd'); -- Error 1452 fk failure
很明显的是users
并不真正需要复合 FK 到domains
。相反,它只需要一个单列 FK 进入替代 AI PKdomains
。这足以达到与您正在做的相同的效果。
与此相一致,users.domainId
就足够了,并且users.groupId
引入了非规范化,后者应该被丢弃。
无论如何,希望这对您有所帮助。