關系數據庫經過幾十年的發展,已經非常成熟,但同時也存在不足:
表結構是強約束的,業務變更時擴充很麻煩。
如果對大數據量的表進行統計運算,I/O會很高,因為即使只針對某列進行運算,也需要將整行數據讀入內存。
全文搜索只能使用 Like 進行整表掃描,性能非常低。
針對這些不足,產生了不同的 NoSQL 解決方案,在某些場景下比關系數據庫更有優勢,但同時也犧牲了某些特性,所以不能片面的迷信某種方案,應將其作為 SQL 的有利補充。
NoSQL != No SQL,而是:
NoSQL = Not Only SQL
典型的 NoSQL 方案分為4類:
Redis 是典型,其 value 是具體的數據結構,包括 string, hash, list, set, sorted set, bitmap, hyperloglog,常被稱為數據結構服務器。
以 list 為例:
LPOP key 是移除並返回隊列左邊的第壹個元素。
如果用關系數據庫就比較麻煩了,需要操作:
Redis 的缺點主要體現在不支持完成的ACID事務,只能保證隔離性和壹致性,無法保證原子性和持久性。
最大的特點是 no-schema,無需在使用前定義字段,讀取壹個不存在的字段也不會導致語法錯誤。
特點:
以電商為例,不同商品的屬性差異很大,如冰箱和電腦,這種差異性在關系數據庫中會有很大的麻煩,而使用文檔數據庫則非常方便。
文檔數據庫的主要缺點:
關系數據庫是按行來存儲的,列式數據庫是按照列來存儲數據。
按行存儲的優勢:
在某些場景下,這些優勢就成為劣勢了,例如,計算超重人員的數據,只需要讀取體重這壹列進行統計即可,但行式存儲會將整行數據讀取到內存中,很浪費。
而列式存儲中,只需要讀取體重這列的數據即可,I/O 將大大減少。
除了節省I/O,列式存儲還有更高的壓縮比,可以節省存儲空間。普通行式數據庫的壓縮比在 3:1 到 5:1 左右,列式數據庫在 8:1 到 30:1,因為單個列的數據相似度更高。
列式存儲的隨機寫效率遠低於行式存儲,因為行式存儲時同壹行多個列都存儲在連續空間中,而列式存儲將不同列存儲在不連續的空間。
壹般將列式存儲應用在離線大數據分析統計場景,因為這時主要針對部分列進行操作,而且數據寫入後無須更新。
關系數據庫通過索引進行快速查詢,但在全文搜索的情景下,索引就不夠了,因為:
假設有壹個交友網站,信息表如下:
需要匹配性別、地點、語言列。
需要匹配性別、地點、愛好列。
實際搜索中,各種排列組合非常多,關系數據庫很難支持。
全文搜索引擎是使用 倒排索引 技術,建立單詞到文檔的索引,例如上面的表信息建立倒排索引:
所以特別適合根據關鍵詞來查詢文檔內容。
上面介紹了幾種典型的NoSQL方案,及各自的適用場景和特點,您可以根據實際需求進行選擇。