經過1年斷斷續續的迭代,ClickHouse ORM 3.x 釋出啦~說說它的故事吧。
回顧下2022
說來慚愧上次寫部落格都是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,也可以透過倉庫文件最下方提供的聯絡方式加入討論群。如果有任何相關合作機會也可以聯絡我,作者也想增加點收入機會,混口飯吃。