如何表示图的数据模型

时间:2014-05-20 14:22:02

标签: graph neo4j data-modeling

因此,我们一直在开发一些基于图形的分析工具,在后台使用neo4j作为持久性引擎。作为其中的一部分,我们正在开发适合于我们的域的图数据模型,并且我们希望在应用层中使用它来限制节点的类型,或者确保某些类型的节点必须携带某些属性。正常的数据模型限制。

那就是背景,我要问的是,是否有一些标准方法来表示图形数据库的数据模型?图的等效xsd也许?

2 个答案:

答案 0 :(得分:4)

在Neo4j中有一个开源项目支持强大的模式定义:Structr(http://structr.org,看到它的实际应用:http://vimeo.com/structr/videos

Structr's Visual Schema Editor

使用Structr,您可以定义数据模型的图形内架构,包括

  • 类型继承
  • 支持的数据类型:Boolean,String,Integer,Long,Double,Date,Enum(+ values)
  • 默认值
  • 基数(1:1,1:*,*:1)
  • 非空约束
  • 唯一性约束
  • 完整型安全
  • 验证
  • 基数执法

目前正在向架构中添加对方法(自定义操作)的支持。

可以使用编辑器或直接通过REST编辑模式,修改数据模型的JSON表示:

{
   "query_time": "0.001618446",
   "result_count": 4,
   "result": [
      {
         "name": "Whisky",
         "extendsClass": null,
         "relatedTo": [
            {
               "id": "96d05ddc9f0b42e2801f06afb1374458",
               "name": "Flavour"
            },
            {
               "id": "28f85dca915245afa3782354ea824130",
               "name": "Location"
            }
         ],
         "relatedFrom": [],
         "id": "df9f9431ed304b0494da84ef63f5f2d8",
         "type": "SchemaNode",
         "_name": "String"
      },
      {
         "name": "Flavour",
         ...
      },
      {
         "name": "Location",
         ...
      },
      {
         "name": "Region",
         ...
      }
   ],
   "serialization_time": "0.000829985"
}

{
   "query_time": "0.001466743",
   "result_count": 3,
   "result": [
      {
         "name": null,
         "sourceId": "28f85dca915245afa3782354ea824130",
         "targetId": "e4139c5db45a4c1cbfe5e358a84b11ed",
         "sourceMultiplicity": null,
         "targetMultiplicity": "1",
         "sourceNotion": null,
         "targetNotion": null,
         "relationshipType": "LOCATED_IN",
         "sourceJsonName": null,
         "targetJsonName": null,
         "id": "d43902ad7348498cbdebcd92135926ea",
         "type": "SchemaRelationship",
         "relType": "IS_RELATED_TO"
      },
      {
         "name": null,
         "sourceId": "df9f9431ed304b0494da84ef63f5f2d8",
         "targetId": "96d05ddc9f0b42e2801f06afb1374458",
         "sourceMultiplicity": null,
         "targetMultiplicity": "1",
         "sourceNotion": null,
         "targetNotion": null,
         "relationshipType": "HAS_FLAVOURS",
         "sourceJsonName": null,
         "targetJsonName": null,
         "id": "bc9a6308d1fd4bfdb64caa355444299d",
         "type": "SchemaRelationship",
         "relType": "IS_RELATED_TO"
      },
      {
         "name": null,
         "sourceId": "df9f9431ed304b0494da84ef63f5f2d8",
         "targetId": "28f85dca915245afa3782354ea824130",
         "sourceMultiplicity": null,
         "targetMultiplicity": "1",
         "sourceNotion": null,
         "targetNotion": null,
         "relationshipType": "PRODUCED_IN",
         "sourceJsonName": null,
         "targetJsonName": null,
         "id": "a55fb5c3cc29448e99a538ef209b8421",
         "type": "SchemaRelationship",
         "relType": "IS_RELATED_TO"
      }
   ],
   "serialization_time": "0.000403616"
}

您可以通过基于图中架构动态配置的RESTful API访问存储在Neo4j中的节点和关系作为JSON对象。

$ curl try.structr.org:8082/structr/rest/whiskies?name=Ardbeg
{
   "query_time": "0.001267211",
   "result_count": 1,
   "result": [
      {
         "flavour": {
            "name": "J",
            "description": "Full-Bodied, Dry, Pungent, Peaty and Medicinal, with Spicy, Feinty Notes.",
            "id": "626ba892263b45e29d71f51889839ebc",
            "type": "Flavour"
         },
         "location": {
            "region": {
               "name": "Islay",
               "id": "4c7dd3fe2779492e85bdfe7323cd78ee",
               "type": "Region"
            },
            "whiskies": [
               ...
            ],
            "name": "Port Ellen",
            "latitude": null,
            "longitude": null,
            "altitude": null,
            "id": "47f90d67e1954cc584c868e7337b6cbb",
            "type": "Location"
         },
         "name": "Ardbeg",
         "id": "2db6b3b41b70439dac002ba2294dc5e7",
         "type": "Whisky"
      }
   ],
   "serialization_time": "0.010824154"
}

在用户界面中,还有一个数据编辑(CRUD)工具和支持在Neo4j上创建Web应用程序的CMS组件。

免责声明:我是Structr的开发者,也是该项目的创始人。

答案 1 :(得分:3)

不,没有标准的方法可以做到这一点。实际上,即使有,请记住,neo4j目前支持的唯一约束是uniqueness constraints

以一些示例规则为例:

  • 标有:Person的所有节点必须包含非空属性fnamelname
  • 标有:Person的所有节点必须具有> = 1类型:works_for的出站关系

现在的neo4j的问题在于,即使在你确实拥有可以表达这些东西的模式语言(标准化)的情况下,也不会有数据库引擎本身可以实际强制执行该约束的方式。

所以简单的答案是否定的,现在没有标准的方法可以做到这一点。

我见过人们用来模拟相同的一些技巧:

  1. 使用已知结果汇总“测试套件”密码查询列表。查询你知道的事情不应该在那里;非空结果集是问题/完整性违规的标志。查询你知道的事情应该在那里;空结果集是个问题。
  2. 应用程序级控制 - 通过某些层(如spring-data或类似控件)控制谁可以与数据库通信。这实质上将您的数据完整性/测试问题移到应用程序中,远离数据库。
  3. 许多NoSQL解决方案(不是特别是neo4j)的常见(和恕我直言,令人讨厌)因为它们的架构弱点,它们倾向于强制将技术堆栈验证到应用程序中。在应用程序中执行这些操作往往更难,更容易出错。 SQL数据库允许您实现各种模式约束,触发器等 - 特别是为了使得将错误的数据放入数据库真的很难。 NoSQL数据库通常不存在,或者不作为设计决策执行此操作。确实存在灵活性/性能权衡。如果数据库不需要根据一长串模式规则检查每个数据原子,就可以更快地插入并更灵活地快速适应。

    编辑:两个相关资源:metagraphs proposal讨论如何将架构表示为图形,neoprofiler是一个尝试推断 neo4j数据库的实际结构,并显示其“配置文件”。

    随着时间的推移,我认为希望neo包含基本的完整性功能是合理的,例如要求某些标签具有某些属性(上面的示例),限制某些属性的数据类型(lname必须始终是String,而不是整数),等等。虽然(在计算复杂性意义上)图形数据模型有点疯狂和毛茸茸,但人们拼命想要的图形有一些限制,但可能永远不会得到。一个例子是图形中不能有循环的约束。强制执行每个关系的创建将是非常计算密集的。 (