Go 每日一库之 nutsdb( 二 )
先插入 300 条数据 , 然后使用PrefixScan()从第 25 条数据开始 , 一共返回 100 条数据 。 需要注意的是 , 键是以字节顺序排列 , 所以user_21在user_209之后 。 观察输出:
...user_208 dj208user_209 dj209user_21 dj21user_210 dj210
范围遍历可以使用tx.RangeScan()只返回键在指定范围内的数据:
func main() {opt := nutsdb.DefaultOptionsopt.Dir = "./nutsdb"db, _ := nutsdb.Open(opt)defer db.Close()bucket := "user_list"prefix := "user_"db.Update(func(tx *nutsdb.Tx) error {for i := 1; i <= 300; i++ {key := []byte(prefix + strconv.FormatInt(int64(i), 10))val := []byte("dj" + strconv.FormatInt(int64(i), 10))tx.Put(bucket, key, val, 0)}return nil})db.View(func(tx *nutsdb.Tx) error {lbound := []byte("user_100")ubound := []byte("user_199")entries, _ := tx.RangeScan(bucket, lbound, ubound)for _, entry := range entries {fmt.Println(string(entry.Key), string(entry.Value))}return nil})}
获取全部调用tx.GetAll()返回某个桶中所有的数据:
func main() {opt := nutsdb.DefaultOptionsopt.Dir = "./nutsdb"db, _ := nutsdb.Open(opt)defer db.Close()bucket := "user_list"prefix := "user_"db.Update(func(tx *nutsdb.Tx) error {for i := 1; i <= 300; i++ {key := []byte(prefix + strconv.FormatInt(int64(i), 10))val := []byte("dj" + strconv.FormatInt(int64(i), 10))tx.Put(bucket, key, val, 0)}return nil})db.View(func(tx *nutsdb.Tx) error {entries, _ := tx.GetAll(bucket)for _, entry := range entries {fmt.Println(string(entry.Key), string(entry.Value))}return nil})}
数据结构相比其他数据库 , nutsdb比较强大的地方在于它支持多种数据结构:list/set/sorted set 。 命令主要仿造redis命令编写 。 这三种结构的操作与redis中对应的命令非常相似 , 本文简单介绍一下list相关方法 , set/sorted set可自行探索 。
nutsdb中支持的list方法如下:
- LPush:从头部插入一个元素;
- RPush:从尾部插入一个元素;
- LPop:从头部删除一个元素;
- RPop:从尾部删除一个元素;
- LPeek:返回头部第一个元素;
- RPeek:返回尾部第一个元素;
- LRange:返回指定索引范围内的元素;
- LRem:删除指定数量的值等于特定值的项;
- LSet:设置某个索引的值;
- Ltrim:只保留指定索引范围内的元素 , 其它都移除;
- LSize:返回list长度 。
func main() {opt := nutsdb.DefaultOptionsopt.Dir = "./nutsdb"db, _ := nutsdb.Open(opt)defer db.Close()bucket := "list"key := []byte("userList")db.Update(func(tx *nutsdb.Tx) error {// 从头部依次插入多个值 , 注意顺序tx.LPush(bucket, key, []byte("user1"), []byte("user3"), []byte("user5"))// 当前list:user5, user3, user1// 从尾部依次插入多个值tx.RPush(bucket, key, []byte("user7"), []byte("user9"), []byte("user11"))// 当前list:user5, user3, user1, user7, user9, user11return nil})db.Update(func(tx *nutsdb.Tx) error {// 从头部删除一个值tx.LPop(bucket, key)// 当前list:user3, user1, user7, user9, user11// 从尾部删除一个值tx.RPop(bucket, key)// 当前list:user3, user1, user7, user9// 从头部删除两个值tx.LRem(bucket, key, 2)// 当前list:user7, user9return nil})db.View(func(tx *nutsdb.Tx) error {// 头部第一个值 , user7b, _ := tx.LPeek(bucket, key)fmt.Println(string(b))// 长度l, _ := tx.LSize(bucket, key)fmt.Println(l)return nil})}
注意不要在同一个Update中执行插入和删除 。数据库备份nutsdb可以很方便地进行数据库备份 , 只需要调用db.Backup() , 传入备份存放目录即可:
func main() {opt := nutsdb.DefaultOptionsopt.Dir = "./nutsdb"db, _ := nutsdb.Open(opt)key := []byte("name")val := []byte("dj")db.Update(func(tx *nutsdb.Tx) error {tx.Put("", key, val, 0)return nil})db.Backup("./backup")db.Close()opt.Dir = "./backup"backupDB, _ := nutsdb.Open(opt)backupDB.View(func(tx *nutsdb.Tx) error {e, _ := tx.Get("", key)fmt.Println(string(e.Value))return nil})}
上面先备份 , 再从备份中加载数据库 , 读取键 。总结大家如果发现好玩、好用的 Go 语言库 , 欢迎到 Go 每日一库 GitHub 上提交 issue
参考
- nutsdb GitHub:
- Go 每日一库 GitHub:
- 纠结|硬杠红米Note9Pro?iQOO Z1跌至1575,对比之后纠结了!
- 王兴称美团优选目前重点是建设核心能力;苏宁旗下云网万店融资60亿元;阿里小米拟增资居然之家|8点1氪 | 美团
- 长安|长安傍上华为这个大腿,市值暴涨500亿!可见华为影响力之大?
- 巅峰|realme巅峰之作:120Hz+陶瓷机身+5000mAh 做到了颜值与性能并存
- 蛋壳公寓|官媒发声:绝不能让“割韭菜者”一跑了之!
- 看过明年的iPhone之后,现在下手的都哭了
- 直播销售员|石家庄桥西区插上“互联网+”智慧发展之翼
- 精英|业务流程图怎么绘制?销售精英的经验之谈
- 砍单|iPhone12之后,拼多多又将iPhone12Pro拉下水
- 报名啦!宿迁开展第五届“十大科技之星”评选