Hibernate 4 多租户数据库设计
Posted
技术标签:
【中文标题】Hibernate 4 多租户数据库设计【英文标题】:Hibernate 4 multi tenant database design 【发布时间】:2013-08-09 15:53:54 【问题描述】:我想用 JSF + Hibernate 4 开发多租户应用程序。
我已经知道多租户数据库设计的理论,但我需要知道 Hibernate 4 对我的数据库设计的具体要求是什么。我需要在 mysql 中配置或准备什么吗?
也许,我必须在每个表中添加tenantId 列?或者我必须在 MySQL 数据库中准备一些选项。
我打算在我的数据库上使用共享数据库和分离架构设计。我想知道休眠如何使用此策略,我是否需要首先为数据库中的每个租户准备架构?或者 hibernate 会为我做这件事,所以基本上我只提供 1 个基本模式,hibernate 会复制它与我的租户编号一样多?
我真的需要找到一些很好的教程和解释来使用 Hibernate 4 多租户功能。有没有链接或电子书建议?谢谢
【问题讨论】:
这是一个开始:docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch16.html 我已经读过了,但是那个开发指南没有给我任何关于 MySQL 数据库或配置的解释。 【参考方案1】:我已经在 C# 和 NHibernate 中解决了类似的问题,但您似乎有概念问题,而不是与特定技术相关。
我们希望为我们的“主要聚合”的不同实例提供单独的表。不是因为多租户,而是为了避免某些主聚合影响另一个主聚合时的性能损失(例如,由于执行第一个“主聚合”的更新查询导致表锁定,因此第二个“主聚合”的读取查询无法读取任何内容)。
我们做了什么:
使用可参数化的表名创建 SQL 脚本,例如 MY_TABLE_0
一旦创建了新的“主聚合”(在您的案例中注册了新用途),第一个项目符号的脚本将使用替换的占位符执行。我们有一张表,其中标识符以原子方式递增,例如它执行了类似CREATE TABLE MY_TABLE_412
...
我们以相同的方式使用命名查询。一旦我们的项目开始,一项服务的代码为每个“主要聚合”创建了一个会话工厂。这段代码为所有“主要聚合”预编译了命名查询。我们存储了Dictionary <"main aggregate"_id, named queries>
我们包装了会话工厂和存储库,因此每个执行的查询都需要“主聚合”的标识符。因此,当有人调用MyPrettyNamedQuery
以及“主聚合”ID 时,该服务会找到正确编译的命名查询并针对连接执行该查询。所以查询确实使用了正确的表,例如SELECT name FROM MY_TABLE_412
我们将此方法调整为我们的应用程序使用共享表的状态,其中数据库包含一个用于所有“主聚合”的表,但对于性能关键的子聚合,我们可以使用描述的方法,其中包含更多表以获取更多主聚合。
我们的应用已经投入生产 3 年,没有客户拒绝授予使用 DB 权限来创建表。
我不确定 java 的 Hibernate 是否包含对此功能的一些支持,但 C# 没有,所以我们需要编写它。
我不建议使用一些“tenant_id”,因为它不安全,您不能将表/模式移动到不同的数据库节点(在可扩展性的情况下),或者它会带来令人不快的性能问题(我已经写过关于它)。
【讨论】:
您好,感谢您的回复。那么,我想您将为每个租户提供 1 个逻辑架构?如果 saas 应用程序有很多租户(即免费注册的网络应用程序)怎么办。根据您的应用程序,我会想象这个数据库有很多表,对于每个注册的用户,它会先创建模式,然后将表放到数据库中? 是的,一旦你想保证某种安全性,你就应该这样做。我不认为每个用户模式的概念会在云部署中带来任何问题,因为大多数数据库实例更多,所以如果你有很多用户,那么你就有很多数据库,但在很多计算机上。以上是关于Hibernate 4 多租户数据库设计的主要内容,如果未能解决你的问题,请参考以下文章