Redis ORM使用 Redis 作為關(guān)系數(shù)據(jù)庫(kù)的 ORM 框架
使用 Redis 作為類關(guān)系數(shù)據(jù)庫(kù)的 ORM 框架。
產(chǎn)出背景
項(xiàng)目的快速迭代,不僅需要敏捷的開(kāi)發(fā),還需具備較高性能的和穩(wěn)定性,單純用關(guān)系型數(shù)據(jù)庫(kù)有瓶頸,然后在關(guān)系型數(shù)據(jù)庫(kù)基礎(chǔ)上加分布式緩存或者進(jìn)程內(nèi)緩存有增加了開(kāi)發(fā)和維護(hù)成本,
剛好項(xiàng)目中在用Redis,就考慮基于Redis的Hash和SortedSet兩個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)設(shè)計(jì)類似關(guān)系型數(shù)據(jù)庫(kù)的ORM。經(jīng)過(guò)多個(gè)版本的迭代,現(xiàn)在已經(jīng)實(shí)現(xiàn)了ORM的基本功能,在應(yīng)用中發(fā)現(xiàn)維護(hù)和查看數(shù)據(jù)
不太方便,又開(kāi)發(fā)了[工作臺(tái)](https://github.com/weikaishio/redis_orm_workbench).
功能列表
- 基于對(duì)象的增、刪、改、查、統(tǒng)計(jì)
- 基于Map的增、刪、改、查、統(tǒng)計(jì)(方便用在redis_orm_workbench)
- 支持動(dòng)態(tài)創(chuàng)建表、刪除表、創(chuàng)建索引、重建索引
- 支持可配置的自動(dòng)同步到MySql數(shù)據(jù)庫(kù)(一般為了更方便的查詢統(tǒng)計(jì)所用)
使用說(shuō)明
- 模型定義的標(biāo)簽說(shuō)明
TagIdentifier = "redis_orm"
//定義是否索引,索引名自動(dòng)生成 e.g.fmt.Sprintf("%s%s_%s", KeyIndexPrefix, strings.ToLower(table.Name), strings.ToLower(columnName)),
TagIndex = "index"
//唯一索引 hash和走zscore一樣都是O(1) 針對(duì)IndexType_IdMember有效,IndexType_IdScore的索引本來(lái)就是唯一的~
TagUniqueIndex = "unique"
/*
要支持一種查詢條件就得增加一個(gè)索引,定義用&連接聯(lián)合索引中的字段,e.g.Status&Uid
組合索引 字符串則唯一!集合數(shù)據(jù)結(jié)構(gòu)決定;
除非用int64,44或224或2222來(lái)存放Score,即44:前4個(gè)字節(jié)uint32和后4個(gè)字節(jié)uint32
1、id作為score, 可以組合但是member唯一,唯一查詢可用
此情況下的組合索引,直接按順序拼接即可
2、id作為member,同一個(gè)member只能有一個(gè)score,該字段類型必須是長(zhǎng)整型,數(shù)值索引可用,可以查詢范圍
此情況下的組合索引,僅僅支持兩整型字段,左邊32位 右邊32位,支持范圍查詢的放左邊
*/
TagCombinedindex = "combinedindex"
//默認(rèn)值
TagDefaultValue = "dft"
//是否主鍵
TagPrimaryKey = "pk"
//自增~ 應(yīng)用于主鍵
TagAutoIncrement = "autoincr"
//配置在主鍵的tag上,配置了該tag才能生效,同步到數(shù)據(jù)庫(kù)
TagSync2DB = "sync2db"
//備注名
TagComment = "comment"
//是否支持自動(dòng)寫創(chuàng)建時(shí)間
TagCreatedAt = "created_at"
//是否支持自動(dòng)寫更新時(shí)間
TagUpdatedAt = "updated_at"
- 模型例子
type Faq struct {
Id int64 `redis_orm:"pk autoincr sync2db comment 'ID'"` //主鍵 自增 備注是ID
Unique int64 `redis_orm:"unique comment '唯一'"` //唯一索引
Type uint32 `redis_orm:"dft 1 comment '類型'"` //默認(rèn)值:1
Title string `redis_orm:"dft 'faqtitle' index comment '標(biāo)題'"` //默認(rèn)值 faqtitle, 索引,備注 標(biāo)題
Content string `redis_orm:"dft 'cnt' comment '內(nèi)容'"`
Hearts uint32 `redis_orm:"dft 10 comment '點(diǎn)贊數(shù)'"`
CreatedAt int64 `redis_orm:"created_at comment '創(chuàng)建時(shí)間'"` //入庫(kù)時(shí)自動(dòng)寫創(chuàng)建時(shí)間
UpdatedAt int64 `redis_orm:"updated_at comment '修改時(shí)間'"`
TypeTitle string `redis_orm:"combinedindex Type&Title comment '組合索引(類型&標(biāo)題)'"` //組合索引 用到Type和Title兩字段,字符串類型的索引,所以是唯一索引
TypeHearts int64 `redis_orm:"combinedindex Type&Hearts comment '組合索引(類型&贊數(shù))'"` //組合索引 非唯一索引
}
- 需要引用的庫(kù)、初始化方式等
import (
"github.com/mkideal/log"
"github.com/go-redis/redis"
"github.com/weikaishio/redis_orm"
"github.com/weikaishio/redis_orm/test/models"
)
func main() {
options := redis.Options{
Addr: "127.0.0.1:6379",
Password: "",
DB: 1,
}
redisClient := redis.NewClient(&options)
//注:已省略redisClient可用性檢測(cè)
engine := redis_orm.NewEngine(redisClient)
engine.IsShowLog(true)
driver := "mysql"
host := "127.0.0.1:3306"
database := "bg_db"
username := "root"
password := ""
dataSourceName := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&&allowOldPasswords=1&parseTime=true", username, password, host, database)
dbEngine, err := xorm.NewEngine(driver, dataSourceName)
if err != nil {
log.Error("NewEngine:%s,err:%v", dataSourceName, err)
return
}
//給redisORM對(duì)象設(shè)置同步到dbEngine數(shù)據(jù)庫(kù)對(duì)象,每90秒同步一次
engine.SetSync2DB(dbEngine, 90)
//退出之前會(huì)執(zhí)行同步到DB
defer engine.Quit()
faq := &models.Faq{
Type: 1,
Title: "Title",
Unique: 111,
Content: "Content",
}
//插入數(shù)據(jù)
engine.Insert(faq)
//查詢指定Id的數(shù)據(jù)
model := &models.Faq{
Id: 1,
}
has, err := engine.Get(model)
if err != nil {
log.Error("Get(%d) err:%v", model.Id, err)
return
}
//查詢指定條件的數(shù)據(jù)
searchCon := NewSearchConditionV2(faq.Unique, faq.Unique, 111)
var ary []model.Faq
count, err := engine.Find(0, 100, searchCon, &ary)
if err != nil {
log.Error("Find(%v) err:%v", searchCon, err)
return
}
//其他請(qǐng)見(jiàn)engine_curd.go、engine_curd_by_map.go里面的方法....更新、刪除等功能, 也可以看目錄下面的測(cè)試代碼
}
- 查看數(shù)據(jù)
建議使用配套的redis_orm_workbench來(lái)管理,可以維護(hù)表結(jié)構(gòu)、數(shù)據(jù)和索引,方便直接在上面新增、修改和刪除行數(shù)據(jù)。
也可以直接用redis-cli來(lái)查看數(shù)據(jù),前綴tb:和ix:分別查看表數(shù)據(jù)和索引。
評(píng)論
圖片
表情
