dgraph 使用簡介

dgraph 簡介

dgraph 是基於 golang 開發的開源的分佈式圖數據庫. 誕生時間不長, 發展卻很迅速. 目前是 v20.x 版本, dgraph 集羣主要包含 3 種節點:git

  1. Zero: 是集羣的核心, 負責調度集羣服務器和平衡服務器組之間的數據
  2. Alpha: 保存數據的 謂詞索引. 謂詞包括數據的 屬性 和數據之間的 關係; 索引是爲了更快的進行數據的過濾和查找
  3. Ratel: dgraph 的 UI 接口, 能夠在此界面上進行數據的 CURD, 也能夠修改數據的 schema

經過增長 Alpha 的數量完成 dgraph 的水平擴展.github

dgraph 是 golang 開發的, 因此部署很是簡單, 更簡單的方式是使用 dockergolang

docker pull dgraph/dgraph:latest

而後配置一個 docker-comopse.yml, 一鍵啓動 dgraph 服務:sql

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

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.json

dgraph 自己就是基於 golang 開發的, 因此對 Go 的支持確定最全面, 下面就使用 golang 的 client 來演示 dgraph 的操做.api

golang client 安裝

安裝最新版的 client:bash

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 的坑中.

相關文章
相關標籤/搜索