繁体   English   中英

mysql-将一个外键引用到多个可能的主键

[英]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_byme_last_modified_by的字段应引用存储一些用户数据的表。

您的案例似乎是设计模式的又一个实例,称为“通用化专门化”或“类继承的表设计”。

如果将点和线视为对象类,则它们都是某些更通用的对象类的子类。 在这种情况下,我不确定给超类起什么名字。 这是解决同一问题的先前几个问题之一。

扩展数据库中的类

福勒对此主题进行了广泛的治疗。 您的情况更加复杂,因为您正在处理元数据。 但这不必更改设计。 您需要第三个表,由于缺少更好的用语,因此我将其称为“项”。 键“ it_id”将被分配一个自动编号,并且每次添加点或线时都将添加一个项。 不会为两列“ po_id”和“ li_id”分配自动编号。 相反,它们将是外键,在Items表中引用“ it_id”。

这样,元数据表中对点或线的引用将成为对“项”的引用,并且视情况而定,您可以使用该信息查找有关点或线的信息。

这有多有用,取决于您要使用元数据做什么。

您的表格pointslines应包含metadata的外键,而不是相反。 这样做可以避免您定义任何更复杂的表设置。 使用这种方法,单个metadata输入可以为许多不同的点或线重复使用多次。 这甚至不是特定于MySQL的,而是通用的,标准化的数据库结构。

您可以使用触发器来执行此操作,您需要触发一个事件,该事件可以为点或线创建参考键,然后再插入基于各个表的记录

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM