在 Neo4j 中,当粒度级别可以不受限制时,应该使用什么级别的特异性?
In Neo4j, what level of specificity should be used when granularity level can be unlimited?
在使用图形数据库时,最让我头疼的事情是选择粒度级别。假设我有一张图表,显示一周中特定几天发生的事情:垃圾日、炸玉米饼星期二、BYOB 星期五等。
- 我可以让每一天成为一个节点(周一,周二,周三,...),这样查询特定日期就很快了。
- 我可以创建一个名为 Day 的节点,并在 属性 名称中添加星期几。这样,在图表中显示所有日期很容易查询。
我自己想,让节点非常具体是不好的,因为没有粒度限制。例如星期六早上、晚上和晚上,或者更糟的是,每天每小时一个新节点。我还可以通过说星期六节点由 "evening" 边链接到垃圾日节点来使边成为粒度的组成部分。
例如,我时常遇到类似的问题;我应该根据一个人的全名创建一个新节点,还是一个名为 "Person" 和 属性 "name" 的节点。然后我根据方便性将节点设为具体或通用,但我觉得可能缺少一些最佳实践或更高级别的原则。我不清楚如何判断哪种方式更好。
首先,我建议您考虑一下您希望如何处理您的数据。您不只是将图形数据库用于存储数据,您还想用它做一些事情。所以你可能有一个特定的用例,比如寻路。在这种情况下,没有那么多选项,但仍然有不同的数据建模方法。在这种情况下,我会查看已经提供的算法,以及它们是否能够处理我想用它做的事情。所以假设我想使用 apoc.algo.aStar 因为它能够做我想做的事情。在这一点上,我限制了自己,因为 aStar 只能处理关系上的权重,而算法想要在节点上获得坐标。这可能也是您想到的第一个模式,但我认为您已经理解了它背后的想法。如果你的问题没有算法,你就要自己做一个算法。查看您拥有的选项,您通常会局限于某种数据建模方式。
正如您已经说过的,您处理数据的方式也会影响您查询 某些内容的速度。例如,您对地图进行建模,因此您有一个点 A 和一个点 B,您希望从 A 到 B 再从 B 到 A。neo4j 中的问题是您没有双向边。所以你可能会考虑添加 2 条边,从 A 到 B 和从 B 到 A。不要这样做!性能将因遍历而受到很大影响。
- I can make each day a node (Mon, Tue, Wed, ...), that way, querying for specific days is fast.
- I can make a node called Day, and add the property name with the day of the week. That way, showing all days in a graph is easy to
query for.
问问自己为什么要拥有这个数据库以及要用它做什么,不要忘记索引。您仍然可以创建一个索引来恢复一些性能,这在第一个示例中仍然存在。还要避免添加冗余数据。例如连接到所有工作日的节点日。每个人都知道星期五是一天。只有在您从中受益时才考虑这样做。在对一些图形进行建模并为图形编写自己的算法之后,您会对它有一个感觉。在某个时候,您将知道如何为特定用例设计最适合的图表。 经验是设计图形的关键,了解您已经可以使用的算法的局限性以及您可以自己做的事情。希望对您有所帮助。
您的数据模型的粒度级别应由您的查询要求驱动,而不是相反。即:在对数据库建模时,您应该问自己:"what kind of query I will do over my data?"。根据这个问题的答案,您将获得一个良好的起点,以创建具有适当粒度级别的良好模型。
在 Rik Van Bruggen 的书 Learning Neo4j 中(您可以在 this link 下载),作者谈到设计图数据库以提高查询能力:
Like with any database management system, but perhaps even more so for
a graph database management system such as Neo4j, your queries will
drive your model. What we mean with this is that, exactly like it was
with any type of database that you may have used in the past or would
still be using today, you will need to make specific design decisions
based on specific trade-offs. Therefore, it follows that there is no
one perfect way to model in a graph database such as Neo4j. It
will all depend on the questions that you want to ask of the data, and
this will drive your design and your model.
所以,基于此,你的问题"what level of specificity should be used when granularity level can be unlimited?"的答案是:这取决于你的查询需求。首先考虑您将执行的查询,然后再考虑数据模型。
我的建议是:一开始就让你的模型尽可能简单,然后在需要的时候逐渐改变。
在使用图形数据库时,最让我头疼的事情是选择粒度级别。假设我有一张图表,显示一周中特定几天发生的事情:垃圾日、炸玉米饼星期二、BYOB 星期五等。
- 我可以让每一天成为一个节点(周一,周二,周三,...),这样查询特定日期就很快了。
- 我可以创建一个名为 Day 的节点,并在 属性 名称中添加星期几。这样,在图表中显示所有日期很容易查询。
我自己想,让节点非常具体是不好的,因为没有粒度限制。例如星期六早上、晚上和晚上,或者更糟的是,每天每小时一个新节点。我还可以通过说星期六节点由 "evening" 边链接到垃圾日节点来使边成为粒度的组成部分。
例如,我时常遇到类似的问题;我应该根据一个人的全名创建一个新节点,还是一个名为 "Person" 和 属性 "name" 的节点。然后我根据方便性将节点设为具体或通用,但我觉得可能缺少一些最佳实践或更高级别的原则。我不清楚如何判断哪种方式更好。
首先,我建议您考虑一下您希望如何处理您的数据。您不只是将图形数据库用于存储数据,您还想用它做一些事情。所以你可能有一个特定的用例,比如寻路。在这种情况下,没有那么多选项,但仍然有不同的数据建模方法。在这种情况下,我会查看已经提供的算法,以及它们是否能够处理我想用它做的事情。所以假设我想使用 apoc.algo.aStar 因为它能够做我想做的事情。在这一点上,我限制了自己,因为 aStar 只能处理关系上的权重,而算法想要在节点上获得坐标。这可能也是您想到的第一个模式,但我认为您已经理解了它背后的想法。如果你的问题没有算法,你就要自己做一个算法。查看您拥有的选项,您通常会局限于某种数据建模方式。
正如您已经说过的,您处理数据的方式也会影响您查询 某些内容的速度。例如,您对地图进行建模,因此您有一个点 A 和一个点 B,您希望从 A 到 B 再从 B 到 A。neo4j 中的问题是您没有双向边。所以你可能会考虑添加 2 条边,从 A 到 B 和从 B 到 A。不要这样做!性能将因遍历而受到很大影响。
- I can make each day a node (Mon, Tue, Wed, ...), that way, querying for specific days is fast.
- I can make a node called Day, and add the property name with the day of the week. That way, showing all days in a graph is easy to query for.
问问自己为什么要拥有这个数据库以及要用它做什么,不要忘记索引。您仍然可以创建一个索引来恢复一些性能,这在第一个示例中仍然存在。还要避免添加冗余数据。例如连接到所有工作日的节点日。每个人都知道星期五是一天。只有在您从中受益时才考虑这样做。在对一些图形进行建模并为图形编写自己的算法之后,您会对它有一个感觉。在某个时候,您将知道如何为特定用例设计最适合的图表。 经验是设计图形的关键,了解您已经可以使用的算法的局限性以及您可以自己做的事情。希望对您有所帮助。
您的数据模型的粒度级别应由您的查询要求驱动,而不是相反。即:在对数据库建模时,您应该问自己:"what kind of query I will do over my data?"。根据这个问题的答案,您将获得一个良好的起点,以创建具有适当粒度级别的良好模型。
在 Rik Van Bruggen 的书 Learning Neo4j 中(您可以在 this link 下载),作者谈到设计图数据库以提高查询能力:
Like with any database management system, but perhaps even more so for a graph database management system such as Neo4j, your queries will drive your model. What we mean with this is that, exactly like it was with any type of database that you may have used in the past or would still be using today, you will need to make specific design decisions based on specific trade-offs. Therefore, it follows that there is no one perfect way to model in a graph database such as Neo4j. It will all depend on the questions that you want to ask of the data, and this will drive your design and your model.
所以,基于此,你的问题"what level of specificity should be used when granularity level can be unlimited?"的答案是:这取决于你的查询需求。首先考虑您将执行的查询,然后再考虑数据模型。
我的建议是:一开始就让你的模型尽可能简单,然后在需要的时候逐渐改变。