一个基于差异同步数据库结构的工具 - Skeema

请添加图片描述

本文是 GO 三方库推荐的第 5 篇,继续介绍数据库 schema 同步工具,我前面已经写了两篇这个主题的文章。系列查看:Golang 三方库。

今天,推荐是的一个基于差异实现数据库 schema 迁移的工具库 - skeema,同样由 Go 实现。

背景

我的上家公司时,有名架构师开发了一个类似于 skeema 的工具,也是基于差异同步表结构的,区别在于那个工具使用的 yaml 声明表结构定义的。我当时就想在市面上找一个类似的工具,但没找到。好在通过 ChatGPT,搜索效率提升很多,不过也是一步步的引导才让我找到这个工具。

概述

Skeema 是基于差异同步数据库 schema,这让我们只要表结构的终态就行。 还有,skeema 支持在不同环境间同步数据库 schema。

Skeema 支持 linter 识别 SQL 语句,方便我们将其集成到 CICD 中提升 Schema 质量。还有,它默认是禁用了一些不安全的数据库操作,如删表删字段等操作。

如果要说缺点,它现在只支持 MySQL 和 MariaDB。

安装

Skeema 的安装过程直接了当。如果你使用的是 MacOS,可以通过Homebrew来安装:

brew install skeema/tap/skeema

或是也可通过 go get 安装,但 Go 的版本要求在 v1.21+。

$ go install github.com/skeema/skeema@v1.11.1

对于其他平台,可以从Skeema的GitHub页面下载二进制文件,并按照文档指引进行安装。

使用

Skeema 的使用可概括为 5 个核心步骤:

  • 通过 skeema init 下载初始建表 SQL;
  • 基于初始 SQL 按需求修改文件;
  • 使用 skeema diff 在提交前确认差异;
  • 使用 skeema lint 检查 SQL 是否满足 linter 规则;
  • 使用 skeema push 推送 SQL,变更数据库 schema。

我将按这个步骤展开介绍。

初始化

首先,通过 skeema init 实现基于现有的数据库结构初始我们的目录,生成初始建表语句。

示例如下:

$ skeema init -h 127.0.0.1 -uroot -ppassword --schema blog -d .

--schema 用于指定目标库名称,如果没有指定,会生成实例下所有库的建表 SQL。而 -d/--dir 用于指定目标目录。

现在,回车确认和输入密码执行命令。

由于我这个 blog 数据库没有任何内容,只会在当前目录下生成一个 .skeema 文件,它也就是 skeema 的配置文件。

打开它,查看内容如下:

default-character-set=utf8mb4
default-collation=utf8mb4_0900_ai_ci
generator=skeema:1.11.1-community
schema=blog[production]
flavor=mysql:8.3
host=127.0.0.1
port=3306
user=root

如果想在接下来执行其他命令时,省略掉 -p 输入密码的步骤,可加上密码配置。

...
port=3306
user=root
password=password

这一步会在指定目录下创建数据库架构的本地表示。

而如果我没有指定 --schema 选项,将会把数据库中所有库表初始化到我的目录下。

$ ls -a
.skeema  article  blog  core

生成差异

现在尝试做一些变更,article 库下的有一个名为 comments 的表,它的建表语句如下所示:

