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