龙空技术网

图数据建模:标签

闻数起舞 626

前言:

而今看官们对“cypher 模糊查询”可能比较关切,我们都需要剖析一些“cypher 模糊查询”的相关知识。那么小编同时在网上网罗了一些关于“cypher 模糊查询””的相关内容,希望各位老铁们能喜欢,各位老铁们一起来学习一下吧!

本文是先进图模型的最新系列;该系列中的其他文章处理键,关系,超节点和分类变量。

今天我们将在Neo4J中谈论标签,他们是什么,如何使用它们,如何被滥用,以及如何避免这种情况。Neo4J的数据模型从根本上称为“标记的属性图(LPG)模型”,标签非常重要。

我们将涵盖:

什么是标签?他们的意思是什么?neo4j如何对待标签我该如何在我的模型中使用它们?什么是标签?他们的意思是什么?

标签是一种可以应用于图中的任何节点的命名。它们只是一个名称 - 所以标签是存在的或缺席。从图表数据库概念:

标签用于通过将节点分组到集合中的所有节点属于同一组的所有节点来塑造域。

如果您使用过的Cypher,您已经看到了它们:CREATE (p:Person { name: "David" }) 指定标签“Person”。它可以是您喜欢的任何UTF-8字符串。通过使用后蜱脱离Cypher的字符串,您可以拥有一个

(:`Longer Spaced Label`)

