無模式/靈活 + ACID 數據庫?
我正在考慮將基於 VB 的本地(本地安裝)應用程序(發票+庫存)重寫為面向小型企業客戶的基於 Web 的 Clojure 應用程序。我打算將其作為 SaaS 應用程序提供給類似行業的客戶。
我正在查看數據庫選項:我的選擇是 RDBMS:Postgresql/MySQL。我可能會在第一年擴大到 400 個使用者,通常每個使用者每天有 20-40 次頁面瀏覽量 - 主要用於交易而不是靜態瀏覽量。每個視圖都將涉及獲取數據和更新數據。ACID 合規性是必要的(或者我認為是這樣)。所以交易量並不大。
根據我的偏好選擇其中任何一個是不費吹灰之力的,但是對於這一要求,我認為這是 SaaS 應用程序的典型要求:隨著我添加更多客戶/使用者以及每個客戶的不斷變化的業務需求(我將只提供一些有限的靈活性)。由於我不是數據庫專家,根據我能想到和讀過的內容,我可以通過多種方式處理它:
- 在 MySQl/Postgresql 中使用傳統的 RDBMS 模式設計,單個數據庫託管多個租戶。並在每個表中添加足夠的“自由浮動”列,以便在我添加更多客戶或對現有客戶進行更改時進行更改。每次對 Schema 進行小的更改時,這可能具有將更改傳播到 DB 的缺點。我記得讀過 Postgresql 架構更新可以實時完成而無需鎖定。但不確定在這個案例中它有多痛苦或有多實用。而且,由於架構更改也可能引入新的/次要的 SQL 更改。
- 擁有 RDBMS,但以靈活的方式設計數據庫模式:接近實體屬性值或僅作為鍵值儲存。(例如工作日,FriendFeed)
- 將整個事物作為對象保存在記憶體中,並定期將它們儲存在日誌文件中。(例如,edval、lmax)
- 選擇像 MongoDB 或 Redis 這樣的 NoSQL 數據庫。但根據我收集到的資訊,它們不適合這個案例,也不完全符合 ACID。
- 選擇一些 NewSQL Db,例如 VoltDb 或 JustoneDb(基於雲),它們保留了 SQL 和 ACID 兼容行為並且是“新一代”RDBMS。
- 我查看了 neo4j(graphdb),但不確定它是否適合這個案例
在我的案例中,不僅僅是可擴展性或分佈式計算,我正在尋找一種更好的方法來實現“架構中的靈活性 + ACID + 一些合理的性能”。我可以在網上找到的大多數文章都將架構的靈活性作為導致性能(在 NoSQL DB 的情況下)和可伸縮性的原因,同時忽略了 ACID/Transactions 方面。
這是“架構靈活性與 ACID”事務的“非此即彼”的情況,還是有更好的出路?
選項1
這有幾個原因,我將在下面解釋。首先,這是如何做到的。
- 使用您選擇的標準 RDBMS 平台。
- 使用多個使用者可配置的欄位設置您的模式,並使您的應用程序促進基於每個租戶的配置。
- 從每個租戶的元數據中,您可以創建其數據的每個租戶視圖,其中包含內置的過濾器以及從元數據中命名的列。提供的任何報告也可以繼承元數據。如果他們想對數據進行 MI,則向他們提供事務數據的提取,或者如果他們願意為此付費,則可能在不同的伺服器上提供一些額外的 MIS 應用程序。
- 不要嘗試提供比這更多的自定義(即不對模式進行根本性更改),除非客戶準備為他們自己的私有實例付費並維護自定義建構。
這背後的原因是:
- 這些數據庫系統將處理您在相當普通的硬體上描述的那種卷。你並沒有真正擁有與 NoSQL 數據庫相配的那種交易量。除非您有其他架構上的理由想要一個,否則走前沿並沒有多大意義。
- 它們是成熟的、易於理解的技術。
- 系統管理、備份/恢復、複製、報告和災難恢復都在 RDBMS 平台上得到了很好的分類。
- 您可以獲得所有主要 RDBMS 平台的客戶端庫,包括 JDBC。
- 視圖可用於每個使用者的自定義並從您的應用程序元數據生成。
- 它比 XML 欄位或 EAV 結構更有效。
使用 PostgreSQL,您可以選擇使用單獨的數據庫、單獨的模式或視圖來處理多租戶。
使用多個數據庫(在同一數據庫伺服器內)使管理更加複雜,因為必須單獨管理每個數據庫。因此,只有在租戶之間的安全是最受關注的情況下,才建議這樣做。
單獨的模式提供了很大的靈活性和安全性,但使升級更加複雜,因為它們必須單獨應用,並且可能僅在您的租戶使用完全不同的表結構時才需要;如果他們使用相同的應用程序,這是不太可能的。
視圖允許租戶查看公共表結構的不同部分,並允許您控制他們有權訪問哪些表、哪些列和哪些行。唯一需要注意的是,您的應用程序必須確保它只使用這些視圖而不是基表,否則由於軟體缺陷,租戶之間可能會發生意外的數據洩漏。
您實際上並不需要在應用程序要求之前創建列。列可以動態添加到表中(對使用者沒有任何明顯影響),視圖也可以動態更新。您只需要考慮進行更改的順序 - 即。更改表,然後是視圖,然後是應用程式碼。
您唯一的潛在問題是您是否需要添加需要添加到現有索引或需要新索引的新列。那是在建構索引時表可能會被鎖定而無法使用 - 但 PostgreSQL 支持在不鎖定表的情況下同時建構索引的能力。除非新索引需要唯一併發現唯一性違規,否則這很好用。
您可能不需要 NoSQL 數據庫,因為它們有效地從數據庫中刪除了模式並需要應用程序來管理它。聽起來您的音量並不需要那種犧牲。