zoukankan      html  css  js  c++  java
  • dgraph 使用简介

    dgraph 简介

    dgraph 是基于 golang 开发的开源的分布式图数据库. 诞生时间不长, 发展却很迅速. 目前是 v20.x 版本, dgraph 集群主要包含 3 种节点:

    1. Zero: 是集群的核心, 负责调度集群服务器和平衡服务器组之间的数据
    2. Alpha: 保存数据的 谓词索引. 谓词包括数据的 属性 和数据之间的 关系; 索引是为了更快的进行数据的过滤和查找
    3. Ratel: dgraph 的 UI 接口, 可以在此界面上进行数据的 CURD, 也可以修改数据的 schema

    通过增加 Alpha 的数量完成 dgraph 的水平扩展.

    dgraph 是 golang 开发的, 所以部署非常简单, 更简单的方式是使用 docker

    docker pull dgraph/dgraph:latest
    

    然后配置一个 docker-comopse.yml, 一键启动 dgraph 服务:

    version: "3.2"
    services:
      zero:
        image: dgraph/dgraph:latest
        volumes:
          - type: volume
            source: dgraph
            target: /dgraph
            volume:
              nocopy: true
        ports:
          - 5080:5080
          - 6080:6080
        restart: on-failure
        command: dgraph zero --my=zero:5080
      alpha:
        image: dgraph/dgraph:latest
        volumes:
          - type: volume
            source: dgraph
            target: /dgraph
            volume:
              nocopy: true
        ports:
          - 7080:7080
          - 8080:8080
          - 9080:9080
        restart: on-failure
        command: dgraph alpha --my=alpha:7080 --lru_mb=2048 --zero=zero:5080
      ratel:
        image: dgraph/dgraph:latest
        volumes:
          - type: volume
            source: dgraph
            target: /dgraph
            volume:
              nocopy: true
        ports:
          - 8000:8000
        command: dgraph-ratel
    
    volumes:
      dgraph:
    

    启动 dgraph, 在上面 docker-compose.yml 相同的文件夹下执行:

    docker-compose up -d
    

    如果没有错误, 可以通过: http://<YOUR IP/Domain>:8000/ 来访问 draph 的 UI 界面.

    dgraph 使用示例(基于 golang)

    通过 dgraph 的 UI 界面, 可以完成所有的操作, 但要想将 dgraph 和应用结合, 还得使用 dgraph 的 SDK.
    dgraph 的 SDK 支持各种语言, 官方支持的主要有: Go, C#, Java, Javascript, Python.

    dgraph 本身就是基于 golang 开发的, 所以对 Go 的支持肯定最全面, 下面就使用 golang 的 client 来演示 dgraph 的操作.

    golang client 安装

    安装最新版的 client:

    go get github.com/dgraph-io/dgo/v200
    

    创建 schema

    代码:

     1  func NewDgraphClient() *dgo.Dgraph {
     2   conn, err := grpc.Dial("localhost:9080", grpc.WithInsecure())
     3   if err != nil {
     4     log.Fatal(err)
     5   }
     6  
     7   client := dgo.NewDgraphClient(api.NewDgraphClient(conn))
     8  
     9   return client
    10  }
    11  
    12  func CreateSchema(client *dgo.Dgraph) error {
    13   schema := `
    14  name: string @index(term) .
    15  age: int .
    16  
    17  type Person {
    18    name
    19    age
    20  }
    21  `
    22   op := &api.Operation{Schema: schema}
    23  
    24   err := client.Alter(context.Background(), op)
    25   return err
    26  }
    

    执行成功后, 在 UI 界面(http://localhost:8000)上验证是否创建成功:

    schema(pred:[name, age]) {
      perdicate
      type
      index
    }
    

    结果如下:

    {
      "data": {
        "schema": [
          {
            "predicate": "age",
            "type": "int"
          },
          {
            "predicate": "name",
            "type": "string",
            "index": true
          }
        ]
      },
      ... 省略 ...
    }
    

    数据的 CURD

    首先, 新增数据

     1  type Person struct {
     2   Uid     string   `json:"uid"`
     3   Name    string   `json:"name"`
     4   Age     int      `json:"age"`
     5   Friends []Person `json:"friends"`
     6  }
     7  
     8  func AddSomeData(client *dgo.Dgraph) error {
     9   p1 := &Person{
    10     Name: "Dog",
    11     Age:  10,
    12   }
    13   p1.Friends = make([]Person, 0)
    14  
    15   p2 := &Person{
    16     Name: "Monkey",
    17     Age:  20,
    18   }
    19   p3 := &Person{
    20     Name: "Cat",
    21     Age:  30,
    22   }
    23  
    24   p1.Friends = append(p1.Friends, *p2)
    25   p1.Friends = append(p1.Friends, *p3)
    26  
    27   mu := &api.Mutation{CommitNow: true}
    28   pb, err := json.Marshal(p1)
    29   if err != nil {
    30     return err
    31   }
    32  
    33   mu.SetJson = pb
    34   _, err = client.NewTxn().Mutate(context.Background(), mu)
    35   return err
    36  }
    

    查询数据:

     1  func QueryData(client *dgo.Dgraph) error {
     2   q := `
     3  query q($name: string){
     4      q(func:allofterms(name, $name)){
     5          name
     6          age
     7          uid
     8          friends{
     9              name
    10              age
    11              uid
    12          }
    13      }
    14  }
    15  `
    16   txn := client.NewTxn()
    17   res, err := txn.QueryWithVars(context.Background(), q, map[string]string{"$name": "Dog"})
    18   if err != nil {
    19     return err
    20   }
    21   fmt.Println(res.String())
    22   return nil
    23  }
    

    为了简化, 返回值中我直接打印了 string 格式, 其实返回的是个 json 结构.
    可以看出, 返回值中包含了上一步创建的 3 个 Person, 其中 2 个作为 Dog 的 friends 返回的.

    更新数据:

    1  func UpdateData(client *dgo.Dgraph) error {
    2   mu := &api.Mutation{
    3     CommitNow: true,
    4     SetNquads: []byte(`<0xfffd8d67d832b975> <age> "12" .`),
    5   }
    6  
    7   _, err := client.NewTxn().Mutate(context.Background(), mu)
    8   return err
    9  }
    

    其中 <0xfffd8d67d832b975> 是数据的 uid, 根据上面 query 示例的返回值中可以查找到.
    这里需要注意的是, 虽然是 int 类型, 但是它的值要用 双引号 围住.

    删除数据(删除数据的一个属性):

    1  func DeleteProp(client *dgo.Dgraph) error {
    2   mu := &api.Mutation{
    3     CommitNow: true,
    4     DelNquads: []byte(`<0xfffd8d67d832b976> <age> * .`),
    5   }
    6  
    7   _, err := client.NewTxn().Mutate(context.Background(), mu)
    8   return err
    9  }
    

    删除了 <0xfffd8d67d832b976> 这条数据的 属性, <0xfffd8d67d832b976> 是上面 name="Monkey" 的那条数据.

    将数据的属性和关系都删除之后, 这条数据就相当于删除了.
    直接根据 Uid 删除数据的 api 也有, 但是使用后无效(具体我提了个 issue 到 dgraph 的代码库)

    事务

    draph 是支持事务的, 上面的例子中其实已经使用了事务, 只不过每个事务中只有一个操作.
    如果有多个操作, 类似下面这样的代码即可:

     1  ctx := context.Background()
     2  tnx := client.NewTxn()
     3  
     4  _, err := tnx.Mutate(ctx, mu1)
     5  if err !=  nil {
     6         tnx.Discard(ctx)
     7  }
     8  _, err = tnx.Mutate(ctx, mu2)
     9  if err !=  nil {
    10         tnx.Discard(ctx)
    11  }
    12  
    13  tnx.Commit(ctx)
    

    总结

    图数据库不是万能的, 它的目的也不是取代关系数据库.
    我们根据使用场景在合适的时候选用 dgraph, 可以更加的轻松的完成数据分析, 而不用深陷 sql 的坑中.

  • 相关阅读:
    服务器状态码
    QuerySet中添加Extra进行SQL查询
    django配置一个网站建设
    MySQL数据库查询中的特殊命令
    125. Valid Palindrome
    121. Best Time to Buy and Sell Stock
    117. Populating Next Right Pointers in Each Node II
    98. Validate Binary Search Tree
    91. Decode Ways
    90. Subsets II
  • 原文地址:https://www.cnblogs.com/wang_yb/p/13204729.html
Copyright © 2011-2022 走看看