经过1年断断续续的迭代,ClickHouse ORM 3.x 发布啦~说说它的故事吧。
说来惭愧上次写博客都是22年4月份了,今年行情不好团队急剧收缩,工作几乎全扑在接手存量业务和主业务线开发之中。21年团队规模大的时候,可以有一部分时间做基建并且有一定的技术产出。22年变成了一边缩减团队规模,一边做项目交接、开发主要业务,并没有太多技术层面的学习提升。裁员还一轮一轮,收入也走了下坡路,今年的情况想必大家都差不多,是真正的寒冬。
无论如何技术不能丢下,总还得积累。这一年技术项目主要升级了前端监控基础框架 Egg -> Midway,JS 也变为了 TS,重构优化了代码和数据库。开发开源了 node-clickhouse-orm 库。经过一年时间断断续续的迭代,现在已经发布了3.x版本,大版本更新的快,但实际并没有更新太多东西,这个后面再解释。
这篇文章将会聊聊 node-clickhouse-orm 库的诞生、发展和思考。
背景与起因
在前端监控系统中,我使用了 ClickHouse,为什么选择它可以从《天啦,从Mongo到ClickHouse我到底经历了什么?》这篇文章了解。这是一个比较新兴的列数据库,生态并不那么完善。而它本身主要用作数据分析,相对来说对于 ORM 的诉求不如行数据库,并且使用 NODEJS 的 ClickHouse 开发者就更少了。所以我没有找到一个 Node ClickHouse ORM 库能帮助我减少工作量和优化代码结构。于是,我在第一次使用 ClickHouse 的时候,就着手在监控服务代码中写一个模块来实现一些我需要的 ORM 功能。这就是 node-clickhouse-orm 库的雏形。
随着模块在系统中稳定运行了一段时间,时机成熟便与另一位同事协作(仓库的另一位贡献者)开发开源了 1.x 版本。随着监控系统的迭代,ORM 开源库也在同步更新。
为什么
为什么最终产出了 node-clickhouse-orm,有必要吗?下面通过自问自答的方式来回答
问题1:可以不用 ORM 吗?
对于体验过 ORM 好处的开发者,突然说这个数据库没有 ORM 着实有点不习惯。根本原因还是在于如果没有 ORM,在开发过程中,将会存在许多低效率的工作,比如:
- 手动执行建库、建表、修改表结构
此类工作麻烦且容易出错。试想一个项目在多环境部署,从本地开发到更新部署测试、线上环境,同样的事情会重复做多次。
在我们项目的场景下,做了分表的逻辑,比如同一个模型的表会根据不同的子项目ID,生成不同的表。模型 User,表 user_子项目1,user_子项目2,表特别多的情况下,人工操作表结构的工作量就巨大了。
- 纯SQL语句写起来慢,难维护
SQL 里面很多重复的语句要通过额外代码来组织或者每个语句都直接全部手写,无法保证开发者能写出统一的代码。
数据插入和验证的代码会非常繁琐。
表里包含什么字段,都无法从项目代码中确定,需要从数据库层面熟悉每个表结构。
问题2:非要自己造个 ORM?
你们这些狗B能不能别卷了?现在做个东西,还是要反问下自己,这个*造出来有没有意义,整不好就要被喷。
首先市场上没有其他*可以使用,我对此有需求。但是如果一开始就直接上手撸一个 ORM 库,很难确定自己要优先实现哪些功能,不能快速满足业务需求,有点不切实际。
所以最初考虑是先通过一个代码模块来实现一部分 ORM,主要满足当前项目的需求。如果这个代码模块比较成熟且使用稳定了,才会去考虑单独开发一个库。这个*,其实就是把积累的代码做一个封装,让技术上的积累更上一层楼,产出一个成果。因此造这个*是基于项目本身顺水推舟的产物,并不是完全的从零到一的创作。
问题3: 为什么不通过 Sequelize 或者 TypeORM 实现为统一标准的子库
要去掌握他们的代码标准对我来说,成本太高了。大部分情况下,没有来自外部对此 ORM 的需求,都是实现有关自己需要的功能。
行列数据库本身也有一定差异。我只能参考它们的使用方式方法,来尽量让开发者使用起来感觉更相似,减少一些理解成本。
实现了哪些能力
- 数据库连接和通信(使用三方库)
- 表模型定义
- 通过表模型定义来建表和同步表字段结构
- 数据查询、插入、删除等方法
- 支持集群配置
- 部分数据类型验证
代码仓库中提供了中英文档,提供了所有功能的代码使用示例供参考。测试报告已上传,测试覆盖率80%以上。
回顾一下几个版本主要做的事情
1.x:
搭建仓库脚手架;抽象封装代码;编写测试用例、文档。功能上实现:数据库连接和通信;表模型定义;数据查询和插入方法;基本数据类型验证。
2.x:
重构改造 ORM 的使用API;兼容集群模式;增加数据删除方法。
3.x:
新增代码模型字段检测、同步修改远程数据库表结构;
完善主要数据类型和兼容所有数据类型( DATA_TYPE );
新增中文文档;
完善测试用例并上传测试报告到 coveralls.io;
代码优化重构。
小结
一年的时间,迭代的频率也并不高,现在已经来到了 3.x 版本,大版本升级过快,多少让人有点疑惑。原因是多方面的
- 对于 ClickHouse 本身掌握度不够
- 使用过的其他数据库 ORM 也并不多,经验不足
- 精力有限,对于库的规划不足,更多的是通过解决自己的问题去迭代库
- 目前使用库的开发者不多,市场需求量小,可以大胆升级代码
终归它并不完美,甚至有些 low,但目前它能满足我的需求。
收获
学习更多知识
系统代码更干净可维护性提升
有关 ClickHouse 的代码和系统中其他数据库代码变得更为相近,代码更简洁。系统代码的边界也变得非常清晰,方便区分哪些是 ORM 需要解决的,哪些是业务代码需要处理的。以后其他同事维护项目也可以层层递进,他可以先学会使用库,专心维护项目本身,而后有兴趣再考虑学习库的代码。
积累
说点关于积累的感想,最近一个朋友聊到几年前在开发一个硬件模块交互流程的时候,觉得实现的通用交互流程可以抽象为一个库方便以后使用,于是实现了一个库。最近一个陌生开发者和他成为了好友并打赏了表示感谢。据说他在尝试很多办法和库都没有打通硬件,结果搜到这个库使用之后直接就跑通了。积累的代码帮助到了别人还结交了更多同行。这位朋友感叹相信积累的力量。
对于社区开发者来说,如果觉得此 ORM 库可以帮助解决一些问题,多一个人使用,多一分认可,这个库的价值就提升一分。说明积累是值得的,相信积累的力量。
官方收录
node-clickhouse-orm 库目前已经收录在 ClickHouse 官方文档中 ,还得到了包括 ClickHouse CTO 等一些开发者的支持点赞。
https://clickhouse.com/docs/en/interfaces/third-party/client-libraries/。
最后
如果你有任何建议或者需求可以给仓库node-clickhouse-orm 提 issue,也可以通过仓库文档最下方提供的联系方式加入讨论群。如果有任何相关合作机会也可以联系我,作者也想增加点收入机会,混口饭吃。