2012-07-16 104 views
1

我想建立如下的数据库场景:MySQL的 - 引用一个外键的多种可能的主键

CREATE TABLE IF NOT EXISTS `points` (
    `po_id` INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    `po_north` INT, 
    `po_east` INT, 
    PRIMARY KEY (`po_id`), 
) ENGINE=InnoDB; 

CREATE TABLE IF NOT EXISTS `lines`(
    `li_id` INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    `li_from` INT NOT NULL, 
    `li_to` INT NOT NULL, 
    PRIMARY KEY (`li_id`), 
    FOREIGN KEY (`li_from`) REFERENCES points(`po_id`), 
    FOREIGN KEY (`li_to`) REFERENCES points(`po_id`), 
) ENGINE=InnoDB; 

现在我想建立第三个表,那疮喜欢谁创造了一些元数据或改变的一个点或线:

CREATE TABLE IF NOT EXISTS `metadata` (
    `me_type` ENUM('point','line') NOT NULL, 
    `me_type_id` INT UNSIGNED NOT NULL, 
    `me_permissions` VARCHAR(255) NOT NULL, 
    `me_created_by` INT UNSIGNED NOT NULL, 
    `me_created_on` DATETIME NOT NULL, 
    `me_last_modified_by` INT UNSIGNED NOT NULL, 
    `me_last_modified_by` DATETIME NOT NULL, 
) ENGINE=InnoDB; 

我的第一种方法是设置一个ENUM与两种类型(点线)。但问题仍然是,我无法正确地将外键引用到其中一个表。 MySQL中有没有推荐的解决方案?

BTW: me_created_byme_last_modified_by的字段应引用存储一些用户数据的表。

+0

您的表中的点和线可以引用元数据吗,即将外键'metadata_id'放在这两个表中? – 2012-07-16 11:06:10

回答

0

您的表格pointslines应该包含metadata的外键 - 而不是相反。这样做可以避免您定义更复杂的表格设置。使用这种方法,单个metadata -entry可以多次重复使用多个不同的点或线。这甚至不是MySQL特有的,但是是一个通用的,规范化的数据库结构。

+0

啊,我没那么想。这似乎是解决我的问题的最简单的解决方案。谢谢 – mgr 2012-07-16 12:15:07

+0

@mgr这是关系数据库中的“默认”方式。你应该阅读[数据库规范化](http://en.wikipedia.org/wiki/Database_normalization)。 – feeela 2012-07-16 12:25:05

-1

您可以使用触发器做到这一点,你需要根据各自的表

你插入一条记录之前触发可以为任何点或线创建基准关键事件
+0

我想mgr问的是如何构建数据库模式,以便表可以在一个表或另一个不同的表中有一个主键字段的外键。或者你的意思是使用触发器来检查引用完整性而不是约束? – 2012-07-16 10:59:06

1

你的情况似乎是另一种情况被称为“泛化专业化”的设计模式或者“类继承的表设计”。

如果将点和线想象为对象类,它们都是一些更一般对象类的子类。在这种情况下,我不确定给这个超类命名的名字。以下是几个解决同一问题的问题之一。

Extending classes in the database

福勒给出的主题的广泛的治疗。你的情况有一个额外的皱纹,因为你正在处理元数据。但是这并不需要改变设计。你需要第三个表格,我将其称为“项目”,因为缺乏更好的术语。关键字“it_id”将被分配一个自动编号,并且每次添加一个点或一行时,都会添加一个项目。两列“po_id”和“li_id”不会被分配一个自动编号。相反,它们将是外键,在Items表中引用“it_id”。

对元数据表中的点或线的引用将是对“条目”的引用,您可以根据具体情况使用该信息来查找有关点或线的信息。

这是否有帮助取决于您想要对元数据进行的操作。

+0

这个解决方案对我来说很有意思,我会按照你的建议阅读一些给定的文章。谢谢 – mgr 2012-07-16 12:18:17

相关问题