簡體   English   中英

如何設計多租戶mysql數據庫

[英]How to design a multi tenant mysql database

假設我需要設計一個數據庫來托管多家公司的數據。 現在出於安全和管理目的,我需要確保正確隔離不同公司的數據,但我也不想啟動 10 mysql 進程來在 10 台不同的服務器上托管 10 家公司的數據。 使用 mysql 數據庫執行此操作的最佳方法是什么。

多租戶數據庫有多種方法。 為了討論,它們通常分為三類。

  • 每個租戶一個數據庫。
  • 共享數據庫,每個租戶一個架構。
  • 共享數據庫,共享模式。 租戶標識符(租戶鍵)將每一行與正確的租戶相關聯。

MSDN 有一篇關於每種設計優缺點以及實現示例的好文章。


微軟顯然已經刪除了我提到的頁面,但它們在 archive.org 上。 鏈接已更改為指向那里。

供參考,這是第二篇文章原始鏈接

在 MySQL 中,我更喜歡為所有租戶使用一個數據庫。 我通過為每個租戶使用單獨的數據庫用戶來限制對數據的訪問,該用戶只能訪問僅顯示屬於該租戶的行的視圖。

這可以通過以下方式完成:

  1. 向每個表添加一個 tenant_id 列
  2. 使用觸發器在插入時使用當前數據庫用戶名填充tenant_id
  3. 為每個表創建一個視圖,其中 tenant_id = current_database_username
  4. 僅使用應用程序中的視圖
  5. 使用租戶特定的用戶名連接到數據庫

我已經在博客文章中完整記錄了這一點: https : //opensource.io/it/mysql-multi-tenant/

簡單的方法是:為每個共享表,添加一列表示SEGMENT_ID。 為每個客戶分配適當的 SEGMENT_ID。 然后根據 SEGMENT_ID 為每個客戶創建視圖,這些視圖將使數據與每個客戶分開。 通過這種方式,可以實現信息的共享,讓運維和開發都變得簡單(存儲過程也可以共享)簡單。

假設您在單個 MySQL 實例上運行一個 MySQL 數據庫 - 有幾種方法可以區分哪些內容屬於誰。 最明顯的選擇(至少對我而言)是創建一個復合主鍵,例如:

CREATE TABLE some_table (
id int unsigned not null auto_increment,
companyId int unsigned not null,
..
..
..,
primary key(id, company_id)
) engine = innodb;

然后通過更改主鍵的 companyId 部分來區分公司。 這樣您就可以在同一個表/數據庫中擁有所有公司的所有數據,並且在應用程序級別,您可以控制哪個公司與哪個 companyId 相關聯,並確定要為特定公司顯示哪些數據。

如果這不是您要找的東西 - 我很抱歉誤解了您的問題。

您是否考慮過為每家公司創建不同的架構

不過,您應該嘗試更准確地定義您想要實現的目標。

例如,如果您想確保硬件故障不會危及多家公司的數據,則必須創建不同的實例並在不同的節點上運行它們。

如果您想確保 A 公司的某個人無法看到屬於 B 公司的數據,您可以按照 Matthew PK 答案在應用程序級別執行此操作,例如

但是,如果您想確保有人設法破壞安全性並對數據庫運行任意 SQL,您需要比這更強大的東西。

如果您希望能夠獨立備份數據,以便您可以在星期一安全地備份 C 公司,在星期日安全地備份 A 公司,並且能夠僅恢復 C 公司,那么同樣,純粹基於應用程序的解決方案將無濟於事。

給定一個特定的數據庫用戶,您可以將用戶成員資格授予組,指明他們被允許訪問其數據的公司。

我想你會有一個Companies表,所以只需在CompaniesMySQLUsers或類似的東西之間創建一個一對多的關系。

然后,作為所有查詢的條件,只需根據UserID匹配CompanyID

在我的文件 Generate_multiTanentMysql.php 中,我使用 PHP 腳本執行所有步驟

https://github.com/ziedtuihri/SaaS_Application

解決方案設計模式:

  • 為每個租戶創建一個數據庫用戶

  • 將每個表重命名為不同且唯一的名稱(例如使用前綴“someprefix_”)

  • 向每個表添加名為“id_tenant”的文本列以存儲該行所屬租戶的名稱

  • 為每個表創建一個觸發器,在插入新行之前自動將當前數據庫用戶名存儲到 id_tenant 列

  • 使用原始表名為每個表創建一個視圖,其中包含除 id_tenant 之外的所有列。 該視圖將僅返回行,其中 (id_tenant = current_database_username)

  • 僅向每個租戶的數據庫用戶授予對視圖(而非表)的權限 然后,應用程序中唯一需要更改的部分是數據庫連接邏輯。 當有人連接到 SaaS 時,應用程序需要:

  • 以特定於租戶的用戶名連接到數據庫

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM