1

我想设置以下数据库场景:

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

4

3 回答 3

1

您的案例似乎是称为“泛化专业化”或“类继承的表设计”的设计模式的另一个实例。

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

在数据库中扩展类

福勒对这个主题进行了广泛的处理。您的案例有一个额外的问题,因为您正在处理元数据。但这不需要改变设计。您需要第三张表,由于没有更好的术语,我将其称为“项目”。键“it_id”将被分配一个自动编号,每次添加点或线时,您都会添加一个项目。不会为“po_id”和“li_id”两列分配自动编号。相反,它们将是外键,在 Items 表中引用“it_id”。

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

这有多大帮助取决于您尝试对元数据执行的操作。

于 2012-07-16T11:09:08.407 回答
0

你的表应该包含一个外键——points而不是相反。这样做将使您免于定义任何更复杂的表格设置。使用这种方法,单个条目可以多次重复用于许多不同的点或线。这甚至不是 MySQL 特有的,而是一个通用的、规范化的数据库结构。linesmetadatametadata

于 2012-07-16T11:12:57.763 回答
-1

您可以使用触发器来执行此操作,您需要先触发一个事件,该事件可以为点或线创建引用键,然后再根据相应的表插入记录

于 2012-07-16T10:55:44.513 回答