簡單數據庫遷移實踐
現(xiàn)在NoSQL流行,有一個原因也是因為不需要去刻意處理table的schema,直接存儲數據,這樣簡單!所以也不會有數據庫表的遷移問題。數據庫表遷移這一塊兒一直是一個麻煩點,但我最近用了sqlite3做了個小項目,所以總結下數據庫遷移的方案。
原理
- 每一次數據表改動,都對應一個數據庫版本號
- 數據遷移是漸進式的,比如把數據庫版本從1 升級到n,那么就升級n-1次,版本1到2,2到3,直到n-1到n。
實施
1. 使用sqlite3的user_version 存貯自定義的數據庫版
- /*設置版本號*/
- PRAGMA user_version=1;
- /*讀取版本號*/
- PRAGMA user_version;
2. 所有的數據庫升級文件,放在一個文件中,都直接使用sql文件,方便直接查看管理。文件結構如下
文件結構設計
- v1.sql v2.sql, v3.sql等 是每個數據庫版本,完整的數據庫定義文件
- v1tov2.sql, v2tov3.sql等 是間隔版本數據庫升級文件。一個數據m到n升級的過程就是,運行 v[m]tov[m+1].sql, v[m+1]tov[m+2].sql, 直到 v[n-1]tov[n].sql
- run.sh 就是每次要跑的數據遷移腳本,包括了當前的版本號和遷移邏輯
- 其中的v2.sql 到v[n].sql 不是必須的,只是為了方便查看當前***的數據表設計,如果存在v[n].sql 那么創(chuàng)建新數據庫也可以直接從這個文件來創(chuàng)建
3. 遷移腳本如下, 具體邏輯注釋中已經寫明
4. v[n].sql 和v[n-1]tov[n].sql 文件的***都去需要通過user_version來設置數據版本為n,一個v2tov3.sql 的demo如下:
總結
使用場景
目前這套方案適合數據量小,對停機維護可以接受的業(yè)務情況,因為需要停機升級,但是這個方案,足夠簡單清晰且能滿足所有不同版本間的數據升級。
不足與展望
- 這個方案沒有考慮到數據升級失敗的回滾。由于是小業(yè)務,所以考慮更多的是簡單易維護。所以針對這種情況的,首先要保證升級腳本經過了足夠的線上數據測試,經的起考驗。其次,一旦發(fā)生問題,線上可以直接操作維護,寫腳本。這樣說,因為你都沒有測試到這種需要rollback的case,你也不能在寫升級腳本的時候,知道這種case是怎樣,所以提前寫好rollback的邏輯不一定可行或者合適。
- 部署時,數據遷移之前要備份,數據量較大些,用增量備份,節(jié)省時間。備份有成熟的工具,而且備份方便升級失敗時rollback。部署的步驟應該是: 拉代碼build(或者拉docker鏡像)-> 備份數據庫 -> 升級數據庫 -> 跑新的代碼
- 對于Android,iOS的設備中使用sqlite3的情況,數據遷移的邏輯是一樣。sql文件結構設計可以重用,也可以寫到代碼里去管理。遷移腳本需要轉換成native的Java或者Objective-C,Swift的代碼。
- 對于更大的業(yè)務,多實例的的數據庫遷移可以使用Flyway