gorm-sharding分表插件升级版

代码地址: GitHub - 137/gorm-sharding: Sharding 是一个高性能的 Gorm 分表中间件。它基于 Conn 层做 SQL 拦截、AST 解析、分表路由、自增主键填充,带来的额外开销极小。对开发者友好、透明,使用上与普通 SQL、Gorm 查询无差别.解决了原生sharding的三个问题:1.不支持不带分表键的查询 2,不支持不同分表策略的配置 3.没有配置分表的自定义sql可能因为无法解析而发生异常

更新点

💡

原生gorm-sharding支持的功能有限,在公共包common中做了功能的扩展

  • 本插件的gorm版本与现在的大部分服务一致v1.20.8,与原作者的不一致,避免版本冲突
  • 原sharding解析sql用的sqlParse不一定能成功解析一些自定义的复杂sql,所以遇到解析不了的直接扔给gorm处理。如果涉及到分表的则需改成可以被sharding识别的标准gorm sql写法
  • 原sharding本身不支持全表扫描,在此做了支持
  • 原sharding不支持全表汇总查询,在此做了对count和sum的支持
  • 原sharding不支持多分表配置不同分表策略,在此增加了配置接口

简要

Gorm Sharding 插件使用 SQL 解析器和替换将大表拆分为较小的表,将查询重定向到分片表。给您高性能的数据库访问。

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

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

注意事项

  • 1.不要自己拼接sql会导致无法识别分表键,目前解析的是gorm条件表达式,而不是sql树(binaryTree),所以无法支持原生sql的分表 建议写法.where().orderby().limit().offset().find这样子
  • 2.查询条件需要分表键,如果没有的话需要UnionFlag 配置为true才不会报错,但是会导致全表扫描,慎用

特征

  • 非侵入式设计。加载插件,指定配置,一切就完成了。
  • 快如闪电。没有基于网络的中间件,与 Go 一样快。
  • 多种数据库(PostgreSQL、MySQL)支持。
  • 集成主键生成器(Snowflake、PostgreSQL 序列、自定义等)。

快速上手

1. go mod引入

2. gorm插件加载

shardByOrderIdConf := gormsharding.Config{ShardingKey:        "order_id",NumberOfShards:      uint(shardingNumber),PrimaryKeyGenerator: gormsharding.PKCustom, PrimaryKeyGeneratorFn: func(_ int64) int64 {return 0},ShardingAlgorithm: func(value any) (suffix string, err error) {if orderId, ok := value.(string); ok {return fmt.Sprintf("_%04d", HashStr(orderId)%shardingNumber), nil}return "", errors.New("invalid orderId")},ShardingAlgorithmForUnion: func(tableId int) (suffix string, err error) {return fmt.Sprintf("_%04d", tableId), nil},UnionFlag: true,}db.Use(gormsharding.RegisterMultiConf(map[string]gormsharding.Config{"order":            shardByOrderIdConf,}))

原始代码加载方式:

    //分表中间件DBHandle.Use(sharding.Register(sharding.Config{ShardingKey:    ShardingKey,NumberOfShards: ShardingNumber,//PrimaryKeyGenerator: sharding.PKMySQLSequence,PrimaryKeyGenerator: sharding.PKCustom,PrimaryKeyGeneratorFn: func(_ int64) int64 {return 0},}, ShardTablesByUid...))

dao层调用

尽量采用gorm的标准写法,避免使用原生sql,可能导致无法分表

示例代码

    orm := dao.GetKpayDB()db := orm.DBHandle.Table("order")if order.Uid != 0 {db = orm.DBHandle.Table("uid_order")}getOrderCondition(order, db)db = db.Order(" create_tm desc ")if order.CurPage > 0 && order.PageSize > 0 {db = db.Limit(order.PageSize).Offset((order.CurPage - 1) * order.PageSize)}err = db.Find(&orders).Errorif err != nil && err != gorm.ErrRecordNotFound {_ = log.Error(nil, fmt.Sprintf("GetOrders error, err=%v", err))return}

工作原理

原理图

插件加载

Sharding实现了gorm接口

// Plugin GORM plugin interface
type Plugin interface {Name() stringInitialize(*DB) error
}

Initialize中执行了函数compile

参数预处理(分表主键算法、后缀处理)

Initialize中生成了gorm语句执行的钩子,switchConn主要处理双写的

func (s *Sharding) registerCallbacks(db *gorm.DB) {s.Callback().Create().Before("*").Register("gorm:sharding", s.switchConn)s.Callback().Query().Before("*").Register("gorm:sharding", s.switchConn)s.Callback().Update().Before("*").Register("gorm:sharding", s.switchConn)s.Callback().Delete().Before("*").Register("gorm:sharding", s.switchConn)s.Callback().Row().Before("*").Register("gorm:sharding", s.switchConn)s.Callback().Raw().Before("*").Register("gorm:sharding", s.switchConn)
}

sharding实现gorm的接口

