2

我想用 JSF + Hibernate 4 开发多租户应用程序。

我已经知道多租户数据库设计的理论,但我需要知道 Hibernate 4 对我的数据库设计的具体要求。我需要在 MySQL 中配置或准备什么吗?

也许就像,我必须在每个表中添加tenantId 列?或者我必须在 MySQL 数据库中准备一些选项。

我打算在我的数据库上使用共享数据库和分离的架构设计。我想知道休眠如何使用此策略,我是否需要首先为数据库中的每个租户准备架构?或者hibernate会为我做这个,所以基本上我只提供1个基本模式,hibernate会复制我的租户号码吗?

我真的需要找到一些很好的教程和解释来使用 Hibernate 4 多租户功能。有没有链接或电子书建议?谢谢

4

1 回答 1

2

我已经在 C# 和 NHibernate 中解决了类似的问题,但似乎您的概念问题不仅仅与特定技术相关。

我们希望为我们的“主要聚合”的不同实例分离表。不是因为多租户,而是为了避免某些主聚合影响另一个主聚合时的性能损失(例如,由于执行第一个“主聚合”的更新查询导致表锁定,因此第二个“主聚合”的读取查询无法读取任何内容)。

我们做了什么:

  1. 使用可参数化的表名创建 SQL 脚本,例如 MY_TABLE_{0}

  2. 一旦创建了新的“主要聚合”(在您的案例中注册了新用途),第一个项目符号的脚本将使用替换的占位符执行。我们有一个表,其中标识符以原子方式递增,例如,它执行类似CREATE TABLE MY_TABLE_412...

  3. 我们以相同的方式使用命名查询。一旦我们的项目开始,一项服务的代码为每个“主要聚合”创建了一个会话工厂。这段代码为所有“主要聚合”预编译了命名查询。我们存储Dictionary <"main aggregate"_id, named queries>

  4. 我们包装了会话工厂和存储库,因此每个执行的查询都需要“主聚合”的标识符。因此,当有人MyPrettyNamedQuery与“主聚合”ID 一起调用时,该服务会找到正确编译的命名查询并针对连接执行该查询。所以查询确实使用了正确的表,例如SELECT name FROM MY_TABLE_412

  5. 我们将这种方法调整到我们的应用程序使用共享表的状态,其中数据库包含一个用于所有“主要聚合”的表,但对于性能关键的子聚合,我们可以使用所描述的方法,使用更多表来获取更多主要聚合。

我们的应用程序已投入生产 3 年,没有客户拒绝授予使用 DB 权限来创建表。

我不确定 java 的 Hibernate 是否包含对此功能的一些支持,但 C# 没有,所以我们需要编写它。

我不建议使用一些“tenant_id”,因为它不安全,你不能将表/模式移动到不同的数据库节点(在可伸缩性的情况下),或者它会带来令人不快的性能问题(我已经写过它) .

于 2013-08-11T15:19:29.840 回答