图数据库是一种专门设计用于存储和管理图形数据的数据库类型。在图数据库中,数据以图的形式表示,其中节点表示实体,边表示实体之间的关系。这种表示方式非常适合处理具有复杂关系的数据,如社交网络、推荐系统、网络拓扑、生物信息学等领域的数据。
图数据库通常具有以下特点:
应用图数据库的场景包括:
社交网络分析:分析社交网络中的用户关系、群体结构等。推荐系统:基于用户和物品之间的关系提供个性化的推荐。网络拓扑:管理和分析复杂的网络结构,如计算机网络或交通网络。生物信息学:分析基因、蛋白质和其他生物实体之间的关系。图数据库的例子包括Neo4j、Amazon Neptune、ArangoDB等。这些数据库在处理具有复杂关系的数据时通常比传统的关系型数据库更有效。
为什么要使用图数据库:
在数据关系中心,图形数据库在查询速度方面非常高效,即使面对深度和复杂的查询也是如此。之前有人做了个实验,在一个社交网络找到最大深度为 4 的朋友的朋友,其中当深度为 4 的时候,图数据库的执行时间约为关系型数据库的 一千五百分之一,。
图数据库是以图结构存储和查询数据的数据库。在图数据库中,节点和关系取代表,外键和 Join。在图数据库中,无论何时运行类似 Join 的操作,数据库都会使用列表并直接访问链接的节点,而无需进行昂贵的搜索和匹配运算。
各个数据库的优劣点:
Neo4j是一种图数据库管理系统,专门设计用于存储和处理图形数据。主要有以下构建元素:
节点:节点是图中的基本单元,用于表示实体。每个节点可以包含一个或多个属性,用于描述实体的特征。属性: 节点和关系可以包含属性,属性是键值对的形式,用于存储有关节点或关系的信息。属性提供了关于节点或关系的详细数据。关系:关系表示节点之间的连接或关联。它有一个方向,描述了连接的含义。关系也可以包含属性,用于描述关系的特征。标签:标签是用于将节点分组的一种方式。节点可以附加一个或多个标签,这样可以更轻松地对节点进行分类和检索。标签类似于节点的“类型”。数据浏览器: Neo4j提供了一个数据浏览器,是一个可视化工具,用于浏览和查询图数据库中的数据。通过数据浏览器,用户可以执行Cypher查询、可视化图形数据,并了解节点、关系和属性的结构。Neo4j 使用场景:
Neo4j 常用于欺诈检测、实时推荐引擎。Neo4j常用于欺诈检测和实时推荐引擎等应用场景,这是因为Neo4j在处理复杂关系型数据方面具有优势。
安装Neo4j可以通过Docker容器化来简化和隔离部署过程。以下是在Docker中安装Neo4j的一般步骤:
拉取Neo4j镜像: 打开终端(命令行)并运行以下命令来拉取Neo4j官方Docker镜像: docker pull neo4j
这将从Docker Hub下载最新的Neo4j镜像。
这将在后台运行Neo4j容器,并将其命名为my-neo4j。你可以根据需要更改容器名称。
Neo4j 的 Cypher 语言是专门为处理图形数据而构建的,CQL 代表 Cypher 查询语言。像 Oracle 数据库具有查询语言 SQL,Neo4j 具有 CQL 作为查询语言。
对于 CQL 而言,它是一种声明性模式匹配语言,遵循 SQL 语法。
简单的 CQL 命令及用法如下:
CQL 命令用法CREATE创建节点MATCH检索有关节点,关系和属性数据RETURN返回查询结果WHERE提供条件过滤检索数据DELETE删除节点和关系REMOVE删除节点和关系的属性ORDER BY排序检索数据SET添加或更新标签 创建节点(CREATE) CREATE (n:Label {property1: value1, property2: value2, ...}) 示例: CREATE (person:Person {name: 'John', age: 30}) 创建关系(CREATE) MATCH (node1:Label1), (node2:Label2) WHERE node1.property = value1 AND node2.property = value2 CREATE (node1)-[:RELATIONSHIP_TYPE]->(node2) 示例: MATCH (john:Person {name: 'John'}), (jane:Person {name: 'Jane'}) CREATE (john)-[:KNOWS]->(jane) 查询节点和关系(MATCH) MATCH (node:Label {property: value})-[:RELATIONSHIP_TYPE]->(relatedNode) RETURN node, relatedNode 示例: MATCH (person:Person {name: 'John'})-[:KNOWS]->(friend) RETURN person, friend 更新节点属性(SET) MATCH (node:Label {property: value}) SET node.property = newValue 示例: MATCH (person:Person {name: 'John'}) SET person.age = 31 删除节点及其关系(DELETE) MATCH (node:Label {property: value})-[relation:RELATIONSHIP_TYPE]->() DELETE node, relation 示例: MATCH (person:Person {name: 'John'})-[relation:KNOWS]->() DELETE person, relation 查询节点及其关系(RETURN) MATCH (node:Label {property: value})-[:RELATIONSHIP_TYPE]->(relatedNode) RETURN node, relatedNode 示例: MATCH (person:Person {name: 'John'})-[:KNOWS]->(friend) RETURN person, friend 查询节点的属性(RETURN) MATCH (node:Label {property: value}) RETURN node.property 示例: MATCH (person:Person {name: 'John'}) RETURN person.age Go 语言创建 Neo4j 数据库使用 Go 语言创建 Neo4j 数据库西游数据并写入 Neo4j 数据库中:
package main import ("fmt""github.com/neo4j/neo4j-go-driver/v4/neo4j""log") func main() { // Neo4j数据库连接信息 neo4jURI :="bolt://43.143.147.135:27687"username :="username"password :="password"// 创建Neo4j数据库驱动 driver, err := neo4j.NewDriver(neo4jURI, neo4j.BasicAuth(username, password,"")) if err != nil { log.Fatal(err) } defer driver.Close() // 创建Neo4j数据库会话 session, err := driver.Session(neo4j.AccessModeWrite) if err != nil { log.Fatal(err) } defer session.Close() // 定义要写入的数据 data := []string{ `CREATE (tang:Character {NodeID: 1, Name: 'TangSeng', Title: '唐僧'})`, `CREATE (wukong:Character {NodeID: 2, Name: 'SunWukong', Title: '孙悟空'})`, `CREATE (bajie:Character {NodeID: 3, Name: 'ZhuBajie', Title: '猪八戒'})`, `CREATE (wujing:Character {NodeID: 4, Name: 'ShaWujing', Title: '沙悟净'})`, `CREATE (xitian:Place {NodeID: 5, Name: 'Xitian', Title: '西天'})`, `CREATE (journey:Task {NodeID: 6, Name: 'Journey', Title: '西天取经任务'})`, `MATCH (master:Character {Name: 'TangSeng'}), (student:Character {Name: 'SunWukong'}) CREATE (student)-[:MasterOf]->(master)`, `MATCH (master:Character {Name: 'TangSeng'}), (student:Character {Name: 'ZhuBajie'}) CREATE (student)-[:MasterOf]->(master)`, `MATCH (master:Character {Name: 'TangSeng'}), (student:Character {Name: 'ShaWujing'}) CREATE (student)-[:MasterOf]->(master)`, `MATCH (companion1:Character {Name: 'SunWukong'}), (companion2:Character {Name: 'ZhuBajie'}) CREATE (companion1)-[:CompanionOf]->(companion2)`, `MATCH (companion1:Character {Name: 'SunWukong'}), (companion2:Character {Name: 'ShaWujing'}) CREATE (companion1)-[:CompanionOf]->(companion2)`, `MATCH (character:Character {Name: 'SunWukong'}), (place:Place {Name: 'Xitian'}) CREATE (character)-[:TravelsTo]->(place)`, `MATCH (character:Character {Name: 'ZhuBajie'}), (place:Place {Name: 'Xitian'}) CREATE (character)-[:TravelsTo]->(place)`, `MATCH (character:Character {Name: 'ShaWujing'}), (place:Place {Name: 'Xitian'}) CREATE (character)-[:TravelsTo]->(place)`, `MATCH (place:Place {Name: 'Xitian'}), (task:Task {Name: 'Journey'}) CREATE (task)-[:MissionTo]->(place)`, } // 执行CQL命令 for _, query := range data { result, err := session.Run(query, nil) if err != nil { log.Fatal(err) } // 输出查询结果 fmt.Printf("Result: %+v\n", result) } } 创建新的关系,比如猪八戒和沙悟净曾是同事关系,具体数据库执行命令如下: MATCH (n:Character {Name:"ZhuBajie"}),(m:Character {Name:"ShaWujing"}) Create (n)-[r:同事]->(m) return n.Name,type(r),m.Name执行成功后,关系图谱增加了一条关系,当执行两次后,关系图谱会增加两条相同的关系:
执行完成后新的团队组织关系如下:
总结:以上是Neo4j的简单增删改查,对于熟练掌握Neo4j数据库来说还有很长的路要走和分析,后续需要在项目中不断学习和锤炼自己。