微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – 如何在Doctrine映射中描述多列外键

我们有一个数据库模式,以简化(略微设计)的形式,如下所示:

enter image description here

用户到域的外键设置在列(domainId,groupId)上,以保证参照完整性.该结构适用于预期目的.

但是,对于与同一数据库通信的新应用程序,我现在需要为Doctrine创建映射上述结构的映射,包括两列上的外键关系.

我尝试过以下方法

但这给了我一个错误
UnitOfWork.PHP第2649行:未定义的索引:groupId

所以,我的问题是:

在Doctrine中描述多列多对一外键关系的正确方法是什么?

为了完整起见,数据库为模式创建代码,如上面的ERD中所述:

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),PRIMARY KEY (`userId`),KEY `key_users_groupId_domainId` (`groupId`,`domainId`)
) ENGINE=InnoDB;

CREATE TABLE `domains` (
  `domainId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,`someOtherData` VARCHAR(32),PRIMARY KEY (`domainId`),KEY `key_domains_groupId` (`groupId`)
) ENGINE=InnoDB;


CREATE TABLE `groups` (
  `groupId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,`someMoreData` VARCHAR(32),PRIMARY KEY (`groupId`)
) ENGINE=InnoDB;


ALTER TABLE `users`
    ADD CONSTRAINT `fk_users_domains` FOREIGN KEY (`groupId`,`domainId`) REFERENCES `domains` (`groupId`,`domainId`),ADD CONSTRAINT `fk_users_groups` FOREIGN KEY (`groupId`) REFERENCES `groups` (`groupId`);

ALTER TABLE `domains`
    ADD CONSTRAINT `fk_domains_groups` FOREIGN KEY (`groupId`) REFERENCES `groups` (`groupId`);
最佳答案
这不是你问题的绝佳答案.另外,我从未使用过Doctrine或Doctrine2.但是我花了一些时间环顾四周,并且最后得到了前三个参考文献:

Doctrine multiple composite foreign key,一个问题,虽然它没有显示XML映射,并且可能是偏离基础的,至少它似乎是关于FK中的多列.并根据答案回答关于Doctrine2的某些方面的问题.

Doctrine2 Map entities with composite foreign keys in …一个问题虽然没有多大价值,但至少可以作为一个骗子候选人加入你的问题.

XML Mapping Doctrine2 XML映射文档.搜索文本多重没有价值,但搜索复合材料时说:

For composite keys you can specify more than one id-element,however
surrogate keys are recommended for use with Doctrine 2.

这让我想到了代理商Wikipedia的定义:

The surrogate is internally generated by the system and is invisible
to the user or application.

Natural vs Surrogate.关于在两者之间进行选择的讨论.

回到你的模型,按照独立性递减的顺序列出:

CREATE TABLE `groups` (
  `groupId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,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,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,`domainId` int(10) unsigned NOT NULL,`someData` varchar(32) DEFAULT NULL,CONSTRAINT `fk_users_domains` FOREIGN KEY (`groupId`,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,(2,'sod');
select * from domains; -- AI 1 to 5 above
insert users(groupId,domainId,someData) values (1,1,'sd'); -- success
insert users(groupId,3,4,'sd'); -- Error 1452 fk failure

很明显,用户并不真正需要复合FK到域中.相反,它只需要一个列FK进入域的替代AI PK.这足以完成与你正在做的相同的效果.

与此一致,users.domainId就足够了,users.groupId引入了非规范化,后者应该被丢弃.

无论如何,希望这是有帮助的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