5

我目前正在制作一个将订阅作为多租户应用程序销售的网络应用程序。我使用的技术是rails。

但是,它不仅仅是使用当前应用程序的隔离租户。

每个租户创建产品并将它们发布到他们的应用程序个人实例上。每个租户都有自己的用户群。

有问题的规范是租户可以将其产品分享给其他租户,以便他们可以转售。

解释 :

FruitShop 出售苹果橙子和西红柿。
蔬菜店出售萝卜和胡椒铃。

Fruitshop 将西红柿分享给其他商店。

VegetableShop 决定从可用的共享项目列表中获取西红柿并将其添加到其库存中。

现在,浏览蔬菜店的顾客会看到萝卜、胡椒铃和西红柿。

如您所料, aselect products where tenant_id='vegetableshop_ID'将不起作用。

我正在考虑与某种具有,甚至发布开始-结束日期的tenant_to_product表进行多对多关系。并且产品将是一个“半租户表”,其中租户 ID 被替换为 tenant_creator_id 以了解谁是原始所有者。tenant_idproduct_idprice_id

对我来说这似乎很麻烦,添加它意味着复杂的查询,即使对于只销售自己产品的商店也是如此。获得销售的产品会很复杂:

select tenant_to_products.* 
where tenant_to_products.tenant_ID='current tenant' 
AND (tenant_to_products.product match publication constraints) 

for each tenant_to_product do
   # it will trigger a lot of DB call
   Display tenant_to_product.product with tenant_to_product.price

取消共享产品还意味着修改所有引用原始产品的tenant_to_products 的复杂更新。

我不确定像这样实现这个约束是个好主意,你建议我怎么做?我打算做一些愚蠢的事情还是一个不错的主意?

4

2 回答 2

3

正如您已经制定的那样,您将需要更复杂的产品机制订阅。听起来你在正确的轨道上。

尽可能地抽象信息。例如,不要将表称为“tenant_to_product”,而是将其称为“tenant_relationships”,并将产品 ID 作为该表中的列。

然后,当租户想要拥有服务时,您可以简单地在此表“服务 ID”中添加一列,而无需添加整个额外的表。

为了提高性能,您可以拥有一个只读数据库服务器,该服务器具有稍微延迟更新的租户关系。Azure 或类似的云服务将使这很容易启动。但是,除非您的用户数量超过 100 万,否则可能不需要这样做。

我建议你考虑:

  • 活跃/不活跃(蔬菜店可能更愿意暂时停止销售西红柿,因为它们目前非常有缺陷,直到种植者停止在其中包含虫子)

  • 用于通知的服务器端服务,例如“productRemoved”服务。这些服务将批量更改,为用户提供更快的反馈。

  • 不要删除信息,而是设置列 'delete_date' 和 'delete_user_id' 或类似的。

  • 对产品、租户、关系等更改的完整审计历史记录。此表将变得非常大,因此请避免从中读取并确保更新是异步的,以免调用者在等待表更新时被阻塞。但从商业角度来看,它可能非常有用。

编辑:

如果您还没有看过这个相关问题,它可能会很有用:如何创建具有共享表结构的多租户数据库?

于 2014-03-05T22:55:28.853 回答
2

当您为多个客户提供系统时,多租户似乎是显而易见的答案。

然而,作为替代方案,也许可以考虑转销商“服务层”,这将实现一定程度的隔离,同时仍提供集成。从经销商账户如何与亚马逊等第三方合作中汲取灵感。

我意识到这是非常抽象的推理,但考虑到比数据层更高的集成可能会有所帮助。

根据在数据层级别严格执行多租户的经验,我们发现有时必须在业务层(如您的经销商想法)对租户进行操作,以至于租户成为一个棘手的概念。因此,尽早考虑替代方案可能会有所帮助。

于 2014-03-06T22:57:18.003 回答