在SQL中表示DAG的标准方法是传递闭包表:
CREATE TABLE Foo (Id int primary key identity, Name nvachar(30))
CREATE TABLE Foo_Foo
(ParentId int not null
,ChildId int not null
,Distance int not null)
因此,插入的每个父子关系都需要使用距离+ 1复制所有父级的Foo_Foo条目:
INSERT INTO Foo (Name) VALUES ('Some Name')
DECLARE @somename int = @@IDENTITY
-- DAG: Some Name -> Some other name
INSERT INFO Foo (Name) VALUES ('Some other name')
DECLARE @someother int = @@IDENTITY
INSERT INTO Foo_Foo (ParentId, ChildId, Distance)
VALUES (@somename, @someother, 0)
-- DAG: Some Name -> Some other name -> Some final name
INSERT INTO Foo (Name) Values ('Some final name')
INSERT INTO Foo_Foo (ParentId, ChildId, Distance)
VALUES (@someother, @@IDENTITY, 0)
INSERT INTO Foo_Foo (ParentId, ChildId, Distance)
SELECT ParentId, @@IDENTITY, Distance + 1 FROM Foo_Foo
WHERE ChildId = @someother
-- DAG: Some Name -> Some other name -> Some final name
-- \_____________________/
INSERT INTO Foo_Foo (ParentId, ChildId, Distance)
VALUES (@someother, @@IDENTITY, 0)
问题是Foo_Foo表随着DAG路径深度的阶乘乘以唯一路径的数量而增长,即。从DAG的根顶点V到距离D处插入的每个Foo至少需要(来自V的D的唯一路径)*(D-1)*(D-2)* ... Foo_Foo表中的条目。我可以进一步规范化上面的内容,以获得空间复杂性(距离V的距离为D的##顶点)*(D-1)!,但这样我就可以得到它。
这对于代表可以任意长度增长的DAG显然是不可行的。递归查询可能是最好的解决方案,但并不是所有地方都完全支持。树有一些聪明的解决方案,但我无法为DAG找到一个好的解决方案。有没有使用SQL表和非递归查询的聪明的DAG解决方案?