type ConnPool interface {PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
}

实现的接口中都会调用resolve的函数 (解决旧查询拆分为全表查询和分表查询)

配置参数说明

以下标红的是本包中新增的字段

  1. UnionFlag
    • 类型:布尔值
    • 说明:表示是否启用联合查询标志。当为 true 时,即使没有分表键,也能够查询,但会扫描全表,需要注意性能问题。 建议配成false,暴露出没有分表键的查询
  2. DoubleWrite
    • 类型:布尔值
    • 说明:表示是否启用双写功能。当启用时,数据将同时写入主表和分表中。
  3. ShardingKey
    • 类型:字符串
    • 说明:指定用于分表的列名。例如,对于产品订单表,可以根据 user_id 来分表。
  4. NumberOfShards
    • 类型:无符号整数
    • 说明:指定分表的数量,即分表的个数
  5. tableFormat
    • 类型:字符串
    • 说明:指定分表的表名格式。在不重写ShardingAlgorithm 分表函数时,自动根据分表数量算出

  1. ShardingAlgorithm
    • 类型:函数
    • 说明:指定用于生成分表后缀的算法函数。该函数根据传入的列值,生成对应的分表后缀。
  2. ShardingAlgorithmForUnion
    • 类型:函数
    • 说明:与 ShardingAlgorithm 对应,用于处理全表扫描但无分表字段查询的情况。根据传入的表 ID,直接返回对应的分表后缀。
  3. ShardingSuffixs
    • 类型:函数
    • 说明:生成所有分表后缀的函数,用于支持迁移器和生成主键。在compile插件的时候生成函数--根据函数ShardingAlgorithm拼接后缀
  4. ShardingAlgorithmByPrimaryKey
    • 类型:函数
    • 说明:指定根据主键生成分表后缀的算法函数。当没有指定分表键时使用。
  5. PrimaryKeyGenerator
    • 类型:整数
    • 说明:指定主键生成器算法,可选项有 PKSnowflake、PKPGSequence 和 PKCustom
  6. PrimaryKeyGeneratorFn
    • 类型:函数
    • 说明:指定生成主键的算法函数。当使用自动增量类似的生成器时,可以忽略 tableIdx 参数。PrimaryKeyGenerator为 PKCustom时,直接返回0表示不做处理,让mysql自动递增

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/9558.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

传统鞋业如何转型?3D数字化技术让鞋业品牌焕发新机!

数字经济时代,3D数字化技术在各行业都得到广泛应用,这其中,传统的鞋服行业的发展也受到了3D数字化技术的影响,产生了深刻的变化,越来越多的鞋企品牌开始尝试3D数字化营销。 比如,时尚运动品牌VANS就在官网上…

论文AIGC检测让毕业生头疼,如何有效降低AI查重率!

在准备毕业论文的过程中,不知道大家有没有跟我一样,遇到这样棘手的问题。我们都知道在撰写完论文后,进行论文查重是我们必不可少的一步。于是,我拿着论文进行了论文重复率的检测,发现重复率只有2.8%,看到这…

探案录 | KingbaseES+SqlSugar为医疗用户排忧解难

在2024年的初春,某大型三甲医院的CT预约系统上线测试,如同新芽破土,充满了希望与活力。然而,仅仅两天后,一个技术难题如同迷雾中的幽灵,悄然出现:The connection pool has been exhausted…… 福…

三相两电平逆变器的Simulink仿真建模及SPWM

三相两电平逆变器的介绍 三相两电平逆变器的电路结构如下图所示,作为非常基本的电力电子电路,众多教科书中均有对该电路的原理介绍,本文不再对原理进行赘述,主要目的在于提供simulink仿真电路。下图即为三相两电平逆变器电路结构…

图文并茂:解析Spring Boot Controller返回图片的三种方式

欢迎来到我的博客,代码的世界里,每一行都是一个故事 图文并茂:解析Spring Boot Controller返回图片的三种方式 前言使用Base64编码返回图片使用byte数组返回图片使用Resource对象返回图片图片格式转换与性能对比 前言 在互联网的世界里&…

AI雷达智能销售名片小程序源码系统+企业商城+公司动态 带完整的安装代码包以及安装搭建教程

在数字化时代,企业的销售模式正在经历一场深刻的变革。为了更好地满足市场需求,提升销售效率,罗峰给大家分享一款集AI雷达智能销售名片、企业商城、公司动态于一体的源码系统。该系统不仅配备了完整的安装代码包,还附有详细的安装…

批量自定义重命名,一键添加顺序编号,文件夹管理更高效!

我们经常需要对文件夹进行管理和整理。然而,当面对大量需要改名的文件夹时,手动逐个修改不仅效率低下,还容易出错。那么,有没有一种方法能够批量自定义重命名文件夹,并在名称后自动添加顺序编号呢?答案是肯…

ABC352编程笔记

