Go实战--golang中使用RethinkDB(gorethink/gorethink.v3)
来源:互联网 发布:淘宝企业店铺的条件 编辑:程序博客网 时间:2024/04/29 01:08
生命不止,继续go go go !!!
关于golang中操作数据库,曾经介绍了不少:
Go实战–go语言操作sqlite数据库(The way to go)
Go实战–go语言操作MySQL数据库(go-sql-driver/mysql)
Go实战–golang中使用redis(redigo和go-redis/redis)
Go实战–golang中使用MongoDB(mgo)
今天继续跟大家一起学习分享另一种数据库叫 RethinkDB。
RethinkDB
RethinkDB 是一个主要用来存储 JSON 文档的数据库引擎(MongoDB 存储的是 BSON),可以轻松和多个节点连成分布式数据库,非常好用的查询语言以及支持表的 joins 和 group by 操作等,其实跟mongodb类似。
RethinkDB pushes JSON to your apps in realtime.
When your app polls for data, it becomes slow, unscalable, and cumbersome to maintain.
RethinkDB is the open-source, scalable database that makes building realtime apps dramatically easier.
What is RethinkDB?
RethinkDB is the first open-source, scalable JSON database built from the ground up for the realtime web. It inverts the traditional database architecture by exposing an exciting new access model – instead of polling for changes, the developer can tell RethinkDB to continuously push updated query results to applications in realtime. RethinkDB’s realtime push architecture dramatically reduces the time and effort necessary to build scalable realtime apps.
In addition to being designed from the ground up for realtime apps, RethinkDB offers a flexible query language, intuitive operations and monitoring APIs, and is easy to setup and learn.
官网
https://www.rethinkdb.com/
Windows下安装
下载地址:
https://www.rethinkdb.com/docs/install/windows/
解压
创建数据目录:
d:\RethinkDB\data\
运行命令:
rethinkdb.exe -d d:\RethinkDB\data\
成功
In recursion: removing file 'd:\RethinkDB\data\\tmp'warn: Trying to delete non-existent file 'd:\RethinkDB\data\\tmp'Initializing directory d:\RethinkDB\data\Running rethinkdb 2.3.6-windows (MSC 190024215)...Running on 6.2.9200 (Windows 8, Server 2012)Loading data from directory d:\RethinkDB\data\Listening for intracluster connections on port 29015Listening for client driver connections on port 28015Listening for administrative HTTP connections on port 8080Listening on cluster address: 127.0.0.1Listening on driver address: 127.0.0.1Listening on http address: 127.0.0.1To fully expose RethinkDB on the network, bind to all addresses by running rethinkdb with the `--bind all` command line option.Server ready, "LAPTOP_MNU6522J_xsq" b8612d2e-7c2b-4511-b85a-17468d91bf6d
可视化
http://localhost:8080
GoRethink - RethinkDB Driver for Go
github地址:
https://github.com/GoRethink/gorethink
Star:
1253
获取:
go get gopkg.in/gorethink/gorethink.v3
文档地址:
https://godoc.org/github.com/GoRethink/gorethink
ConnectOpts
type ConnectOpts struct { Address string `gorethink:"address,omitempty"` Addresses []string `gorethink:"addresses,omitempty"` Database string `gorethink:"database,omitempty"` Username string `gorethink:"username,omitempty"` Password string `gorethink:"password,omitempty"` AuthKey string `gorethink:"authkey,omitempty"` Timeout time.Duration `gorethink:"timeout,omitempty"` WriteTimeout time.Duration `gorethink:"write_timeout,omitempty"` ReadTimeout time.Duration `gorethink:"read_timeout,omitempty"` KeepAlivePeriod time.Duration `gorethink:"keep_alive_timeout,omitempty"` TLSConfig *tls.Config `gorethink:"tlsconfig,omitempty"` HandshakeVersion HandshakeVersion `gorethink:"handshake_version,omitempty"` UseJSONNumber bool NumRetries int InitialCap int `gorethink:"initial_cap,omitempty"` MaxOpen int `gorethink:"max_open,omitempty"` DiscoverHosts bool `gorethink:"discover_hosts,omitempty"` HostDecayDuration time.Duration NodeRefreshInterval time.Duration `gorethink:"node_refresh_interval,omitempty"` MaxIdle int `gorethink:"max_idle,omitempty"`}
func Connect
Connect creates a new database session.
func Connect(opts ConnectOpts) (*Session, error)
func Expr
Expr converts any value to an expression and is also used by many other terms such as Insert and Update. This function can convert the following basic Go types (bool, int, uint, string, float) and even pointers, maps and structs.
func Expr(val interface{}) Term
func (Term) Run
func (t Term) Run(s QueryExecutor, optArgs ...RunOpts) (*Cursor, error)
Run runs a query using the given connection.
func (*Cursor) One
func (c *Cursor) One(result interface{}) error
One retrieves a single document from the result set into the provided slice and closes the cursor.
func DB
func DB(args ...interface{}) Term
DB references a database.
func TableDrop
func TableDrop(args ...interface{}) Term
TableDrop deletes a table. The table and all its data will be deleted.
func TableCreate
func TableCreate(name interface{}, optArgs ...TableCreateOpts) Term
TableCreate creates a table. A RethinkDB table is a collection of JSON documents.
官方例子
main.go
package mainimport ( "fmt" "log" r "gopkg.in/gorethink/gorethink.v3")func main() { session, err := r.Connect(r.ConnectOpts{ Address: "localhost:28015", }) if err != nil { log.Fatalln(err) } res, err := r.Expr("Hello World").Run(session) if err != nil { log.Fatalln(err) } var response string err = res.One(&response) if err != nil { log.Fatalln(err) } fmt.Println(response)}
如果rethinkdb服务没有开启则:
2017/12/12 14:37:34 gorethink: dial tcp [::1]:28015: connectex: No connection could be made because the target machine actively refused it.
开启后运行:
Hello World
rethinkdb应用
访问:
http://localhost:8080/#tables
创建一个database,命名为players
读写数据库
package mainimport ( "fmt" "log" "math/rand" "strconv" "time" r "gopkg.in/gorethink/gorethink.v3")//ScoreEntry for scorestype ScoreEntry struct { ID string `gorethink:"id,omitempty"` PlayerName string Score int}func main() { fmt.Println("Connecting to RethinkDB: localhost:28015") session, err := r.Connect(r.ConnectOpts{ Address: "localhost:28015", Database: "players", }) if err != nil { log.Fatal("Could not connect") } err = r.DB("players").TableDrop("scores").Exec(session) err = r.DB("players").TableCreate("scores").Exec(session) if err != nil { log.Fatal("Could not create table") } err = r.DB("players").Table("scores").IndexCreate("Score").Exec(session) if err != nil { log.Fatal("Could not create index") } for i := 0; i < 1000; i++ { player := new(ScoreEntry) player.ID = strconv.Itoa(i) player.PlayerName = fmt.Sprintf("Player %d", i) player.Score = rand.Intn(100) _, err := r.Table("scores").Insert(player).RunWrite(session) if err != nil { log.Fatal(err) } } for { var scoreentry ScoreEntry pl := rand.Intn(1000) sc := rand.Intn(6) - 2 res, err := r.Table("scores").Get(strconv.Itoa(pl)).Run(session) if err != nil { log.Fatal(err) } err = res.One(&scoreentry) scoreentry.Score = scoreentry.Score + sc _, err = r.Table("scores").Update(scoreentry).RunWrite(session) time.Sleep(100 * time.Millisecond) }}
可以通过localhost:8080可视化查看:
RethinkDB的CRUD
再来一个比较复杂的例子,代码结构会更好一点:
bookmarket_store.go
其中包括了:
create
update
Delete
getAll
GetByID
package mainimport ( "time" r "gopkg.in/gorethink/gorethink.v3")// Bookmark type reperesents the metadata of a bookmark.type Bookmark struct { ID string `gorethink:"id,omitempty" json:"id"` Name, Description, Location string Priority int // Priority (1 -5) CreatedOn time.Time Tags []string}// BookmarkStore provides CRUD operations against the Table "bookmarks".type BookmarkStore struct { Session *r.Session}// Create inserts the value of struct Bookmark into Table.func (store BookmarkStore) Create(b *Bookmark) error { resp, err := r.Table("bookmarks").Insert(b).RunWrite(store.Session) if err == nil { b.ID = resp.GeneratedKeys[0] } return err}// Update modifies an existing value of a Table.func (store BookmarkStore) Update(b Bookmark) error { var data = map[string]interface{}{ "description": b.Description, "location": b.Location, "priority": b.Priority, "tags": b.Tags, } // partial update on RethinkDB _, err := r.Table("bookmarks").Get(b.ID).Update(data).RunWrite(store.Session) return err}// Delete removes an existing value from the Table.func (store BookmarkStore) Delete(id string) error { _, err := r.Table("bookmarks").Get(id).Delete().RunWrite(store.Session) return err}// GetAll returns all documents from the Table.func (store BookmarkStore) GetAll() ([]Bookmark, error) { bookmarks := []Bookmark{} res, err := r.Table("bookmarks").OrderBy("priority", r.Desc("createdon")).Run(store.Session) err = res.All(&bookmarks) return bookmarks, err}// GetByID returns single document from the Table.func (store BookmarkStore) GetByID(id string) (Bookmark, error) { var b Bookmark res, err := r.Table("bookmarks").Get(id).Run(store.Session) res.One(&b) return b, err}
main.go
package mainimport ( "fmt" "log" "time" r "gopkg.in/gorethink/gorethink.v3")var store BookmarkStorevar id stringfunc initDB(session *r.Session) { var err error // Create Database _, err = r.DBCreate("bookmarkdb").RunWrite(session) if err != nil { log.Fatalf("[initDB]: %s\n", err) } // Create Table _, err = r.DB("bookmarkdb").TableCreate("bookmarks").RunWrite(session) if err != nil { log.Fatalf("[initDB]: %s\n", err) }}func changeFeeds(session *r.Session) { bookmarks, err := r.Table("bookmarks").Changes().Field("new_val").Run(session) if err != nil { log.Fatalf("[changeFeeds]: %s\n", err) } // Luanch a goroutine to print real-time updates. go func() { var bookmark Bookmark for bookmarks.Next(&bookmark) { if bookmark.ID == "" { // for delete, new_val will be null. fmt.Println("Real-time update: Document has been deleted") } else { fmt.Printf("Real-time update: Name:%s, Description:%s, Priority:%d\n", bookmark.Name, bookmark.Description, bookmark.Priority) } } }()}func init() { session, err := r.Connect(r.ConnectOpts{ Address: "localhost:28015", Database: "bookmarkdb", MaxIdle: 10, MaxOpen: 10, }) if err != nil { log.Fatalf("[RethinkDB Session]: %s\n", err) } r.Table("bookmarks").Delete().Run(session) // Create Database and Table. initDB(session) store = BookmarkStore{ Session: session, } // Subscribe real-time changes changeFeeds(session)}func createUpdate() { bookmark := Bookmark{ Name: "mgo", Description: "Go driver for MongoDB", Location: "https://github.com/go-mgo/mgo", Priority: 1, CreatedOn: time.Now(), Tags: []string{"go", "nosql", "mongodb"}, } // Insert a new document. if err := store.Create(&bookmark); err != nil { log.Fatalf("[Create]: %s\n", err) } id = bookmark.ID fmt.Printf("New bookmark has been inserted with ID: %s\n", id) // Retrieve the updated document. bookmark.Priority = 2 if err := store.Update(bookmark); err != nil { log.Fatalf("[Update]: %s\n", err) } fmt.Println("The value after update:") // Retrieve an existing document by id. getByID(id) bookmark = Bookmark{ Name: "gorethink", Description: "Go driver for RethinkDB", Location: "https://github.com/dancannon/gorethink", Priority: 1, CreatedOn: time.Now(), Tags: []string{"go", "nosql", "rethinkdb"}, } // Insert a new document. if err := store.Create(&bookmark); err != nil { log.Fatalf("[Create]: %s\n", err) } id = bookmark.ID fmt.Printf("New bookmark has been inserted with ID: %s\n", id)}func getByID(id string) { bookmark, err := store.GetByID(id) if err != nil { log.Fatalf("[GetByID]: %s\n", err) } fmt.Printf("Name:%s, Description:%s, Priority:%d\n", bookmark.Name, bookmark.Description, bookmark.Priority)}func getAll() { // Layout for formatting dates. layout := "2006-01-02 15:04:05" // Retrieve all documents. bookmarks, err := store.GetAll() if err != nil { log.Fatalf("[GetAll]: %s\n", err) } fmt.Println("Read all documents") for _, v := range bookmarks { fmt.Printf("Name:%s, Description:%s, Priority:%d, CreatedOn:%s\n", v.Name, v.Description, v.Priority, v.CreatedOn.Format(layout)) }}func delete() { if err := store.Delete(id); err != nil { log.Fatalf("[Delete]: %s\n", err) } bookmarks, err := store.GetAll() if err != nil { log.Fatalf("[GetAll]: %s\n", err) } fmt.Printf("Number of documents in the table after delete:%d\n", len(bookmarks))}func main() { createUpdate() getAll() delete()}
输出:
Real-time update: Name:mgo, Description:Go driver for MongoDB, Priority:1New bookmark has been inserted with ID: 1f98916d-a5d5-400b-828e-8a53d4193521Real-time update: Name:mgo, Description:Go driver for MongoDB, Priority:2The value after update:Name:mgo, Description:Go driver for MongoDB, Priority:1Real-time update: Name:gorethink, Description:Go driver for RethinkDB, Priority:1New bookmark has been inserted with ID: 0da9d082-265c-40e8-af54-7210a78cdb19Read all documentsName:gorethink, Description:Go driver for RethinkDB, Priority:1, CreatedOn:2017-12-12 15:10:13Name:mgo, Description:Go driver for MongoDB, Priority:2, CreatedOn:2017-12-12 15:10:13Real-time update: Document has been deletedNumber of documents in the table after delete:1
悲伤的消息
Today(OCTOBER 05, 2016) I have sad news to share. After more than seven years of development, the company behind RethinkDB is shutting down. We worked very hard to make RethinkDB successful, but in spite of all our efforts we were ultimately unable to build a sustainable business. There is a lot of information to unpack – over the next few months, I’ll write about lessons learned so the startup community can benefit from our mistakes.
如何评价RethinkDB公司倒闭?
https://www.zhihu.com/question/51345388?sort=created
尾声:
RethinkDB: why we failed
结论:
Pick a large market but build for specific users.
Learn to recognize the talents you’re missing, then work like hell to get them on your team.
Read The Economist religiously. It will make you better faster.
- Go实战--golang中使用RethinkDB(gorethink/gorethink.v3)
- Go实战--golang中使用go-spew(davecgh/go-spew)
- Go实战--golang中使用MongoDB(mgo)
- Go实战--golang中使用JWT(JSON Web Token)
- Go实战--golang中使用markdown(russross/blackfriday)
- Go实战--golang中使用firebase实时数据库(zabawaba99/firego)
- Go实战--golang中使用redis(redigo和go-redis/redis)
- Go实战--golang中使用WebSocket实时聊天室(gorilla/websocket、nkovacs/go-socket.io)
- Go实战--golang中使用echo和MySQL搭建api(labstack/echo、go-sql-driver/mysql)
- Go实战--golang中使用echo嵌入静态资源(labstack/echo、GeertJohan/go.rice)
- Go实战--golang中使用gRPC和Protobuf实现高性能api(golang/protobuf、google.golang.org/grpc)
- Go实战--golang中使用echo框架中JSONP(labstack/echo)
- Go实战--golang中OAuth2.0的使用(使用google账号进行登陆验证)
- Go实战--golang中使用echo框架中的HTTP/2、Server Push(labstack/echo、golang.org/x/net/http2)
- Go实战--golang中defer的使用(有事没事defer一下)
- Go实战--golang中使用图片和验证码(dchest/captcha)
- Go实战--golang中使用echo框架中的cors(labstack/echo、rs/cors)
- Go实战--golang中使用Goji微框架(Goji+Mongodb构建微服务)
- 保存图片到系统相册
- 哈希表(Hash Table)
- 十四、高级特性之切片
- jQuery插件模块化(SeaJS)及其调用方式
- HtmlWebpackPlugin以inine方式引入JS/CSS文件
- Go实战--golang中使用RethinkDB(gorethink/gorethink.v3)
- loj6015「网络流 24 题」星际转移(枚举+分层图最大流)
- java 常用算法--复习笔记--基本排序算法
- api-ms-win-crt-runtimel1-1-0.dll缺失解决方法
- postgre删除后500行数据
- 自动化运维工具SaltStack部署及案例
- 查找使用表空间的TABLE,INDEX,INDEX SUBPARTITION
- avcodec_copy_context() copy方式实现h264和mp3合成mp4
- Git的常用命令