我想创建一个类别的树结构,需要找到一种适当的方法将其存储到数据库中。考虑下面的动物树,它很准确地描述了它的外观:
我现在的问题是,将那些表链接在同一张表中是否是一个好主意。 SQLite不允许我将FOREIGN KEY约束添加到同一表中的值,因此我必须手动确保不创建不一致。这是我目前打算拥有的:
id | parent | name
---+--------+--------
1 | null | Animal
2 | 1 | Reptile
3 | 2 | Lizard
4 | 1 | Mammal
5 | 4 | Equine
6 | 4 | Bovine
parent
引用同一表中的id
,一直向上直到找到null
,它是根。这是一个不好的模式吗?如果是这样,将树结构放入关系数据库的常见替代方法是什么?
答案 0 :(得分:2)
如果您的SQLite版本支持递归CTE,则这是一种选择:
WITH RECURSIVE cte (n) AS (
SELECT id FROM yourTable WHERE parent IS NULL
UNION ALL
SELECT t1.id
FROM yourTable t1
INNER JOIN cte t2
ON t1.parent = t2.n AND t1.name NOT LIKE '%Lizard%'
)
SELECT *
FROM yourTable
WHERE id IN cte;
这未经测试,但是只要我们找到与t1.name
表达式中的名称匹配的记录,就可以对上述CTE的递归部分中的LIKE
进行检查(希望如此)。在搜索Lizard
的情况下,递归应在蜥蜴上方停止一级,这意味着应返回层次结构中位于其上方的每个记录。