从父

时间:2015-11-28 08:26:47

标签: mysql sql database-design

摘要

让我们考虑一个实体,它以树状结构递归地从它的父级继承某些属性。所以只有顶级实体(根)才设置这样的属性。

我可以想到两个设计:

A. 仅在根中设置字段。休息有NULL

B。在每个条目中设置字段。

对我来说不是很清楚,但我认为 B 方法违反了第三种正常形式。根据简单的定义A Simple Guide to Five Normal Forms,它没有(非关键字段 - 我们的属性 - 不是关于非关键字段,所以我们应该没问题)。但是我们列出了所有问题:

  • 在多个记录中重复相同的信息
  • 如果我们只更新树路径中的某些实体,我们就可以达到不一致状态。

编辑:我认为它是关于一个非关键字段:parent_id。

所以我非常感谢此处的澄清。

设计 A 的问题在于我不知道如何查询非根条目的属性值。我需要任意数量的连接,因为根不是固定的距离。例如,如何选择类型为t1的所有类别(参见下面的示例)?

如何对这样的数据库进行建模? (也许我错过了另一种选择)

实施例

嵌套类别。根类别设置type字段。休息继承自父母。

CREATE TABLE IF NOT EXISTS `mydb`.`category` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `parent_category_id` INT NULL,
  `type` ENUM('t1', 't2', 't3') NOT NULL,
  PRIMARY KEY (`id`),
  INDEX `fk_category_category_idx` (`parent_category_id` ASC) ,
  CONSTRAINT `fk_category_parent_category`
    FOREIGN KEY (`parent_category_id`)
    REFERENCES `mydb`.`category` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB

设计 A type NULL B type NOT NULL type可以是type table的FK。

A (t1) <- B <- C
X (t2) <- Y

A

+----+------+------+-----------+
| id | name | type | parent_id |
+----+------+------+-----------+
|  1 |   A  |  t1  | NULL      |
|  2 |   B  | NULL |  1        |
|  3 |   C  | NULL |  2        |
|  4 |   X  |  t2  | NULL      |
|  5 |   Y  | NULL |  4        |
+----+------+------+-----------+

+----+------+------+-----------+
| id | name | type | parent_id |
+----+------+------+-----------+
|  1 |   A  |  t1  | NULL      |
|  2 |   B  |  t1  |  1        |
|  3 |   C  |  t1  |  2        |
|  4 |   X  |  t2  | NULL      |
|  5 |   Y  |  t2  |  4        |
+----+------+------+-----------+

1 个答案:

答案 0 :(得分:0)

由于MySQL没有继承概念,因此您必须完成工作。而这项工作将花费一些东西 - 无论是在INSERT / UPDATE期间(通过传播,如你所建议的),还是在SELECT期间(通过跟随树来推断继承的内容)。

两种型号都“有效”。我们无法告诉您运行速度更快或编码更简单。