ABC352 编程笔记 题意&#xff1a;输入&#xff0c;四个数 a , b , c , d a,b,c,d a,b,c,d&#xff0c;若 d d d 在 c , d c,d c,d 之间&#xff0c;则输出 Yes&#xff0c;否则输出 No。 正解&#xff1a;直接判断。 #include <bits/stdc.h> //#define int long lo…

vscode正则匹配技巧

写正则表达式 下面是匹配加粗的单词或空格 \*\*[a-zA-Z\s]*\*\*vscode提取加粗的内容 altenter&#xff0c;再ctrlC复制选中的内容出来

DDD面试题:DDD聚合和表的对应关系是什么 ?(来自蚂蚁面试)

尼恩说在前面&#xff1a; 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如字节、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; DDD 的外部接口调用&#xff0c;应该放在…

深入了解二叉搜索树:原理、操作与应用

文章目录 二叉搜索树二叉搜索树的操作1.查找操作2.插入操作3.查找最大值或者最小值4.删除操作5.前序中序后序遍历 总结 二叉搜索树 形如上图的二叉树就是二叉搜索树&#xff0c;接下来我们来具体阐述一下什么是二叉搜索树。 二叉搜索树的概念&#xff1a;满足左子树的值小于根…

经济学SSCI期刊,中科院3区,IF=2+,难度不大,收稿范围广泛!

一、期刊名称 Information Economics and Policy 二、期刊简介概况 期刊类型&#xff1a;SSCI 学科领域&#xff1a;经济学 影响因子&#xff1a;2.8 中科院分区&#xff1a;3区 出版方式&#xff1a;订阅模式/开放出版 版面费&#xff1a;选择开放出版需支付$3190 三、…

C++ | Leetcode C++题解之第78题子集

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> t;vector<vector<int>> ans;void dfs(int cur, vector<int>& nums) {if (cur nums.size()) {ans.push_back(t);return;}t.push_back(nums[cur]);dfs(cur 1, nums);t.po…

yum仓库和NFS网络共享服务

一、yum 1.1yum的定义 yum是一个基于RPM包&#xff0c;构建的软件更新机制&#xff0c;能够自动解决软件包之间的依赖关系。解决了日常工作中的大量查找安装依赖包的时间 为什么会有依赖关系的发生 因为linux本身就是以系统简洁为自身优势&#xff0c;所以在安装操作系统的时…

Docker与Harbor:构建企业级私有Docker镜像仓库

目录 引言 一、本地私有仓库 &#xff08;一&#xff09;基本概述 &#xff08;二&#xff09;搭建本地私有仓库 1.下载registry镜像 2.启动容器 3.上传本地镜像 4.客户端下载镜像 二、Harbor简介 &#xff08;一&#xff09;什么是 Harbor &#xff08;二&#xff…

苹果15能用哪些充电宝?充电宝什么牌子好?好用充电宝排名

随着移动设备的普及和功能的不断强大&#xff0c;我们对于充电宝的需求也越来越高。尤其是对于苹果15用户来说&#xff0c;选择一款兼容性好、性能稳定的充电宝显得尤为重要。在市面上众多充电宝品牌中&#xff0c;如何选择适合苹果15的充电宝&#xff1f;究竟哪个牌子的充电宝…

在线扭蛋机小程序:商家稳占市场的新突破口

近几年&#xff0c;扭蛋机进入了爆发期&#xff0c;动漫、游戏的发展更是推动了市场的发展&#xff0c;我国扭蛋机正在蓬勃发展中。 不过&#xff0c;在市场规模扩大下&#xff0c;扭蛋机行业的竞争力也在同时加大&#xff0c;企业商家需要在市场竞争中寻求发展新思路&#xf…

C#进阶-OleDb操作Excel和数据库

在C#编程中&#xff0c;使用OleDb可以方便地实现对Excel文件和数据库的操作。本文探讨了在C#中使用OleDb技术操作Excel和数据库的策略。文章详述了OleDb的定义、配置环境的步骤&#xff0c;并通过实际代码示例演示了如何高效读写Excel文件和交互数据库。文中还评估了OleDb技术的…

KaiwuDB 参编的《分析型数据库技术要求》标准正式发布

近期&#xff0c;中国电子工业标准化技术协会正式发布团体标准《分析型数据库技术要求》&#xff08;项目号&#xff1a;T-CESA 2023-006&#xff09;。该标准由中国电子技术标准化研究院、KaiwuDB&#xff08;上海沄熹科技有限公司&#xff09; 等国内 16 家企业联合起草&…

AI图书推荐:给自媒体创作者的ChatGPT使用指南

你是否厌倦了花费数小时盯着空白屏幕&#xff0c;努力为你的内容想出新鲜点子&#xff1f;想要将你的写作提升到下一个水平&#xff1f;有了ChatGPT&#xff0c;你可以告别写作障碍、无休止的修订和浪费的时间。 在这本全面的指南中&#xff0c;你将学到关于ChatGPT你需要知道…