Gorm实现多租户数据隔离

1,750 阅读1分钟

multi-tenancy

gorm多租户插件,实现租户数据库层面的数据隔离

说明

场景的数据隔离方案:

  • 独立数据库

为每一个租户配置一个独立的数据库,各租户之间的业务数据完全隔离。

  • 共享数据库,独立 Schema

不同的租户使用同一个数据库,每个租户独立分配一个Schema(也可叫做一个user)

  • 共享数据库,共享 Schema,共享数据表

在数据表中新增TenantID字段,通过字段进行数据隔离

安装

go get -u github.com/melf-xyzh/multi-tenancy  

使用方法

数据隔离(自动分库)

实现 TenantDBConn 接口,这样可以保证该租户的数据库链接按需创建,不使用不创建,避免占用链接资源

type TenantConn struct{}  
  
func (c TenantConn) CreateDBConn(tenant string) (db *gorm.DB, err error) {  
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情  
dsn := "root:123456789@tcp(127.0.0.1:3306)/test" + tenant + "?charset=utf8mb4&parseTime=True&loc=Local"  
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})  
return  
}  

注册并使用插件

// 链接主数据库  
dsn := "root:123456789@tcp(127.0.0.1:3306)/test1?charset=utf8mb4&parseTime=True&loc=Local"  
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})  
  
// 注册并使用  
mt := &plugin.MultiTenancy{}  
mt.Register("merchant_no", TenantConn{})  
db.Use(mt)  

简单使用

type User struct {  
gorm.Model  
MerchantNo string  
}  
  
func (User) TableName() string {  
return "user_table_name"  
}  
  
// 可以通过实现这个方法控制对该表是否开启数据隔离  
func (User) DataIsolation() bool {  
return true  
}  
  
// 注册自动迁移  
func (User) AutoMigrate(db *gorm.DB, tableName string) (err error) {  
if tableName == "" {  
err = db.AutoMigrate(User{})  
} else {  
err = db.Table(tableName).AutoMigrate(User{})  
}  
return  
}  
  
// 对需要分库的表在此进行注册  
plugin.MTPlugin.SetDataIsolation(  
User{},  
)  

分布式ID(雪花ID)

var Generator *id.DistributedIdGenerator  
  
Generator, err := id.InitDistributedIdGenerator("", 0)  
if err != nil {  
global.LOG.Error("初始化雪花ID生成器失败")  
return  
}  

字段加密保存

待实现……