基于go语言的高性能的数据库分表中间件介绍:Gorm Sharding
Gorm Sharding 是一个高性能的数据库分表中间件。
它基于 Conn 层做 SQL 拦截、AST 解析、分表路由、自增主键填充,带来的额外开销极小。
对开发者友好、透明,使用上与普通 SQL、Gorm 查询无差别,只需要额外注意一下分表键条件。
官方文档:
https://gorm.io/docs/sharding.html
中文版:
https://gorm.io/zh_CN/docs/sharding.html
github:
https://github.com/go-gorm/sharding
功能特点
非侵入式设计, 加载插件,指定配置,既可实现分表。
轻快, 非基于网络层的中间件,像 Go 一样快
支持多种数据库。 PostgreSQL 已通过测试,MySQL 和 SQLite 也在路上。
多种主键生成方式支持(Snowflake, PostgreSQL Sequence, 以及自定义支持)Snowflake 支持从主键中确定分表键。
安装
go get -u gorm.io/sharding
测试表结构
// ProjectLog 结构体
type ProjectLog struct {
global.GVA_MODEL
ID int64 `gorm:"primarykey"` // 主键ID
ProjectId int64 `json:"project_id" form:"project_id" gorm:"column:project_id;comment:;"`
UpdateContent datatypes.JSONType[project.Project] `json:"update_content" form:"update_content" gorm:"type:json;column:update_content;comment:;"`
UpdateContent2 datatypes.JSONType[project.Project] `json:"update_content2" form:"update_content2" gorm:"-"`
ParentId int64 `json:"parent_id" form:"parent_id" gorm:"column:parent_id;comment:;"`
}
// TableName ProjectLog 表名
func (p ProjectLog) TableName() string {
return "project_log"
}
迁移生成测试表
import (
"fmt"
"strconv"
"testing"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func TestMigrate(t *testing.T) {
mysqlConfig := mysql.Config{
DSN: "root:[email protected](127.0.0.1:3306)/admin_project?charset=utf8mb4&parseTime=True&loc=Local", // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
SkipInitializeWithVersion: false, // 根据版本自动配置
}
DB, err := gorm.Open(mysql.New(mysqlConfig))
if err != nil {
fmt.Println(err.Error())
return
}
//生成128张project_log表,具体数量看自己需要了。
for i := 0; i < 128; i++ {
tableName := fmt.Sprintf("project_log_%0*d", 3, i) //表名
DB.Table(tableName).AutoMigrate(&project_log.ProjectLog{})
}
}
迁移成功:
配置 Sharding 中间件,为需要分表的业务表定义他们分表的规则
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/sharding"
)
mysqlConfig := mysql.Config{
DSN: "root:[email protected](127.0.0.1:3306)/admin_project?charset=utf8mb4&parseTime=True&loc=Local", // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
SkipInitializeWithVersion: false, // 根据版本自动配置
}
DB, err := gorm.Open(mysql.New(mysqlConfig))
DB.Use(sharding.Register(sharding.Config{
ShardingKey: "company_id",
NumberOfShards: 128,
PrimaryKeyGenerator: sharding.PKSnowflake,
}, "project_log"))
//创建数据
DB.Create(&project_log.ProjectLog{Company_id: 1, ParentId: 1})
DB.Create(&project_log.ProjectLog{Company_id: 1, ParentId: 2})
DB.Create(&project_log.ProjectLog{Company_id: 1, ParentId: 3})
DB.Create(&project_log.ProjectLog{Company_id: 1, ParentId: 4})
依然保持原来的方式使用 db 来查询数据库。
你只需要注意在 CURD 动作的时候,明确知道 Sharding Key 对应的分表,
查询条件带 Sharding Key,以确保 Sharding 能理解数据需要对应到哪一个子表。
//查询数据
var data []project.ProjectLog
DB.Unscoped().Select("company_id,parent_id").Where("company_id = ?", 1).
Where("parent_id IN ?", []int{1, 2, 3, 4}).Find(&data)
for _, v := range data {
fmt.Printf("公司Company_id: %d,Parent_id: %d \n", v.Company_id, v.ParentId)
}
相关文章