本周让咱们持续NoSQL家族的访谈之旅,本次咱们的采访对象Neo4J学生。

为什么要有Neo4J?

各种数据库事实上都是在形容事实世界上中数据之间的分割,事实世界中一个比拟典型的场景就是关系数据库力有不逮的中央,那就是社交网络,这种重分割的数据。如下图所示:

A和B、C、D、E都是好敌人,这在关系型数据库是典型的多对多关系, 对于多对多的关系,个别关系型的策略是建设一张两头表来形容这种多对多的关系。然而在关系型数据库中形容分割更常见的场景是形容不同数据的建模关系,比方学生和课程表的关系,选课表就存储学生ID,课程表ID等其余必要信息,学生和课程形容的对象是不同的,下面的图形容的数据是雷同的,可能都是社交圈的人。咱们该如何存储这种分割,一张自分割的表? 存储跟他分割的信息? 像上面这样:

那如果我当初的需要是查问A的敌人的敌人呢,那一个简略而无脑的操作就是我想看我敌人的敌人,这只是一层, 对应的SQL其实很好写:

# 请原谅我还是从Student还是 SELECT * FROM Student WHERE id in (  SELECT studentReleationId  FROM student_releation WHERE studentId in      (SELECT studentReleationId FROM student_releation WHERE studentId  = '1')# 转成join的话,先找出我敌人的敌人的Id,而后再做join,或者子查问SELECT s2.studentReleationId  FROM student_releation s1 INNER JOIN  student_releation s2 on s1.studentReleationId = s2.studentIdWHERE s1.studentId = '1'

但其实并不举荐join,假如一个人的社交好友有100个,有的其实会更高,那我存储个人信息如果只有三万集体的话,那么存储分割的表就是三百万条数据,这个其实还不算穿插意识的。对于关系型数据库来说大表的join是一场劫难,但对于社交软件来说,三万个用户来说是相当少的数据量,对于成熟的社交产品来说,三百万,三千万都有可能。再比方电影关系图,查看某个导演的电影参演的演员,对于关系型数据库来说这个也不是不能做,只是数量下来之后,咱们查问速度是一直在降落的,因为对于表与表之间的关系根本靠join,join的越多速度越慢。由此咱们就引出了图数据库的利用场景,多对多建模、存取数据。图数据库对关联查问个别都进行针对性优化,比方存储模型上、数据结构、查问算法等,避免部分数据的查问引发全副数据的读取。

关系型数据库有不同的实现,MySQL,Oracle, SQL Server 一样,图数据库也有不同的实现: Neo4j,JanusGraph,HugeGraph。关系型数据库的查询语言是SQL,图数据库的查询语言是: Gremlin、Cypher.本次咱们介绍的就是Neo4j。

用起来

我首先还是来到Neo4j官网心愿有收费试用的,因为我不想本人装。而后我看到了收费试用:

而后我就不装了,间接开始用。咱们首先还是先介绍根本的语法:

  • 创立

    • 创立结点

      CREATE (Person { name: "Emil", from: "Sweden", klout: 99 }) 
      Person是这个结点的标签,{}外面是这个标签的属性。
    • 创立分割

      MATCH (ee:Person) WHERE ee.name = "Emil"  #  先查问一次是为了前面建立联系CREATE (js:Person { name: "Johan", from: "Sweden", learn: "surfing" }), # 创立一个结点,并将js指向该结点(ir:Person { name: "Ian", from: "England", title: "author" }),# 创立一个结点,并将ir指向 这个结点(rvb:Person { name: "Rik", from: "Belgium", pet: "Orval" }),(ally:Person { name: "Allison", from: "California", hobby: "surfing" }),(ee)-[:KNOWS {since: 2001}]->(js),(ee)-[:KNOWS {rating: 5}]->(ir),# (变量)-[关系形容]->(变量)  这两个结点建立联系 [中是对这个边的关系形容] KNOWS能够了解为理解,KNOWS{SINCE:2001}示意ee和js意识是在2001年(js)-[:KNOWS]->(ir),(js)-[:KNOWS]->(rvb),(ir)-[:KNOWS]->(js),(ir)-[:KNOWS]->(ally),(rvb)-[:KNOWS]->(ally)
    • 移除结点的属性

      MATCH (a:Person {name:'Emil'}) REMOVE a.name
    • 删结点

      MATCH (a:Person {name:'Ian'}) DELETE a
MATCH(ee:Person) where name = 'Johan'SET ee.name = '张三' RETURN ee; # 将name = Johan 的name改为张三
    • 查找单个结点
    MATCH (ee:Person) WHERE ee.name = "Johan" RETURN ee; # 查出结点中name叫Johan的,而后返回 
    • 查找所有具备Knows关系的结点
    MATCH (n)-[:KNOWS]-() RETURN n
    • 查找某人敌人的敌人, 这里咱们将KNOWS看做敌人
    MATCH (a:Person {name:'Ian'})-[r1:KNOWS]-()-[r2:KNOWS]-(friend_of_a_friend) RETURN friend_of_a_friend.name AS fofName# friend_of_a_friend 是返回的变量

Java操纵Neo4J

Java操纵任何数据库都须要驱动, Neo4j的收费试用版有对应的语言示例.

Neo4J 的驱动跟JDBC相似,原生都是咱们拼SQL,而后提交。依赖:

 <dependency>      <groupId>org.neo4j.driver</groupId>      <artifactId>neo4j-java-driver</artifactId>      <version>4.1.0</version> </dependency>

示例:

public class DriverIntroduction implements AutoCloseable{    private final Driver driver;    public DriverIntroduction(String uri, String user, String password, Config config) {        // The driver is a long living object and should be opened during the start of your application        driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password), config);    }    @Override    public void close() throws Exception {        driver.close();    }    public void createFriendship(final String person1Name, final String person2Name) {        // 创立结点 而后建立联系,并返回结点        String createFriendshipQuery = "CREATE (p1:Person { name: $person1_name })\n" +                "CREATE (p2:Person { name: $person2_name })\n" +                "CREATE (p1)-[:KNOWS]->(p2)\n" +                "RETURN p1, p2";        Map<String, Object> params = new HashMap<>();        params.put("person1_name", person1Name);        params.put("person2_name", person2Name);        try (Session session = driver.session()) {            Record record = session.writeTransaction(tx -> {                Result result = tx.run(createFriendshipQuery, params);                return result.single();            });        } catch (Neo4jException ex) {            throw ex;        }    }}

总结一下

本文简略介绍了一下Neo4J的由来,以及根本的增删改查,Java操纵数据库。Neo4j默认只有一个数据库,目前社区版仿佛不反对语法创立数据库,须要批改配置文件。Neo4J也没有关系型数据库对应表的概念。数据库上面间接就是节点数据。Neo4j也有中文文档:

http://neo4j.com.cn/public/do...

参考资料

  • 相似 Neo4j 这样的图数据库在国内会衰亡么?为什么? https://www.zhihu.com/questio...
  • 手把手教你疾速入门常识图谱 - Neo4J教程 https://zhuanlan.zhihu.com/p/...