[英]mysql - referencing one foreign key to multiple possible primary keys
我想设置以下数据库方案:
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中是否有针对此问题的建议解决方案?
顺便说一句: me_created_by
和me_last_modified_by
的字段应引用存储一些用户数据的表。
您的案例似乎是设计模式的又一个实例,称为“通用化专门化”或“类继承的表设计”。
如果将点和线视为对象类,则它们都是某些更通用的对象类的子类。 在这种情况下,我不确定给超类起什么名字。 这是解决同一问题的先前几个问题之一。
福勒对此主题进行了广泛的治疗。 您的情况更加复杂,因为您正在处理元数据。 但这不必更改设计。 您需要第三个表,由于缺少更好的用语,因此我将其称为“项”。 键“ it_id”将被分配一个自动编号,并且每次添加点或线时都将添加一个项。 不会为两列“ po_id”和“ li_id”分配自动编号。 相反,它们将是外键,在Items表中引用“ it_id”。
这样,元数据表中对点或线的引用将成为对“项”的引用,并且视情况而定,您可以使用该信息查找有关点或线的信息。
这有多有用,取决于您要使用元数据做什么。
您的表格points
和lines
应包含metadata
的外键,而不是相反。 这样做可以避免您定义任何更复杂的表设置。 使用这种方法,单个metadata
输入可以为许多不同的点或线重复使用多次。 这甚至不是特定于MySQL的,而是通用的,标准化的数据库结构。
您可以使用触发器来执行此操作,您需要触发一个事件,该事件可以为点或线创建参考键,然后再插入基于各个表的记录
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.