dgraph 是基於 golang 開發的開源的分佈式圖數據庫. 誕生時間不長, 發展卻很迅速. 目前是 v20.x 版本, dgraph 集羣主要包含 3 種節點:git
經過增長 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 的 UI 界面, 能夠完成全部的操做, 但要想將 dgraph 和應用結合, 還得使用 dgraph 的 SDK.
dgraph 的 SDK 支持各類語言, 官方支持的主要有: Go, C#, Java, Javascript, Python.json
dgraph 自己就是基於 golang 開發的, 因此對 Go 的支持確定最全面, 下面就使用 golang 的 client 來演示 dgraph 的操做.api
安裝最新版的 client:bash
go get github.com/dgraph-io/dgo/v200
代碼:服務器
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 } ] }, ... 省略 ... }
首先, 新增數據
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 示例的返回值中能夠查找到.
這裏須要注意的是,
刪除數據(刪除數據的一個屬性):
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> 這條數據的
將數據的屬性和關係都刪除以後, 這條數據就至關於刪除了.
直接根據 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 的坑中.