无模式/灵活+ ACID数据库?


15

我正在考虑将基于本地(本地安装)的VB应用程序(发票+库存)重写为面向小型企业客户的基于Web的Clojure应用程序。我打算将此作为SaaS应用程序提供给类似行业的客户。

我正在查看数据库选项:我的选择是RDBMS:Postgresql / MySQL。我可能会在第一年扩大到400位用户,通常每位用户每天20-40个页面浏览量/每天-主要用于非静态视图交易。每个视图将涉及获取数据和更新数据。必须符合ACID(或我认为)。因此交易量并不大。

毫无疑问,根据我的喜好选择这两种方法,但是对于这一要求,我认为这是SaaS应用程序的典型要求:随着我添加更多的客户/用户以及每个客户的需求,架构将发生变化。不断变化的业务需求(刚开始我会提供一些有限的灵活性)。由于我不是数据库专家,根据我的想法和所读的内容,我可以通过多种方式来处理:

  1. 在MySQl / Postgresql中进行传统的RDBMS模式设计,其中一个DB托管多个租户。并在每个表中添加足够的“自由浮动”列,以允许将来随着我添加更多客户或现有客户的更改而进行更改。每次对模式进行小的更改时,将更改传播到数据库中可能会有不利之处。我记得读过一篇文章,在Postgresql模式中更新可以实时完成而无需锁定。但是不确定,在这个用例中它有多痛苦或有多实用。而且,由于架构更改可能还会引入新的/次要的SQL更改。
  2. 有一个RDBMS,但是以灵活的方式设计数据库模式:具有接近实体属性值或仅作为键值存储。(例如,工作日为FriendFeed)
  3. 将整个事物作为对象存储在内存中,并定期将它们存储在日志文件中。(例如,edval,lmax)
  4. 选择NoSQL数据库,例如MongoDB或Redis。但是根据我的收集,它们不适合此用例,也不完全符合ACID。
  5. 寻找一些新的SQL Db,例如VoltDb或JustoneDb(基于云),它们保留SQL和ACID兼容行为,并且是“新一代” RDBMS。
  6. 我看了neo4j(graphdb),但不确定是否适合此用例

在我的用例中,除了可伸缩性或分布式计算之外,我还在寻找一种更好的方法来实现“模式中的灵活性+ ACID +一些合理的性能”。我在网上可以找到的大多数文章都谈到模式的灵活性,这是导致性能(在NoSQL DB的情况下)和可伸缩性的原因,而忽略了ACID /事务。

这是“模式灵活性与ACID”事务的“或”案例,还是有更好的出路?


2
在PostgreSQL中检查hstore模块。在SQL数据库中就是“ NoSQL”:postgresql.org/docs/current/static/hstore.html
a_horse_with_no_name 2012年

@马:谢谢...这是一个很好的指针。我听说过MySQL的NoSQL插件。我在寻找类似的Postgres。
tmbsundar

Answers:


11

选项1

造成这种情况的原因有很多,我将在下面解释。首先,这是操作方法。

  • 使用您选择的标准RDBMS平台。

  • 使用几个用户可配置的字段来设置架构,并使您的应用程序便于每个租户进行配置。

  • 从每个租户元数据中,您可以创建数据的每个租户视图,该视图具有内置的过滤器以及从元数据中命名的列。提供的任何报告也可以继承元数据。如果他们想对数据进行MI处理,则向他们提供交易数据的摘录,或者如果他们愿意为此付费,则可以在其他服务器上提供一些其他MIS应用程序。

  • 除非客户准备为自己的私有实例付费并维护自定义版本,否则不要尝试提供更多自定义内容(即,不对架构进行重大更改)。

其背后的原因是:

  • 这些数据库系统将处理您在相当普通的硬件上描述的那种卷。您实际上没有像NoSQL数据库那样的事务量。除非您有其他一些需要的架构原因,否则尖端技术是没有多大意义的。

  • 它们是成熟的,易于理解的技术。

  • 系统管理,备份/还原,复制,报告和灾难恢复都在RDBMS平台上进行了很好的分类。

  • 您可以获得适用于所有主要RDBMS平台的客户端库,包括JDBC。

  • 视图可用于按用户自定义并从您的应用程序元数据生成。

  • 它比XML字段或EAV结构要有效得多。


@COTW:感谢您提供详细的答案。我关心的一件主要事情是模式的“预期”更改,我想我必须仔细考虑并使其尽可能多地“可预配置”,并避免以后发生剧烈的模式更改。
tmbsundar

如果单个租户共享表,则灾难恢复并不简单。(如果每行都有一个租户ID号。)
Mike Sherrill'Cat Recall'12

为此,但使用JSON列:gist.github.com/tobyhede/2715918
mwhite 2014年

5

使用PostgreSQL,您可以选择使用单独的数据库,单独的模式或视图来处理多租户。

使用多个数据库(在同一数据库服务器内)使管理更加复杂,因为必须分别管理每个数据库。因此,只有在最关注租户之间的安全性的情况下才建议这样做。

分离的模式提供了很大的灵活性和安全性,但是使升级更加复杂,因为它们必须单独应用,并且可能仅在租户使用完全不同的表结构时才需要;如果他们使用相同的应用程序,则不太可能。

视图使租户可以查看公用表结构的不同部分,并允许您控制他们有权访问的表,列和行。唯一的警告是您的应用程序必须确保它仅使用那些视图而不使用基表,否则租户之间可能会由于软件缺陷而导致意外数据泄漏。

您实际上并不需要在应用程序需求之前创建列。列可以动态添加到表中(对用户没有任何明显影响),视图也可以动态更新。您只需要考虑进行更改的顺序-即。更改表,然后查看,然后查看应用程序代码。

唯一潜在的问题是,如果您需要添加需要添加到现有索引或需要新索引的新列。那就是在建立索引时可以锁定使用表的情况-但是PostgreSQL支持在不锁定表的情况下同时建立索引的功能。除非新索引需要是唯一的并且发现唯一性违规,否则这将很好地工作。

您可能不需要NoSQL数据库,因为它们可以从数据库中有效删除架构,而需要应用程序来管理它。听起来您的工作量并不需要这种牺牲。


1
使用9.1,您甚至可以替换唯一约束或主键而无需锁定表。在这里看到:depesz.com/index.php/2011/02/19/...
a_horse_with_no_name

同意 我试图说的是,当创建唯一索引但违反了约束时会出现问题-然后您必须解决唯一性问题。这更多的是添加列而不是添加索引本身的问题。
邓肯保利

@DuncanPauly:感谢您的见解。我从您的回答中了解到Postgresql允许“在线/实时模式更改”。但是,当我使用google时,我得到的大多是'facebook online schema change'或'pt-online ...'等,它们与MySQL有关。您是否知道有助于我了解Postgresql实时模式更改的链接或资料?感谢您的帮助。谢谢。
tmbsundar 2012年

此链接描述了如何更改表postgresql.org/docs/8.1/static/ddl-alter.html。要记住的重要原则是,创建,更改和删除表或视图实际上是瞬时的。而创建和更改索引仅此而已。
Duncan Pauly
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.