暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

golang源码分析:cayley(3)

        cayley可以使用多种后端存储,那么如何使用mysql作为后端存储呢,首先我们看下如何配置:

    store:
    # backend to use
    backend: mysql
    # address or path for the database
    address: "root:@tcp(localhost:3306)/cayley?loc=Local&charset=utf8mb4&collation=utf8mb4_general_ci"
    # open database in read-only mode
    read_only: false
    # backend-specific options
    options:
    nosync: false
    query:
    timeout: 30s
    load:
    ignore_duplicates: false
    ignore_missing: false
    batch: 10000

    backend设置成mysql,并且指定dsn即可,接着我们使用mysql作为后端存储导入数据:

    首先创建数据库cayley

      % mysql.server start
      Starting MySQL
      .. SUCCESS!


      % mysql -uroot
      Welcome to the MySQL monitor. Commands end with ; or \g.


      mysql> create database cayley;

      初始化下看看是否成功

        % ../cayley/cayley init -c cayley_example.yml
        I0528 23:40:40.065734 81480 command.go:915] Cayley version: v0.8.x-dev (dev snapshot)
        I0528 23:40:40.066011 81480 command.go:915] using config file: cayley_example.yml
        I0528 23:40:40.066107 81480 database.go:71] using backend "mysql" (root:@tcp(localhost:3306)/cayley?loc=Local&charset=utf8mb4&collation=utf8mb4_general_ci)


        检查下,发现已经创建了两个表

          mysql> use cayley;
          Reading table information for completion of table and column names
          You can turn off this feature to get a quicker startup with -A


          Database changed
          mysql> show tables;
          +------------------+
          | Tables_in_cayley |
          +------------------+
          | nodes |
          | quads |
          +------------------+
          2 rows in set (0.00 sec)

          这两个表分别存了顶点和四元祖

            mysql> show create table nodes\G
            *************************** 1. row ***************************
            Table: nodes
            Create Table: CREATE TABLE `nodes` (
            `hash` binary(20) NOT NULL,
            `refs` int NOT NULL,
            `value` blob,
            `value_string` text,
            `datatype` text,
            `language` text,
            `iri` tinyint(1) DEFAULT NULL,
            `bnode` tinyint(1) DEFAULT NULL,
            `value_int` bigint DEFAULT NULL,
            `value_bool` tinyint(1) DEFAULT NULL,
            `value_float` double DEFAULT NULL,
            `value_time` datetime(6) DEFAULT NULL,
            PRIMARY KEY (`hash`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
            1 row in set (0.02 sec)
              show create table quads\G
              *************************** 1. row ***************************
              Table: quads
              Create Table: CREATE TABLE `quads` (
              `horizon` bigint unsigned NOT NULL AUTO_INCREMENT,
              `subject_hash` binary(20) NOT NULL,
              `predicate_hash` binary(20) NOT NULL,
              `object_hash` binary(20) NOT NULL,
              `label_hash` binary(20) DEFAULT NULL,
              `ts` timestamp NULL DEFAULT NULL,
              PRIMARY KEY (`horizon`),
              UNIQUE KEY `horizon` (`horizon`),
              UNIQUE KEY `spo_unique` (`subject_hash`,`predicate_hash`,`object_hash`),
              UNIQUE KEY `spol_unique` (`subject_hash`,`predicate_hash`,`object_hash`,`label_hash`),
              KEY `label_hash_fk` (`label_hash`),
              KEY `spo_index` (`subject_hash`,`predicate_hash`,`object_hash`),
              KEY `ops_index` (`object_hash`,`predicate_hash`,`subject_hash`),
              KEY `pos_index` (`predicate_hash`,`object_hash`,`subject_hash`),
              KEY `osp_index` (`object_hash`,`subject_hash`,`predicate_hash`),
              CONSTRAINT `label_hash_fk` FOREIGN KEY (`label_hash`) REFERENCES `nodes` (`hash`),
              CONSTRAINT `object_hash_fk` FOREIGN KEY (`object_hash`) REFERENCES `nodes` (`hash`),
              CONSTRAINT `predicate_hash_fk` FOREIGN KEY (`predicate_hash`) REFERENCES `nodes` (`hash`),
              CONSTRAINT `subject_hash_fk` FOREIGN KEY (`subject_hash`) REFERENCES `nodes` (`hash`)
              ) ENGINE=InnoDB AUTO_INCREMENT=314 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
              1 row in set (0.00 sec)

              导入数据

                ../cayley/cayley load -c cayley_example.yml -i ../cayley/data/**nq --alsologtostderr=true
                I0528 23:43:00.003584 82856 command.go:915] Cayley version: v0.8.x-dev (dev snapshot)
                I0528 23:43:00.006404 82856 command.go:915] using config file: cayley_example.yml
                I0528 23:43:00.008158 82856 database.go:91] using backend "mysql" (root:@tcp(localhost:3306)/cayley?loc=Local&charset=utf8mb4&collation=utf8mb4_general_ci)

                查看下存储数据

                  mysql> select * from nodes limit 1\G
                  *************************** 1. row ***************************
                  hash: 0x278A31F9BA54E8D73ADBC4F1AE82B1D2442DE516
                  refs: 3
                  value: NULL
                  value_string: NULL
                  datatype: NULL
                  language: NULL
                  iri: NULL
                  bnode: NULL
                  value_int: NULL
                  value_bool: 1
                  value_float: NULL
                  value_time: NULL
                  1 row in set (0.00 sec)

                  当然也可以开启http服务来访问cayley

                    ../cayley/cayley http -c cayley_example.yml --host=0.0.0.0:64210

                    浏览器打开http://127.0.0.1:64210/,可以看到

                    那么如何使用go来操作我们的图数据库呢

                      package main


                      import (
                      "fmt"
                      "log"


                      "github.com/cayleygraph/cayley"
                      _ "github.com/cayleygraph/cayley/graph/sql/mysql"
                      "github.com/cayleygraph/quad"
                      )


                      func main() {
                      // Create a brand new graph
                      // store, err := cayley.NewGraph("sql", "root:@tcp(localhost:3306)/cayley?loc=Local&charset=utf8mb4&collation=utf8mb4_general_ci", nil)
                      store, err := cayley.NewGraph("mysql", "root:@tcp(localhost:3306)/cayley?loc=Local&charset=utf8mb4&collation=utf8mb4_general_ci", nil)
                      if err != nil {
                      log.Fatalln(err)
                      }


                      store.AddQuad(quad.Make("phrase of the day", "is of course", "Hello World!", "label1"))
                      store.AddQuad(quad.Make("Hello World!", "is of course", "Hello World1!", "label2"))
                      store.AddQuad(quad.Make("Hello World1!", "is course", "Hello World2!", "label2"))
                      // Now we create the path, to get to our data
                      p := cayley.StartPath(store, quad.String("phrase of the day")).Out(quad.String("is of course")).Out(quad.String("is of course")).Out(quad.String("is course"))


                      // Now we iterate over results. Arguments:
                      // 1. Optional context used for cancellation.
                      // 2. Flag to optimize query before execution.
                      // 3. Quad store, but we can omit it because we have already built path with it.
                      err = p.Iterate(nil).EachValue(nil, func(value quad.Value) {
                      nativeValue := quad.NativeOf(value) // this converts RDF values to normal Go types
                      fmt.Println(nativeValue)
                      })
                      if err != nil {
                      log.Fatalln(err)
                      }
                      }

                      运行下

                        % go run ./test/cayley/exp5/main.go
                        Hello World2!

                                总结下,图数据库其实是图到持久化存储的一种迁移实现,我们知道图有两种数据结构可以来表示,邻接表和邻接矩阵。图数据其实是邻接矩阵的形式存储的,同时利用了邻接矩阵的稀疏性,存储了订单和边,对应了两个表node和quad。实现上,图数据库有专用存储和借用三方存储两种形式。cayley是借用第三方存储实现的。它在上层封装了迭代器,并且封装了gizmo查询和graphql等,方便我们更加直观处理图相关逻辑。

                        文章转载自golang算法架构leetcode技术php,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                        评论