外键约束(复杂?)

时间:2010-02-04 20:30:34

标签: mysql foreign-keys constraints

我有一个管理网站虚拟下载文件夹的表。

CREATE TABLE `folder` (
  # id = PK
  `id` int(10) unsigned NOT NULL auto_increment,
  # folderId = self referencing FK to id
  `folderId` int(10) unsigned default NULL,
  # siteId = FK to id in site table
  `siteId` int(10) unsigned NOT NULL
)

理想情况下,我喜欢siteId引用表id中的site,但也有一个复合FK folderId, siteId可自行引用表id, siteId {1}}。

我想要的原因是我想保证子文件夹始终属于与父文件夹相同的站点。

这样的事情可能吗?如果是这样,怎么样?如果没有,你有什么其他建议我怎么能保证这种状态?

修改
对不起,我之前应该提到过:我知道InnoDB,事实上,我已经使用它了(连同外键)。但问题是,我怎样才能保证这两件事:

  • folder中的记录必须引用有效folder site
  • siteId中的记录也必须与父记录相同folder(当然,仅当它是孩子时)

到目前为止我试过这个:

siteId

所以最后一个不起作用(当然?)因为外键( # this one should guarantee folder belongs to # a valid site (this one works of course) CONSTRAINT `FK_folder_site_1` FOREIGN KEY (`siteId`) REFERENCES `site` (`id`) ON UPDATE CASCADE, # this one should guarantee child folder belongs to # the same site as parent folder (doesn't work) CONSTRAINT `FK_folder_folder_1` FOREIGN KEY `FK_folder_folder_1` (`folderId`, `siteId`) REFERENCES `folder` (`id`, `siteId`) ON DELETE CASCADE ON UPDATE CASCADE )不能引用两个不同的字段似乎是合乎逻辑的。你有什么建议让我提出的约束有效?

2 个答案:

答案 0 :(得分:0)

InnoDB存储引擎支持自引用外键,您可以使用它们来模拟分层结构。要声明密钥,您可以在CREATE TABLE语句中执行类似的操作:

FOREIGN KEY (`folderId`,`siteId`) REFERENCES `folder` (`Id`, `siteId`)

要记住的一件重要事情是,此密钥应为NULL - 能够,因此您可以指出哪些记录是树的根。

答案 1 :(得分:0)

如果您使用InnoDB存储引擎

,则可以执行此操作
CREATE TABLE `folder` (
  # id = PK
  `id` int(10) unsigned NOT NULL auto_increment,
  # folderId = self referencing FK to id
  `folderId` int(10) unsigned default NULL,
  # siteId = FK to id in site table
  `siteId` int(10) unsigned NOT NULL,
  FOREIGN KEY (folder_id, site_id) REFERENCES folder(id, site_id)
) ENGINE=INNODB;

它没有测试它,但它应该工作。请参阅FOREIGN KEY Constraints

如果您想/必须使用MyISAM,当然您可以使用与“普通”外键约束相同的方式执行此操作。