关系数据库:将一个树结构集成到另一个树结构中

Relational databases: Integrate one tree structure into another

我目前正在 MySQL 中设计关系数据库 table 以处理多个类别,稍后在客户端的树结构中表示它们并对其进行过滤。这是该结构的图片:

所以我们有一个默认设置的根元素。之后我们可以添加 children 到它(一级)。到目前为止,最简单情况下的 table 结构可以这样定义:

| id |     name     | parent_id |
--------------------------------
  1   All Categories    NULL
  2      History         1

但是,我有一个要求,我需要在 table 中包含另一个树结构类型(Products)(对应的 API 是可用的)。来自其他 table 的记录有自己的 ID 类型 (UUID)。基本上我需要在我的 table 中摄取它们。可能的结构如下所示:

| id |   UUID     |        name       |        parent_id   |
----------------------------------------------------------
  1      NULL        All Categories                NULL
  2      NULL          History                      1
  3      NULL          Products                     1
  4   CN1001231232  Catalog electricity             3
  5   CN1001231242  Catalog basic components        4
  6      NULL          Shipping                     1 

我是关系数据库的新手,但是 UUID 的所有这些可能的 NULL 值都表明(至少对我而言)是数据库的糟糕设计 table。有没有办法避免这种情况,或者有更好的方法来避免这种“摄入”?

如果您为用户设置了一个 table,包含 first_namemiddle_namelast_name 列,但随后用户注册并说他们没有中间名,您可以只为该用户的 middle_name 列存储 NULL。这有什么不好的设计?

NULL 在给定行上的属性未知或不适用时使用。这似乎适合您描述的情况,即当不是来自外部来源的记录没有 UUID,也不需要 UUID。

也就是说,一些计算机科学理论家坚持 NULL 永远不合适。关于 SQL 是否应该有 NULL 的争论已经存在了几十年。

另一种方法是创建第二个 table,在其中仅存储 UUID 和对第一个 table 中的实体的引用。然后就不要为其他 id 存储行。

| id |   UUID     |
-------------------
  4   CN1001231232
  5   CN1001231242

并且不要在您的第一个 table 中存储 UUID 列。这消除了 NULL,但这意味着只要您想使用 UUID 查询实体,就需要对两个 table 进行 JOIN。

首先确保您确实必须将这些组合在同一个 table 中。产品类别?如果它们 类别并且像类别一样使用,那么将它们放在相同的 table 是有意义的,但如果它们 具有 类别那么它们应该分开存放并给定一个 category/parent id。

如果您确定将它们存储在同一个 table 中是合适的,那么只需调整一下就可以了。对于 UUID,您可以使用单独的命名方案,使其可以与这些条目的 id 互换,并避免与其他 uuid 冲突。例如:

| id |   UUID     |        name       |        parent_id   |
----------------------------------------------------------
  1   CAT000000001   All Categories                NULL
  2   CAT000000002     History                      1
  3   CAT000000003     Products                     1
  4   CN1001231232  Catalog electricity             3
  5   CN1001231242  Catalog basic components        4
  6   CAT000000006     Shipping                     1 

您的要求结合了关系数据库开箱即用的两件事:modelling hierarchies, and inheritance(在面向对象的意义上)。

您的设计使用“单一 table 继承”模型(3 个竞争选项之一)。就设计而言,这是最简单的选择。

实际上,您可能希望添加一列来明确说明您正在处理的记录类型(“常规类别”和“产品类别”),以便您的查询对其他人来说更加明显。