繁体   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