Gorm Sharding

Gorm Sharding 是一个高性能的数据库分表中间件。

它基于 Conn 层做 SQL 拦截、AST 解析、分表路由、自增主键填充,带来的额外开销极小。对开发者友好、透明,使用上与普通 SQL、Gorm 查询无差别,只需要额外注意一下分表键条件。

文档

安装
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:123456@tcp(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{})
	}
}

image
配置 Sharding 中间件,为需要分表的业务表定义他们分表的规则

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/sharding"
)

	mysqlConfig := mysql.Config{
		DSN:                       "root:123456@tcp(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)
	}

image

posted @ 2023-06-16 22:58  耳东01  阅读(253)  评论(0)    收藏  举报