Mysql

將大型數據庫拆分為較小的數據庫

  • January 30, 2019

我們的系統目前將所有客戶(商家)帳戶儲存在一個“平面”MySQL(5.6)數據庫命名空間中。我們希望更好地擴展——我們正在考慮根據商家帳戶 ID 分解我們的數據。因此,而不是:

use database single;
table sales (
 `account_id`
 ...
)

將商家分解為單獨的命名空間:

use database <account_id>;
table sales (
 ... // stores data  for a single account
)

上面有幾個好處:

  • 帳戶可以放置在不同的伺服器上,並且可以更好地橫向擴展。我們可以決定要共同定位多少個帳戶,並根據需要進行遷移。
  • 個人帳戶備份/恢復時間將大大減少。
  • 能夠一次升級一個帳戶的數據庫(更精細)。
  • 一位不良使用者不會影響所有帳戶。等等

關注點: 今天,我們所有的數據庫訪問都是通過儲存過程——讀取和突變。我們希望保持這種方式,因為它將數據庫模式與應用程式碼隔離開來。如果我們將帳戶分解為單獨的數據庫命名空間,則儲存過程中使用的點表示法無法參數化,據我們所知。我們必須為每個帳戶命名空間複製儲存過程(約 150 個)。因此,如果我們需要對一個 SP 進行更改,我們需要將其應用於所有命名空間的儲存過程。事實上,任何數據庫架構更改都需要(通過自動化)應用於所有數據庫命名空間。即使在自動部署更改之後,管理成本也有點可怕。

任何替代/更好的橫向擴展解決方案?

如果我們將帳戶分解為單獨的數據庫命名空間,則儲存過程中使用的點表示法無法參數化

我們必須為每個帳戶命名空間複製儲存過程(約 150 個)。

這不應該是一個問題:當在其中呼叫一個過程時database1,它將具有該上下文,因此您不必更改過程。您甚至根本不需要更改過程和表:保留該account_id列並使其始終為每個帳戶/數據庫提供一個固定值。這樣,您可以切換回每個數據庫的多個租戶。

如果您總是針對具有多個租戶的數據庫進行開發和測試,那麼這應該是安全的(如果您針對單租戶數據庫進行開發和測試,您可以輕鬆地發現跨租戶數據會漏掉錯誤)。

如果您稍後決定不再需要/想要多租戶數據庫,那麼您可以在那個階段決定是否值得付出努力和進行回歸測試以account_id從所有內容中刪除。

事實上,任何數據庫架構更改都需要(通過自動化)應用於所有數據庫命名空間。即使在自動部署更改之後,管理成本也有點可怕。

這裡有許多工具可以提供幫助,哪種工具最好(或者如果自己滾動更好)很大程度上取決於應用程序、規模和部署頻率以及其他因素。

您是否同意不可能有一個公共命名空間(數據庫)託管所有儲存過程,然後能夠在另一個(每個商家帳戶)數據庫的上下文中將其作為 shared.sp_get_info() 呼叫?

如果 mySQL 允許這樣的跨數據庫引用(我最近沒怎麼使用它,我主要是一個 MS SQL Server 人,這將允許這樣的事情(儘管在 Azure SQL 中沒有))那麼這將是可能的並且會起作用,但我不會推薦它。

您的公共數據庫成為所有支持數據庫的單點故障。它將它們緊密耦合在一起,通過簡單地將一些數據庫轉移到另一個伺服器/服務上來增加工作量,因為您不能只是簡單地移動所需的客戶端數據庫並更新應用程序中的連接設置(您必須創建一個新的公共數據庫和確保每個人都有正確的家庭程序)。您仍然必須維護相同程序的所有不同副本。您仍然存在保持適當更新的問題,但它會引發一類新的可能錯誤:如果由於建構過程問題或人為錯誤,給定客戶端數據庫的過程會在該數據庫中的架構之前更新或者當數據庫更新時不更新,您會遇到一些可能難以診斷的問題。

這可能感覺像是一種簡化,但你確實增加了複雜性。在每個 DB 的過程中保持相同的程式碼更簡潔。您將遇到潛在的版本控制問題,但公共數據庫不會真正刪除它們,實際上它會增加更多此類問題。

引用自:https://dba.stackexchange.com/questions/228370