sqlite3樹形結構遍歷效率對照測試
一、緣起
項目數據結構:本人從事安防行業,視頻監控領域。項目中會遇到監控點位的組織機構划分、暫時划分的巡邏點位等。這些相機點位、連同組織機構,它們在邏輯關系上構成了一個樹形結構。
二、方案
詳細例如以下:
則遞歸函數退出。
方案3:sql語句遞歸查詢
方案1、2的思路都是在sql語句之外遞歸查詢。
假設可以寫出遞歸的sql語句,效果是不是能更好呢?於是有了方案3。簡單來說。方案3是將方案2中用函數實現的"查找子節點的子節點的子節點......"。替換為用sql語句來實現。
關於sqlite3的遞歸語句,請參考我的另外一篇博文《sqlite3-遞歸查詢》。
這里要注意一下,sqlite3的遞歸語法 with recursive 可能在 其3.7.X 及下面版本號不受支持,可能會提示語法錯誤syntax error。我的sqlite3庫升級到3.8.x之后就能查詢到結果了。
方案4:引入關系表
如今數據庫表的結構例如以下圖所看到的。
它是一種結構化的數據庫表結構。
將節點的id和父節點id都存儲在一個記錄中。
優點是開發時候高速。壞處是,不便於擴展和改動。
說它不便於擴展,是由於假如一個節點有兩個父節點。則一個字段無法滿足。再加一個father_id字段嗎?顯然不現實,由於不知道會有多少個父節點。
說它不便於改動,是由於。假設將多個父節點id都採用格式化都填入father_id字段。則在維護記錄的時候會帶來“拼串和解析串”的步驟,帶來維護上的麻煩。
那么。能否夠換一種思路,採用面向對象的思維創建數據庫表呢?於是想到了以下的表結構和表關系。
如圖所看到的。添加一個關系表,專門用來存儲節點之間的關系。
將father_id和son_id作為聯合主鍵。
如此一來,節點與節點之間的關系,事實上就相應的是關系表中的一條記錄!一個節點有多少個子節點,關系表中就有多少條記錄。一個節點有多少個父節點。也是這樣。
這樣改造了數據庫表之后。帶來的優點是顯而易見的。
首先是可維護性的提升。
從曾經的解析改動表字段,到如今的插入刪除一條或多條記錄。
其次是開發維護人員對於數據的關系也會理解地更加深刻和清楚。
但不可避免,也有不足之處。
首先是開發的成本。這種表結構和表關系。不利於高速開發。
其次是如今的軟件系統已經用了好幾年。突然改動,可能會造成現場維護上的壓力突然增大。
第三,這種結構。是否滿足業務功能要求的效能,還是個未知數。
三、結果對照
以下給出上述方案1、2、3的測試對照表。
方案1
方案2
方案3
從理論上來講。查詢得到結果的效率是 方案3 > 方案1 > 方案2。
從上面3個表來看,結果的確如期望的那樣。
可是,有些意外的是。方案3中從結果集中獲取下一條記錄這一步驟(即next),太占用時間,居然達到了97%的占比。
從綜合效率上來看,方案1時間最快。其次是方案3,最慢的是方案2。
由於方案2要運行大量的函數遞歸調用。函數棧切換。這是最為耗時的。