或者你甚至可以使用表翻转家伙(╯°□°)╯(┻━┻或emoji作为您的标签,虽然这些不能在Neo4j浏览器中非常方便的输入,但它们可以使一些乐趣,Neo4j Bloom这样的可视化。

设置成员资格

将上面提到的“分组节点进入集合”,这是一个了解标签为您所做什么的关键概念。考虑这个简单,未标记的图表:

> An unlabeled graph

现在我们是否要将所有节点分为两组?

> Venn diagram of two kinds of nodes

好的,这已经更清楚了。所以现在neo4j中的标签只是一个“设置成员资格标记”。一旦我们申请真正的蓄电池标签,我们就会自动着色;Neo4j浏览器向我们展示了与上面的韦恩图相同的东西,只是它更容易看到发生了什么。

多个设置成员资格

设置可以具有子集,因此我们可以进一步将我们的(:Job)节点分为(:Job:Technology)或(:Job:Healthcare),如果我们想要。任何节点都可以是您想要的任何数量的组。这更难用颜色视觉表示,但概念与上面的Venn图表不同。

neo4j如何对待标签

存储在磁盘上时每个节点都有几个插槽,其中neo4j可以存储一个标识符,该标识符允许它知道节点具有哪个标签。预先分配了一定量的存储量(我认为这是4个插槽)。当标签应用于节点时,数据库将标签参考投入到其中一个插槽中,以提供半无索引和数据库统计信息的形式,以通知Cypher查询计划者。

“半自动”索引

回到我的玩具数据库我正在使用上面的图,除了我少数的“Job”和“Person”节点之外,我创建了10,000个额外节点。然后我在查询匹配上ran解释(n {name:“a”})返回n。数据库做了什么?

> Note the AllNodesScan at the top

在最顶端,Allnodesscan正是它听起来像的那样。数据库通过整个数据库(10,005估计)中的每个单个节点看,以找到我们想要的节点。这效率很低。但是,如果我们要求它解释它的计划以“a”命名的计划?EXPLAIN MATCH (p:Person { name: "A"}) RETURN p

> NodeByLabelScan

结果是一个NodeBylabelscan,需要考虑估计的10行。这正是使用标签作为索引的意思 - 每次在读取查询中指定一个时,数据库都要少于查看为您完成工作。

我在说他们半自动而不是完全免费的原因当然,数据库还必须维护标签存储。编写那些标签(如写作和维护索引)比未做的是更多的工作,因此通过将标签应用于您在写入时间进行更多的前线工作,以便在读取时间获胜。

作为索引的形式,比较这两个选项并注意到它们是如何等效的,而是如何更容易阅读标签(它可能也更加表现)。

/* Option 1: bad */CREATE (n:Everything { name: "A", nodeType: "Job" })CREATE INDEX nodeType_idx ON :Everything(nodeType)/* Option 2: much better, ultimately the same thing */CREATE (n:Job { name: "A" })
数据库统计数据

Neo4j维护一个“Count Store”,用于为许多东西保持计数元数据。Count Store用于通知查询计划程序,因此它可以对如何规划查询进行受过教育选择。从Count Store获取计数只是获取单个号码,因此它变得非常快。对于您(或Cypeher查询计划者),Count Store很方便。您可以在此知识库文章中了解更多有关它的信息。

在上面的解释计划中,Cypeher大致了解有多少节点,因为标签和计数存储。在哈林中,您可以非常简单地看到Count Store的基础知识 - 数据库看到的相同统计数据。

好的,所有的方式都是,现在是时候使用这些信息并谈论如何构建更好的标记属性图数据模型。

我应该如何在模型中使用标签?

有时最简单的建议是最好的:10个中的9次,如果您将一个且只有一个标签附加到每个节点,那么您就可以精细,不需要进一步的建议。它真的可以很简单。本文的其余部分涉及更复杂的情况,以及如何在使用数据建模原则方面进行思考。

一般原则很简单:使用标签指示语义类别的信息和设置成员资格,并使用它们来获得上述“半自动”索引的速度。为了使这个更具体,让我们来看看一些最好和最糟糕的做法。总结,他们是:

标记每个节点,没有异常始终为标签有一个查询用例多个标签应该是语义正交的避免标签过载标记每个节点

这意味着,使用至少一个标签并尽可能避免未标记的节点。未标记的节点是语义上模糊的;什么是一种节点,甚至认为是什么意思?它们难以区分其他节点。

如果您只需严格地粘在每节点的一个标签,在95%的情况下,你就会好转!本文的其余部分几乎所有的所有节点都会处理周围多个标签的问题。但如果你不需要它们,你可以在这里停下来,你已经完成了。

始终为标签有一个查询用例

如果您不知道要询问数据库的查询,请不要设计数据模型。如果您有一个想法,您想使用标签Foo,请确保它连接到您需要询问数据库所需的真实问题。

数据建模中最重要的方面之一:

存在数据模型,以便于从数据库中应答问题 - 它们不用于创建域的原始语义模型

这是许多人的一个主要错误,是大量数据模型错误和痛苦的源:试图创建一个伟大的域语义模型,而不是专注于他们需要数据库的问题来回答。创建伟大的语义模型是可以说的,所以模型是地图,地图不是领土。我们是数据建模器,而不是哲学家,我们有问题我们需要这个数据库昨天回答。

如果您无法铭记您所需的标签,请不要使用它。您可以稍后始终申请更多标签。(YAGNI原则)

多个标签应该是语义正交的

“语义正交”是一个花哨的术语,意味着标签应该彼此无关。想象一下,我们对国际业务有了一个小报告,展示了它在不同市场销售的产品数量。

“商业区”(美国与欧盟)在视觉上和语义上与伯爵(客户与产品)正交。

客户和地理概念之间没有实际关系;这可能使它们交叉的良好设置标签。

如此标记节点(:客户:美国),(:客户:欧盟),(:产品:美国),(:产品:欧盟)可能会为良好的数据分区提供。注意如何与正交标签,我们支持2个不同用例:我们通过地理学完成了整个分区图。我们可以像这样提出整个子图:

MATCH (n:USA) RETURN n

然而,设置的交叉点也是高度选择性的,并且可以更快地查询:

MATCH (p:Product:EU) RETURN p

这些属性来自标签语义的正交性。

不要过度使用 - 避免标签过载

上面我们提到neo4j预先分配了约4个标签的插槽。这就像我们描述的那样,你得到了“半自星”;但是,如果你走过这个限制,那么Neo4J就开始分配额外的空间只是为了存储你的堆标签。请记住,通常使用查询时最特定的标签,您通常会获得最快的查询加速;因此,如果节点上有10个标签,您通常只是要求数据库做很多不必要的工作,这不会加快查询。

作为一般的经验法则,每节点不超过4个标签,期待整体性能变得更糟,更好

在我看过的大多数思考模型中,每个节点的一个或两个标签就足够了。一些具有充分理由的异国情调案件可能需要三到四个;但在此之上,您应该真正质疑模型是否有意义,并被调整为您的实际查询需求。

避免类层次结构

一个人有时会达到标签的想法是将它们用来模拟类层次结构。这通常被称为“继承”或“是”关系。如果您了解上面的部分“语义正交性”,您应该立即发现类层次结构不是语义正交的。

想象一下你有一个如此的动物园:

现在很有诱人地创造了很多标有的节点(:Bat:Mammal:Animal)(:Pelican:Oviparous:Animal) 等。使用我们上面的“set membership”论证,那些这样做的人将指出将(MATCH (a:Animal) 与所有鳄鱼和鲸鱼一起举行的套件,依赖于所有鳄鱼和鲸鱼。

由于有很多原因,这通常不是一个好主意:

Neo4j不强制执行共同标签约束,即,可以一起出现哪些标签。这意味着数据库不会在避免哺乳动物鳄鱼或非动物鲸时给您任何帮助,这实际上是在您的语义模型下的废话。随着你的层次结构增长,它将倾向于超载标签数量。无论如何,您可以通过设置交叉来执行相同的操作。如果您刚用哺乳动物或卵泡标记一切,您可以随时随地获得所有超级级别成员(动物),MATCH (n) WHERE n:Mammal OR n:Oviparous.。大多数时候,人们喜欢这个模型,但是当他们调查他们的实际查询模式时,他们并不真正有一个用于匹配抽象超级类的用例,可以在真实的世界查询中匹配抽象超级类,而且它刚刚过于复杂。类层次结构通常是一个创建语义模型的案例,而不是专注于如何回答问题。

如果节点具有在某处(例如,鲸鱼 IS-A 哺乳动物)的关系 - 使用与指示哺乳动物的不同节点的关系。它不应该是一个标签。

避免构成关系

或者,有“具有”关系,可以指示所有权。再次,“关系”这个词在这里,所以如果在你的模型中,你有两个不同的东西(例如“人”和“汽车”)它有时可以诱惑模拟与标签的关系,这样截至(:Person:CarOwner)

请注意该标签的名称,承诺者;寻找的模式是“CarOwner”。(名词=汽车动词=自己)。数据模型中的“名词 动词”项表达了关系。使用的更好方法是使用关系。

通常,您将发现构成关系不会是语义正交。上面的良好示例(:Customer:EU), (:Customer:USA)不是“名词 动词”的例子。它不是构成(欧盟没有“拥有”客户,业务确实),而且也不继承(欧盟不是客户),这是它是正交的原因的一部分。

结论

以下这些指南是在您的模型中获得最佳清晰度和性能的最佳平衡的好方法,应该帮助您的模型是一个简单的玩具,还是巨大的企业模型。

(本文由闻数起舞翻译自David Allen的文章《Graph Modeling: Labels》,转载请注明出处,原文链接:)

标签: #cypher 模糊查询