CREATE TABLE `comments` (`id` int NOT NULL,`post_id` int NOT NULL,`author_name` int NOT NULL,`comment` text NOT NULL,`update_at` timestamp NULL DEFAULT NULL,`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

我将在其中添加一个 author_id 字段,修改的建表语句如下所示。

CREATE TABLE `comments` (...`author_id` varchar(255) NOT NULL,...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

现在,让我们使用 skeema diff 查看差异。

$ skeema diff
2024-02-22 18:53:09 [INFO]  Generating diff of 127.0.0.1:3306 article vs/Users/jian.xue/demo/databasemigration/skeema2-demo/article/*.sql
-- instance: 127.0.0.1:3306
USE `article`;
ALTER TABLE `comments` ADD COLUMN `author_id` int NOT NULL AFTER `post_id`;
2024-02-22 18:53:09 [INFO]  127.0.0.1:3306 article: diff complete
...

从上得到在 comments 新增 author_id,要执行的 SQL 是:

ALTER TABLE `comments` ADD COLUMN `author_id` int NOT NULL AFTER `post_id`;

这个命令成功输出了当前目录下建表语句的结构与数据库中表结构的差异。通过查看这个差异,即可确认是否是我们预期的 SQL。

但问题是,和代码审阅一样,如果所有问题都是依靠人来检查,则很难最大限度降低问题发生的可能性。在代码审阅的流程中,通过会加入 linter 工具,SQL 同样也可以有这流程。好在,skeema 也提供了类似这样 lint 能力。

Linter

Skeema 内置了一个linter 工具,检查表结构定义语句,防止一些常规的问题。

运行命令:

skeema lint

Skeema 提供有大量规则选项,有兴趣去看下它的官方文档:Option Reference。

如下是我列举一些常见的大家感兴趣的规则:

# 设置默认的字符集,推荐使用 utf8mb4 以支持全字符集
default-character-set=utf8mb4# 确保所有表和列使用推荐的字符集
lint-charset=error
allow-charset=utf8mb4# 确保所有表使用推荐的存储引擎,如 InnoDB
lint-engine=error
allow-engine=innodb# 推荐使用合适的数据类型作为主键,通常是整数类型
lint-pk-type=error
allow-pk-type=int,bigint# 根据团队策略对外键使用进行限制,如果避免使用外键以提升性能
lint-has-fk=warning# 确保自增列使用合适的数据类型,避免未来可能的整数溢出
lint-auto-inc=error# 避免重复或冗余的索引
lint-dupe-index=error# 如果应用策略限制了存储过程和函数的使用
lint-has-routine=warning# 确保表使用一致的命名规则,如全部小写
lint-name-case=error

现在尝试对 comments 做一些变更,测试能检查出主键类型错误和索引问题。

CREATE TABLE `comments` (`id` CHAR(32) NOT NULL,`post_id` int NOT NULL,`author_name` int NOT NULL,`comment` text NOT NULL,`update_at` timestamp NULL DEFAULT NULL,`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`),KEY `idx_post_id` (`post_id`),KEY `idx_post_id_duplicate` (`post_id`), -- 重复的索引,与 idx_post_id 完全相同
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

执行如下命令:

$ skeema lint
2024-02-23 15:55:55 [INFO]  Linting /xxxx/skeema-demo
2024-02-23 15:55:55 [INFO]  Linting /xxxx/skeema-demo/article
2024-02-23 15:55:55 [INFO]  Wrote/xxxx/skeema-demo/article/comments.sql(500 bytes)
2024-02-23 15:55:55 [ERROR] /xxxx/skeema-demo/article/comments.sql:2:Column id of table `comments` is using data type char(32), whichis not configured to be permitted in a primary key. The followingdata types are listed in option allow-pk-type: int.
2024-02-23 15:55:55 [ERROR] /xxxx/skeema-demo/article/comments.sql:10:Indexes idx_post_id_duplicate and idx_post_id of table `comments`are functionally identical.One of them should be dropped. Redundant indexes waste disk space,and harm write performance.
2024-02-23 15:55:55 [ERROR] Found 2 errors

提示索引类型错误:

Column id of table `comments` is using data type char(32), which
is not configured to be permitted in a primary key. The following
data types are listed in option allow-pk-type: int.

提示重复索引错误:

Indexes idx_post_id_duplicate and idx_post_id of table `comments`
are functionally identical.
One of them should be dropped. Redundant indexes waste disk space,
and harm write performance.

skeema 有社区版和商业版,有一些能力检查规则要商业版支持。

应用变更

skeema 使用的最后一步是应用这些变更,使用 skeema push 命令即可将更新应用到数据库。这个没啥可介绍的了。

多环境配置

skeema 支持多环境的不同配置,上面的配置实例中其实已经能看出了。其中有一个 production 段。

default-character-set=utf8mb4
default-collation=utf8mb4_0900_ai_ci
generator=skeema:1.11.1-community
schema=blog[production]
flavor=mysql:8.3
host=127.0.0.1
port=3306
user=root

如我增加一个 dev 环境,命令如下:

$ skeema add-environment dev --host 127.0.0.1 -uroot -ppassword

配置如下:

[dev]
flavor=mysql:8.3
host=127.0.0.1
port=3306
user=root
password=password

使用时,只要在命令后加上环境名称即可,如:

$ skeema push dev

还有,在不同环境下使用不同 lint 规则,这也是可以的。

安全操作

还有一定要说明,记住 skeema 默认是不允许一些非安全的操作,如删表、列其它如修改导致数据截断啥的等等操作。这也是很符合实际场景的。不然,因为某操作,导致删掉一些数据就完犊子了。

如果有非安全操作的需求,如在开发环境,不喜欢保留一些开发期间临时创建的表,配置 allow-unsafe=true 即可。

[dev]
...
allow-unsafe=true

总结

Skeema 作为一个基于差异同步数据库 schema 的工具,简单强大。它简化了数据库 schema 的管理。使得我们无论是开发新功能时管理架构变更,还是在多环境中同步数据库架构,Skeema都能提供有效的支持,都不再复杂。

最后,如果你和我曾经一样,为不同环境间的数据库表结构管理同步感到头痛,试试 Skeema,或许你会喜欢这种方式。

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

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

相关文章

数字孪生10个技术栈:数据采集的八种方式

大家好,我是贝格前端工场,上期讲了数字孪生10个技术栈(总括):概念扫盲和总体介绍,获得了大家的热捧,本期继续分享技术栈,大家如有数字孪生或者数据可视化的需求,可以联络我们。 一、…

【好书推荐-第九期】Sora核心技术相关书籍《扩散模型:从原理到实战》与《GPT 图解:大模型是怎样构建的》:Sora的两大核心技术,都藏在这两本书里!

😎 作者介绍:我是程序员洲洲,一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公众号:洲与AI。 🎈 本文专栏:本文收录…

解决DBeaver执行脚本报错No active connection

解决DBeaver执行脚本报错No active connection 1、报错问腿 2、问题解决 2.1、右键点击该数据库,选择SQL编辑器,选择新建SQL编辑器,然后将sql语句复制过去。 或者左击选中数据库后直接使用快捷键 Ctrl] 2.2、在Project-General中找到Scr…

Javaweb之SpringBootWeb案例之自动配置案例的自定义starter测试的详细解析

3.2.4.3 自定义starter测试 阿里云OSS的starter我们刚才已经定义好了,接下来我们就来做一个测试。 今天的课程资料当中,提供了一个自定义starter的测试工程。我们直接打开文件夹,里面有一个测试工程。测试工程就是springboot-autoconfigurat…

常见排序算法解析

芝兰生于深林,不以无人而不芳;君子修道立德,不为穷困而改节 文章目录 插入排序直接插入排序希尔排序 选择排序直接选择排序堆排序 交换排序冒泡排序快速排序优化挖坑法前后指针法非递归版 归并排序递归非递归 总结 插入排序 插入排序&#…

【编程小记】在Windows下使用C/C++代码判断一个文件是否被其他进程占用

在Windows下使用C/C代码判断文件是否被占用 一、原理二、函数简单介绍三、实例代码 一、原理 在Windows下有一个Windows API叫做CreateFile,通过这个接口我们可以创建或打开文件,我们打开文件时可以采用独占模式进行打开,如果能够打开文件说…

Word Game

题目链接&#xff1a;Problem - C - Codeforces 解题思路&#xff1a; 用map存字母和出现的次数&#xff0c;然后遍历三个字母数组&#xff0c;如果map值为1&#xff0c;则加三分&#xff0c;为2加1分&#xff0c;否则不加分。 下面是c代码&#xff1a; #include<iostrea…

第41期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

Linux学习-二级指针的使用

目录 ###指针传参时要用二级指针 ###函数体内部想要修改函数外部指针变量值的时候需要使用二级指针(指针变量的地址) ###指针传参时要用二级指针 char *str[5]; int Fun(char **ppstr,int len); ###函数体内部想要修改函数外部指针变量值的时候需要使用二级指针(指针变量的…

#微信小程序创建(获取onenet平台数据)

1.IDE&#xff1a;微信开发者工具 2.实验&#xff1a;创建一个小程序&#xff08;http get获取onenet平台数据&#xff09; 3.记录&#xff1a; 百度网盘链接&#xff1a;https://pan.baidu.com/s/1eOd-2EnilnhPWoGUMj0fzw 提取码: 2023 &#xff08;1&#xff09;新建一个工…

【C++STL详解 —— string类】

【CSTL详解 —— string类】 CSTL详解 —— sring类一、string的定义方式二、string的插入三、string的拼接四、string的删除五、string的查找六、string的比较七、string的替换八、string的交换九、string的大小和容量十、string中元素的访问十一、string中运算符的使用十二、…

2024年腾讯云发红包了,可用于抵扣订单金额,你们领了吗?

在2024年腾讯云新春采购节优惠活动上&#xff0c;可以领取新年惊喜红包&#xff0c;打开活动链接 https://curl.qcloud.com/oRMoSucP 会自动弹出红包领取窗口&#xff0c;如下图&#xff1a; 腾讯云2024新春采购节红包领取 如上图所示&#xff0c;点击“领”红包&#xff0c;每…

回溯算法01-组合(Java)

1.组合 题目描述 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4]]示例 2&#xff1a; 输入&#x…

VMware虚拟机安装Centos7图解,提供软件包镜像(详细安装,小白入门必看)

目录 1. 安装vmware软件 2. 下载centos7镜像 3. 使用镜像安装centos操作系统 3.1 创建新的虚拟机 3.2 开机安装系统 4. 尝试网络连通性 5. 配置静态ip地址 1. 安装vmware软件 下载链接&#xff08;包含激活码&#xff09;&#xff1a;VMware https://www.alipan…

C语言初学10:共同体

一、共同体作用 提供一种在相同内存位置存储不同数据类型的有效方式 二、共同体定义 union [union tag] //tag是可选参数 {member definition;member definition;...member definition; } [one or more union variables]; // 共同体变量是可选的 三、共同体占用空间大小 #…

vCity 2.8 – 在线浏览器元宇宙游戏平台(虚拟现实网页游戏平台)可获取现实金钱对接贝宝

vCity Nulled 是一个采用最新网络技术开发的在线浏览器游戏平台。vCity Free Download Scripts 是多功能游戏脚本&#xff0c;可帮助您根据自己的喜好创建自己的在线浏览器游戏&#xff0c;因为它有许多选项和设置&#xff0c;可以通过这些选项和设置来修改和创建您想要的浏览器…

亚信安慧AntDB:编织数据丝路,缔造创新篇章

亚信安慧AntDB作为一款具备国产化升级改造经验的数据库系统&#xff0c;在15年的平稳运行中积累了丰富经验。通过持续的创新和技术进步&#xff0c;AntDB不断优化性能和功能&#xff0c;满足用户的需求&#xff0c;与国际先进数据库系统保持竞争力。 AntDB秉承着与用户和行业保…

【广度优先搜索】【堆】【C++算法】407. 接雨水 II

作者推荐 【二分查找】【C算法】378. 有序矩阵中第 K 小的元素 本文涉及知识点 广度优先搜索 堆 LeetCoce407. 接雨水 II 给你一个 m x n 的矩阵&#xff0c;其中的值均为非负整数&#xff0c;代表二维高度图每个单元的高度&#xff0c;请计算图中形状最多能接多少体积的雨…

使用MockJS模拟数据,如何获取入参?

场景描述 在使用MockJS进行模拟数据的时候&#xff0c;会遇到一种场景&#xff0c;当参数1时&#xff0c;展示A类数据&#xff0c;当参数B时&#xff0c;展示B类数据&#xff0c;为了实现这场景&#xff0c;那就要在模拟数据时拿到请求参数&#xff1f; 实现逻辑 mock方法的…

遇见未来的你——陪伴是最长情的告白

目录 一、背景介绍二、思路&方案三、过程1.家庭中彼此的陪伴最长情2.事业中与合伙人与同事与朋友与产品的陪伴最长情3.人生中与计划与落实与啊哈的陪伴最长情4.肉体与灵魂分分合合的体验 四、总结 一、背景介绍 人有时候一转身就是一辈子&#xff0c;所以珍惜转身的每一个…