【问题标题】:Give each user their own database给每个用户自己的数据库
【发布时间】:2013-09-27 00:20:00
【问题描述】:

我正在构建我的应用程序,以便每个用户都有自己的数据库(以便于隔离,并最大限度地减少对分片的需求)。这意味着每个 Web 请求和所有后台脚本都需要根据发出请求的用户连接到不同的数据库,并将该连接用于所有函数调用。

我想我可以制作某种中间件,通过将其附加到 request 变量,将正确的连接传递给我的 Web 请求,但我不知道我应该如何确保由请求使用此连接。

【问题讨论】:

  • 艰难的道路。这就是为什么没有人这样做。
  • 我很难看到一个有效的用例(除了数据库黑客竞赛或其他什么)
  • 单独使用多个数据库更容易实现多租户的假设是一种货物崇拜安全思想。
  • 这是一个相关问题:stackoverflow.com/questions/13372001/… - 我最终使用的方法是为每个租户使用单独的 Postgres 架构(又名命名空间)。我很确定您可以配置 SQLALchemy 以维护与不同数据库的连接池并检查每个新请求的正确连接,但您确实需要测试应用程序如何与数百或数千个租户一起工作

标签: python database sqlalchemy pyramid


【解决方案1】:

那么如何“确保请求调用的所有函数和模型方法都使用此连接”很容易。您将连接传递到您的 api 中,就像使用任何不依赖全局变量的精心设计的代码一样。因此,您有一个按请求加载的数据库会话对象,然后将其传递下去。模型对象很容易在不显式传递的情况下进一步海龟该会话对象,因为每个托管对象都知道哪个会话拥有它,您可以从那里查询它。

db = request.db
user = db.query(User).get(1)
user.add_group('foo')

class User(Base):

    def add_group(self, name):
        db = sqlalchemy.orm.object_session(self)
        group = Group(name=name)
        db.add(group)

我不建议您使用确切的模式,但它可以作为如何从托管对象中获取会话的示例,避免必须在任何地方显式传递会话。

关于您最初的问题,如何处理多租户...在您的数据模型中!设计一个将事物拆分到这么低级别的系统是一个很大的维护负担,而且它不能很好地扩展。例如,当您有任意数量的独立连接时,使用任何类型的连接池变得非常困难。为了解决这个问题,人们通常使用某些数据库支持的 SQL SCHEMA 特性。这允许您使用相同的连接,但每个会话可以访问不同的表结构。这更好,但再次独立管理所有这些模式应该引发一些危险信号,违反 DRY 与数据模型中的所有重复。该级别的任何重复都会很快成为您需要做好准备的负担。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    相关资源
    最近更新 更多