假设我有一个ETL流,如下所示:
source1 ---> do_filter ---> join -----> output
^
|
source2 ---------------------
表示这一点的正确数据结构是什么?我的想法是有一个from: to[]
结构。
从注释中可以看出,您想使用 JSON 格式来存储和加载这些图形,因此不使用太多空间的简单数据结构应该没问题。邻接列表(您描述为from: to[]
(是一种很好的通用图形数据结构,可能适合您的用例。
邻接列表可以通过多种方式实现。最简单的方法是作为字典将每个节点映射到其邻居列表:
{
"source1": ["do_filter"],
"do_filter": ["join"],
"join": ["output"],
"output": [],
"source2": ["join"]
}
如果您只需要存储节点的名称和图形的拓扑,这可能没问题。但是,对于具有许多边的大型图形,JSON 将占用比必要更多的空间,因为每个节点的名称都作为该节点的每个边的字符串写入。如果需要更紧凑的表示形式,可以使用数字 ID 来引用节点:
{
"nodes": ["source1", "do_filter", "join", "output", "source2"],
"edges": [[1], [2], [3], [], [2]]
}
这里source1
是节点0,do_filter
是节点1,依此类推,基于它们在nodes
中的索引;所以从source1
到do_filter
的边由包含1
数的edges[0]
表示。类似地,edges[3]
为空,表示nodes[3]
,即output
没有到其他节点的边。
如果您需要存储有关每个节点的更多信息(例如用于绘制它的 x,y 坐标、颜色等(,另一种选择是使每个节点成为对象。这仍然是一个邻接列表,因为它通过将每个节点与其邻居列表相关联来表示图形的拓扑:
[
{ "name": "source1", "colour": "green", "edges": [1] },
{ "name": "do_filter", "colour": "red", "edges": [2] },
{ "name": "join", "colour": "orange", "edges": [3] },
{ "name": "output", "colour": "blue", "edges": [] },
{ "name": "source2", "colour": "black", "edges": [2] }
]