【问题标题】:SQLite3 database per customer每个客户的 SQLite3 数据库
【发布时间】:2016-01-09 02:51:53
【问题描述】:

场景:

使用 symfony2 构建一个包含 RESTful 后端和 AngularJS 前端的商业应用程序

  • 这个应用程序永远不会被很多客户使用(如果我能卖出 100 个,那就太棒了。希望更多,但无论如何都会很大)

  • 我想为数据库建立一个多租户结构,每个客户一个模式(他们为客户存储敏感信息)

  • 我知道更新架构时会出现问题,但我必须忍受它。

  • 今天我有一个 MySQL 演示数据库,每次新客户购买应用程序时我都会克隆它。

  • 我的客户之间没有关系,所以我不需要为任何查询与多个分片通信

  • 对于一位客户,他们可以同时在多个设备上使用该应用,但不会在数据库中进行大量写入操作

我的问题

尝试为后端 API 设置一些功能测试我读到有一个专门的 sqlite 数据库来加载测试数据,这似乎是个好主意。

但是我想知道从 MySQL 切换到 SQLite3 数据库作为我对应用程序的主要数据库支持是否也是一个好主意,以及每个客户拥有一个专用 SQLite3 数据库是否是一种常见的做法。我从未使用过 SQLite,我不知道更新架构和复制所有数据库中的更改的过程是否与其他 RDBMS 的方式相同

这是 SQLite 的正确方案吗? 关于如何实现这一点的任何建议(又名教程)?

【问题讨论】:

  • 如果您的功能测试表明 MySQL 工作正常,您为什么要切换到 SQLite?您也可以在 MySQL 中拥有一个专用数据库——这似乎是保证客户数据分离的好主意(您甚至可以将它们放在单独的服务器上)。
  • @GordonLinoff 我还没有任何功能测试。我想到了 SQLite3,因为我发现的关于我的控制器功能测试的几乎所有信息都在谈论 SQLite,我认为对所有东西都使用相同的系统会很好。我不知道 SQLite,但看起来更容易备份,因为它只是复制文件的问题。我只是想知道这是否是一种简单的方法和常见的做法......谢谢!
  • 这将是一场维护噩梦,并限制您跨多个租户进行查询的能力。当通过例如居住单元来了解事物可能有意义时,您还可以按租户隔离数据库。这里的理由似乎是安全性,但是有一些方法可以安全地构建数据库,而无需每个客户拥有一个(一直都在这样做),并且数据库隔离并不能保证数据安全(攻击者可以访问可以看到的应用程序)它们全部或它们所在的文件系统)。也许您应该备份并询问有关您的安全问题的问题。
  • @Schwern 我的意思是每个客户都有一个 schema 要清楚。既是安全又是维护。例如,单独更新模式不会影响我的所有客户。我在中间msdn.microsoft.com/en-us/library/aa479086.aspx
  • @luso 这就是我的假设。这仍然是一场噩梦。为什么要在租户数据库这样简单的东西中隔离模式更新?你预计这种需求会很大吗?不仅仅是想要更新所有模式?为什么?应用程序如何知道每个租户正在使用哪个版本的架构,它是否必须维护所有可能版本的查询,或者您是否会向每个租户分发不同的应用程序?

标签: mysql database sqlite rest database-design


【解决方案1】:

[我想知道] 每个客户都有一个专用的 SQLite3 数据库是否是一种常见的做法

仅当数据库与应用程序一起部署时,例如在手机上。否则我从来没有听说过这样的事情。

我从未使用过 SQLite,我不知道更新架构和复制所有数据库中的更改的过程是否与其他 RDBMS 的方式相同

SQLite是一个SQL数据库,响应ALTER TABLE之类的。至于更新所有架构,您必须重新运行所有架构的更新。

模式同步通常由外部实用程序处理,通常您的 ORM 会有一些东西。有些与服务器无关,有些仅支持特定服务器。还有专门的数据库变更管理工具,如Sqitch

但是我想知道从 MySQL 切换到 SQLite3 数据库作为我对应用程序的主要数据库支持是否也是一个好主意,并且

SQLite 的主要优点是不需要您安装和运行服务器。这对于快速项目或必须部署数据库的地方(如手机应用程序)来说是有意义的。对于基于服务器的应用程序,拥有数据库服务器没有问题。 SQLite 非常有限的一组 SQL 功能成为一个劣势。除了最简单的查询之外,它的运行速度也可能比服务器数据库慢。

尝试为后端 API 设置一些功能测试我读到有一个专门的 sqlite 数据库来加载测试数据,这似乎是个好主意。

在任何情况下,您都不应使用与生产数据库不同的数据库进行测试。数据库并不都以相同的方式实现 SQL,MySQL 在这方面特别糟糕,您的测试不会反映现实。运行 MySQL 实例进行测试并不需要太多工作。


这个separate schema thing 声称具有三个优点...

  • 可扩展性(您可以随时添加字段)
  • 安全性(查询不能意外显示错误租户的数据)
  • 并行扩展(您可以将每个架构拆分到不同的服务器上)

他们提出的建议相当于为每个租户提供一份单独的自定义代码副本。你不会那样做,这显然是维护的噩梦。代码至少具有分支和合并的版本控制系统的优势。我只知道一种支持分支的数据库管理工具,Sqitch

假设您对租户 5 的架构进行了自定义更改。现在您有了一个想要应用到所有这些的通用架构更改。如果更改为 5 与此冲突怎么办?如果更改为 5 需要与其他人不同的特殊数据迁移怎么办?现在让我们假设您已经对十个模式进行了自定义更改。一百。一千?噩梦。

不同的架构需要不同的查询。应用程序必须知道每个租户正在使用哪个模式,必须有某种模式版本映射,您需要维护。并且必须在应用程序代码中维护对每个不同可能模式的每个不同可能查询。噩梦。

是的,将每个租户放在单独的架构中更安全,但这只能防止编写错误的查询或包含查询构建器(无论如何这都是个坏主意)。有更好的方法可以缓解这个问题,例如文档中建议的view filter。攻击者可以通过许多其他方式访问租户数据,但这些数据并未得到解决:获得数据库连接、获得对文件系统的访问权限、嗅探网络流量。我不认为小小的安全收益值得维护噩梦。

关于缩放,这篇文章已经过时了十年。有很多更好的方法可以实现并行扩展,然后将模式粗略地放在不同的服务器上。有整个数据库致力于这个想法。幸运的是,您不需要任何这些!在您拥有数万到数百万租户之前,扩展对您来说不是问题。为假设的大型并行扩展问题预先加载架构维护噩梦的想法是将购物车放在马前,它已经在酒吧喝了一品脱。


如果你想使用关系数据库,我会推荐 PostgreSQL。它有一个非常丰富的 SQL 实现,它的速度很快并且可以很好地扩展,并且它有一些东西可以让这个单独的模式的整个想法变得毫无意义:built in JSON type。这可以用来实现文章中提到的“可扩展性”。每个表都可以有一个使用JSON 类型的meta 列,您可以将任何额外的数据放入您喜欢的位置。应用程序不需要特殊查询,meta 列始终存在。 PostgreSQL 的 JSON 运算符使处理元数据变得非常简单和高效。

您也可以查看NoSQL database。有很多可供选择,并且许多支持自定义模式和并行扩展。但是,您可能必须更改您选择的框架以使用支持 NoSQL 的框架。

【讨论】:

    猜你喜欢
    • 2011-02-17
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    • 2011-03-31
    • 2017-05-03
    • 2012-11-08
    • 2021-04-30
    • 1970-01-01
    相关资源
    最近更新 更多