关系数据库:将一个树结构集成到另一个树结构中
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_name
、middle_name
、last_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 个竞争选项之一)。就设计而言,这是最简单的选择。
实际上,您可能希望添加一列来明确说明您正在处理的记录类型(“常规类别”和“产品类别”),以便您的查询对其他人来说更加明显。
我目前正在 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_name
、middle_name
、last_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 个竞争选项之一)。就设计而言,这是最简单的选择。
实际上,您可能希望添加一列来明确说明您正在处理的记录类型(“常规类别”和“产品类别”),以便您的查询对其他人来说更加明显。