马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本插件集成了Bolt 和badfer两个纯Go实现的快速的嵌入式K/V数据库,方便开辟时本地存储使用。插件集成Bolt 和badfer两个,如果确定使用此中一个,也可以把此中不消的一个删除,不删除也不会有任何影响。
插件使用分析
1.安装插件
到busines背景的开辟者工具下的代码仓找到“Go语言嵌入式键值数据库”举行安装即可
2.代码分析
插件安装到utils\plugin目次中,此中在app\business\storage中有两个调用演示文件,一个是kv的字符串情势数据,一个是user用户对象信息json数据。
3.设置分析
在utils\plugin\storage\config\config.go的设置文件有两个参数 ,DataPath是创建的数据库文件存放位置,MetadataStorage是使用Bolt大概是badfer,默认是bolt。
4.怎样调用
调用直接 plugin.Storager.函数名 方式。比方:
- // 获取桶中数据列表
- func (t *Kv) List(offset, limit int) ([][]byte, error) {
- return plugin.Storager.List(t.key(""), offset, limit)
- }
- // 获取数据
- func (t *Kv) Get(key string) ([]byte, error) {
- return plugin.Storager.Get(t.key(key))
- }
- // 保存数据
- func (t *Kv) Set(key string, val []byte) error {
- return plugin.Storager.Set(t.key(key), val)
- }
- // 删除桶中的key
- func (t *Kv) Delete(key string) error {
- return plugin.Storager.Delete(t.key(key))
- }
- // 删除桶
- func (t *Kv) DeleteBucket() error {
- return plugin.Storager.DeleteBucket(t.key(""))
- }
- // 设置可以名称
- func (t *Kv) key(key string) string {
- return "kv/" + key
- }
复制代码 此中func (t *Kv) key(key string) string {}是设置key名称字符串。封装是约定传key是把桶和key用/拼接的字符串。调用是接口拿到字符串后分析拿到桶名和key名称。
5.接口调用示例代码
这是安装插件后端再app\business\storage\user.go得到演示代码,在开辟时你可以参数使用,完备代码如下:
- package storage
- import (
- "encoding/json"
- "gofly/utils/gf"
- "gofly/utils/plugin"
- "time"
- )
- type User struct {
- NoNeedLogin []string //忽略登录接口配置-忽略全部传[*]
- NoNeedAuths []string //忽略登录接口配置-忽略全部传[*]
- }
- // 定义用户数据结构体
- type UserData struct {
- ID string `json:"_id"`
- Name string `json:"name"`
- Role string `json:"role"`
- Salt string `json:"salt,omitempty"`
- Password string `json:"password,omitempty"`
- CreatedAt time.Time `json:"created_at"`
- }
- // 初始化路由
- func init() {
- fpath := User{NoNeedLogin: []string{"*"}, NoNeedAuths: []string{"*"}}
- gf.Register(&fpath, fpath)
- }
- // 创建数据
- func (api *User) AddData(c *gf.GinCtx) {
- param, _ := gf.RequestParam(c)
- red := api.Set(gf.String(param["id"]), UserData{ID: gf.String(param["id"]), Name: gf.String(param["name"]), Role: gf.String(param["role"]), CreatedAt: time.Now()})
- gf.Success().SetMsg("创建数据成功").SetData(red).Regin(c)
- }
- // 获取数据
- func (api *User) GetData(c *gf.GinCtx) {
- id := c.DefaultQuery("id", "")
- if id == "" {
- gf.Failed().SetMsg("参数id不能为空").Regin(c)
- return
- }
- data, err := api.Get(id)
- if err != nil {
- gf.Failed().SetMsg(err.Error()).Regin(c)
- return
- }
- gf.Success().SetMsg("获取数据成功").SetData(data).Regin(c)
- }
- // 删除字段数据
- func (api *User) DeleteData(c *gf.GinCtx) {
- param, _ := gf.RequestParam(c)
- if _, ok := param["id"]; !ok {
- gf.Failed().SetMsg("参数id不能为空").Regin(c)
- return
- }
- err := api.Delete(gf.String(param["id"]))
- if err != nil {
- gf.Failed().SetMsg(err.Error()).Regin(c)
- return
- }
- gf.Success().SetMsg("删除字段数据成功").Regin(c)
- }
- // 删除桶
- func (api *User) DelBucket(c *gf.GinCtx) {
- err := api.DeleteBucket()
- if err != nil {
- gf.Failed().SetMsg(err.Error()).Regin(c)
- return
- }
- gf.Success().SetMsg("删除桶成功").Regin(c)
- }
- // 获取数据列表
- func (api *User) GetList(c *gf.GinCtx) {
- offset := gf.Int(c.DefaultQuery("offset", "0"))
- pageSize := gf.Int(c.DefaultQuery("pageSize", "10"))
- list, err := api.List(offset, pageSize)
- if err != nil {
- gf.Failed().SetMsg(err.Error()).Regin(c)
- return
- }
- gf.Success().SetMsg("获取数据列表").SetData(list).Regin(c)
- }
- // 操作基础
- func (t *User) List(offset, limit int) ([]*UserData, error) {
- data, err := plugin.Storager.List(t.key(""), offset, limit)
- if err != nil {
- return nil, err
- }
- users := make([]*UserData, 0, len(data))
- for _, d := range data {
- u := new(UserData)
- err = json.Unmarshal(d, u)
- if err != nil {
- return nil, err
- }
- users = append(users, u)
- }
- return users, nil
- }
- func (t *User) Get(id string) (*UserData, error) {
- data, err := plugin.Storager.Get(t.key(id))
- if err != nil {
- return nil, err
- }
- u := new(UserData)
- err = json.Unmarshal(data, u)
- return u, err
- }
- func (t *User) Set(id string, val UserData) error {
- data, err := json.Marshal(val)
- if err != nil {
- return err
- }
- return plugin.Storager.Set(t.key(id), data)
- }
- // 删除桶中key
- func (t *User) Delete(id string) error {
- return plugin.Storager.Delete(t.key(id))
- }
- // 删除桶
- func (t *User) DeleteBucket() error {
- return plugin.Storager.DeleteBucket(t.key(""))
- }
- // 组装key包含桶名和用户的id
- func (t *User) key(id string) string {
- return "user/" + id
- }
复制代码 BoltDB 先容
BoltDB 是一个用 Go 语言编写的 嵌入式键值对数据库,基于 LMDB(Lightning Memory-Mapped Database)计划,专注于高性能和简朴性。它无需独立服务,直接嵌入到应用步伐中,得当单机场景,支持 ACID 事件。
1. 焦点特点
- 键值存储:数据以 []byte 格式存储,支持嵌套 Bucket(雷同定名空间)。
- 事件性:提供完备的 ACID 事件(读/写隔离),支持并发读,写操纵串行化。
- 零依赖:纯 Go 实现,无需外部服务或依赖库。
- 内存映射:通过内存映射文件提拔读取性能,写入通过 COW(写时复制)包管数据安全。
- B+树索引:数据按字典序排序,支持范围查询和前缀扫描。
2. 实用场景
- 小型到中型单机应用(如设置文件、缓存、会话存储)。
- 须要高可靠性的本地数据长期化(如 IoT 装备、桌面应用)。
- Go 生态项目快速集成轻量级存储。
BoltDB 是 Go 生态中轻量级、高可靠的嵌入式存储方案,得当须要简朴事件和本地长期化的场景,但需衡量其单机写入瓶颈和内存限定。
BadgerDB 先容
BadgerDB 是一个用 Go 语言编写的高性能键值对数据库,基于 LSM-Tree(Log-Structured Merge-Tree) 计划,专为高吞吐量写入和低耽误读取场景优化。与 BoltDB 差异,BadgerDB 通过肴杂内存与磁盘存储,支持海量数据的高效存取,同时保持 ACID 事件特性。
1. 焦点特点
- 写入先写入内存表(MemTable),再异步归并到磁盘(SSTable),得当高吞吐写入。
- 数据按层级归并(Compaction),自动优化存储结构。
- 大 Value 单独存储,淘汰 LSM-Tree 内部碎片,提拔查询服从。
- 支持快照隔离(Snapshot Isolation),包管事件划一性。
- 内存缓存热门数据,团结布隆过滤器(Bloom Filter)加速查询。
- 跨平台:纯 Go 实现,无外部依赖,支持 Linux/macOS/Windows。
2. 实用场景
- 高频写入场景:日志
收罗、实时指标存储、时序数据(如 IoT 装备数据)。
- 大 Value 存储:文档、图片等二进制数据(需开启键值分离)。
- 高并发读:缓存体系、元数据索引。
- 替换 LevelDB/RocksDB:需 Go 原生集成且无需 CGO 的场景。
|