昨天透過簡單規劃一個聊天室資料的儲存方式,暸解在 Cloud Firestore 分層資料結構簡單的規劃。今天就趁著昨天的思路還熱著時,針對分層資料節的幾種儲存方式去做比較吧。
首先,就著目前的暸解來歸納 Cloud Firestore 的資料儲存數種不同的選項:
我們可以在文件裡直接透過 array 或是 map 資料型別的欄位去儲存多層資料,這是最簡單且直接的儲存方式。但是這種情況比較適合簡單、固定的資料清單,也就是這些資料是不會隨著時間成長的。還記這幾天提到的限制嗎?文件最多只能有 1 MB 的大小,而且 Cloud Firestore 希望能維持輕量。若是資料會隨著時間成長,那文件本身也會越來越大,直到碰到大小限制,就會出現無法排除的障礙了。而在取得文件資料時,也無法只取得其中一部分的資料,而是必須整個文件被讀取,若是文件太大,就會導致花太多時間在下載文件。那到底有什麼資料適合以這種方式儲存呢?以昨天聊天室的情境舉例來說,可以在使用者文件中儲存類似「最常拜訪的三個聊天室」,這就是典型的清單,卻又不會隨著時間成長的資料。
那與文件本身相關,但會隨著時間成長的資料,該怎麼辦呢?昨天的範例有提到,這種情境就適合以文件裡的子集合去儲存,這樣無論資料怎麼成長,也不會改變文件的大小,最重要的是,集合相對文件來說,是有提供良好的查詢功能,我們可以在取得資料時進行篩選、排序。同樣以聊天室的情境來說,我們可以透過這種方式去儲存聊天室的訊息清單,也可以儲存屬於這個聊天室的使用者清單。至於這儲存方式會遇到什麼限制呢?在下面會再提到。
通常是指 Top Level,基本上無論是這種階級的集合,或是文件所屬的子集和,都是同一種集合。那為什麼要特別提這個呢?因為隨著集合放置的位置不同,在查詢時的好處與限制也不太一樣。舉例來說,前面提到的都是利用文件裡的子集合儲存訊息,這在一般情境還算適用,畢竟訊息不會跨出聊天室的範疇。
但是,若今天有一個特別的需求,是想要查詢某位使用者在所有聊天室的訊息記錄呢?依照原本的架構,就得一間、一間聊天室去查詢他們下的的訊息集合,如果有 N 間聊天室,就得查詢 N 次。若是把所有訊息通通放在同一個與聊天室集合同階的集合,並且透過欄位去紀錄是屬於哪個聊天室和使用者呢?這樣我們就只需要查詢一次,就可以得到該使用者所有的訊息記錄。那這樣要查詢聊天室所屬的訊息時,效能就會變差呢?其實不會差太多,這就歸功於 Cloud Firestore 的索引特性,兩種方式查詢聊天室所屬訊息時,速度其實是差不多的。