我正在开发一个 Neo4j 数据库,其中包含癌症患者的基因组和临床数据。开发图形数据库时的一个常见设计问题是数据项应该由节点还是节点内的属性表示。就我而言,患者将进行数百项临床和人口统计测量(例如性别、药物、肿瘤大小)。其中一些数据是恒定的(例如性别),而另一些数据将随着每次患者就诊而变化。我对之前的节点与属性问题看到的答复建议使用针对数据的预期查询来做出决定。我想我可以确定一些属性,这些属性将是常见的搜索标准并且应该是节点(例如吸烟史、性别、癌症类型),但这仍然给我留下了数百个其他属性。Neo4j 中节点应包含的属性数量是否有实际限制?此外,混合方法(其中一些数据是属性,其他数据是节点)似乎会使从源文件加载数据和后续查询变得更加复杂。
“查看查询来决定”背后的主要思想是,数据之间的关联方式会影响节点或属性是否更好。实际上,图数据库的要点是使行走关系更易于查询。因此,您应该问自己的真正问题是“(a)-->()<--(b) 有任何重要意义吗?” 换句话说,我是否需要能够找到共享此属性的其他节点?
以下是一些快速的经验法则
节点
特性
标签
那么让我们回顾一下您的一些属性的思考过程......
性别
要么是“男”,要么是“女”,每个人都将连接到两者之一,因此他们最终都会成为超级节点(超载)。此外,如果您最终确实需要找到两个性别相同的人,几乎任何其他方法都会比通过超级节点找到他们更有效。然而,这些是相互排斥的、不可改变的遗传特征,因此将其作为标签也是完全可以接受的(有时是首选)。
地址
这是一个具有子属性的变量值,不会被很多节点共享,并且从一个人到同一地址的另一个人(或者,通过扩展,居住在一个区域)具有有价值的意义。所以这几乎肯定是一个节点。
身高和体重
这些随着时间不断变化,没有子值,两个人共享这个值几乎没有意义。值的范围太宽,因此标签不会产生任何结果,因此这应该是一个属性。
血型
虽然比性别有更多的选择,但所有相同的逻辑都适用,只是这种关系现在确实很重要(因为人们必须共享血型才能捐献)。问题是这个值会超载,您需要首先过滤区域,而不仅仅是验证血型。可能是属性或标签。节点的情况是,如果您在血型之间包含“Can_Donate_To”或“Can_Accept”关系。虽然您可能不会通过这些关系来寻找潜在的捐赠者(因为它们太多了,您必须首先按区域进行过滤),但您可以使用它们来验证某人是否可以成为捐赠者。
社会安全号码
高度敏感,诉讼等待发生。如果可能的话,请远离数据库。如果你绝对必须这样做;这个属性是不可变的,但对每个人来说都是唯一的,因此由于缺乏重用,是一个不好的标签,并且作为节点毫无意义。绝对是一个财产。(但如果仅用于验证目的,则应加盐+散列)
母亲的娘家姓
可能的值是无穷无尽的,共享该值的两个节点没有实际意义。绝对是一个财产。
第一个出生的孩子
由于子节点已经是自己的节点,具有自己的子属性,因此只需在两者之间创建关系即可。虽然此信息的价值值得怀疑,但任何时候您需要引用另一个节点时,请始终为其使用关系。绝对是一个节点。