用于库存管理系统的SQL与NoSQL比较

9
我正在开发一个基于JAVA的Web应用程序,主要目的是为多个名为“渠道”的网站销售的产品提供库存管理。我们将充当所有这些渠道的管理员。 我们需要的是:
  1. 队列来管理每个渠道的库存更新。
  2. 库存表,其中包含每个渠道分配的正确快照。
  3. 将会话ID和其他快速访问数据保存在缓存中。
  4. 提供类似Facebook的仪表板(XMPP),以尽快向卖家更新。
我正在考虑的解决方案包括Postgres(我们现在使用的数据库是同步复制模式)、Cassandra、Redis、CouchDB和MongoDB等NoSQL解决方案。
我的限制条件是:
  1. 库存更新不能丢失。
  2. 作业队列应按顺序执行,最好不要丢失。
  3. 易于/快速开发和未来维护。
我对任何建议都持开放态度。先感谢您。
3个回答

14
  1. 使用队列来管理每个渠道的库存更新。

这不一定是一个数据库问题。你最好考虑一个消息系统(例如RabbitMQ)。

  1. 库存表应该包含每个渠道上分配的正确快照。
  2. 将Session Id等快速访问数据保存在缓存中。

Session数据可能应该放在一个更适合此任务的单独的数据库中(例如memcached、redis等)。 没有一种适合所有情况的数据库。

  1. 提供类似Facebook仪表板(XMPP)的功能,以便让卖家尽快了解最新情况。

我的限制条件是: 1. 库存更新不能丢失。

有三种回答这个问题的方法:

  1. 这个特性必须由你的应用程序提供。数据库可以保证拒绝和回滚错误记录,但不能保证每个查询都会被录入。 应用程序必须足够聪明,能够识别出发生错误的时候并重试。

  2. 某些数据库将记录存储在内存中,然后定期将内存刷新到磁盘,这可能会导致数据丢失(例如Mongo默认情况下就是这样工作的,除非你启用了日志记录。CouchDB始终追加记录(即使删除也是将标志追加到记录中,因此极难丢失数据))

  3. 某些数据库被设计为极其可靠,即使地震、飓风或其他自然灾害袭击,它们仍然具有持久性。这些包括Cassandra、Hbase、Riak、Hadoop等。

你指的是哪种耐久性?

  1. 作业队列应按顺序执行,最好不要丢失。

大多数NoSQL解决方案更喜欢并行运行。因此,你有两个选择。 1. 使用一个锁定整个表的DB来处理每个查询(速度较慢)。

2. 将你的应用程序构建得更加智能或事件化(客户端顺序排队)

  1. 易于/快速开发和未来维护。

一般来说,你会发现在最初阶段,使用SQL进行开发更快,但是修改可能更难实施。 noSQL可能需要更多的规划,但很容易进行即兴查询或模式更改。

你可能需要问自己的问题更多地是:

  1. “我是否需要强烈的查询或深入的分析,Map / Reduce更适合?”

  2. “我是否需要经常更改我的模式?”

  3. “我的数据高度相关?以什么方式?”

  4. “我选择的数据库背后的供应商是否具有足够的经验在我需要时帮助我?”

  5. “我是否需要特殊功能,如地理空间索引、全文搜索等?”

  6. “我需要多接近实时的数据?如果我直到1秒钟后才看到最新记录出现在我的查询中,会对我造成影响吗?可以接受什么级别的延迟?”

  7. “我真正需要什么样的故障转移?”

  8. “我的数据有多大?它是否适合内存?它是否适合一个计算机?每个单独的记录是大还是小?”

  9. “我的数据会经常更改吗?这是一个归档吗?”

如果你将要拥有多个客户(频道?)各自拥有自己的库存模式,那么基于文档的数据库可能具有优势。我记得有一次我看过一个带有库存的电子商务系统,它有近235张表! 另一方面,如果你有某些关系型数据,SQL解决方案也可以有一些优势。

我当然可以看出如何使用Mongo、Couch、Riak或Orientdb来构建符合给定约束条件的解决方案。但至于哪种最好?我会尝试直接与DB供应商交流,也许观看noSQL磁带。


6

解决您的限制:

  1. 大多数NoSQL解决方案都提供了一种可配置的一致性与性能权衡。例如,在MongoDB中,您可以决定写入应该有多持久。如果您想要,您可以强制在所有副本集服务器上同步写入。另一方面,您也可以选择发送命令并且甚至不等待服务器的响应。

  2. 按顺序执行作业队列似乎是一个应用程序代码问题。我认为数据库中的时间戳和类似于order by的查询对于大多数应用程序来说已经足够了。如果您有多个应用程序服务器,并且您的队列需要完美,请使用真正分布式算法提供排序,但这不是典型的要求,而且非常棘手。

  3. 我们已经使用MongoDB一段时间了,我相信这确实加速了您的应用程序开发速度。维护数据没有太大区别,无论如何维护数据都是痛苦的。没有模式给您增加了灵活性(懒惰迁移),但它更为复杂,需要一些小心处理。

总之,我认为您可以两种方式都做。NoSQL更多地由代码驱动,事务和关系完整性大多由您的代码管理。如果您对此感到不舒服,请选择关系型数据库。

但是,如果您的数据变得非常庞大,则必须手动编写一些此逻辑,因为您可能不希望在10亿行数据库上进行实时联接。但是,您也可以使用SQL实现这一点。

找到不同数据库的边界的一个好方法是考虑您可以缓存什么。可以随时缓存和重构的数据是引入新层的绝佳方式,因为那里没有太大的风险。此外,缓存的数据通常不保留任何关系,因此您在这里不会牺牲任何一致性。


4

对于这个应用程序来说,NoSQL不是正确的选择。

我的意思是,你当然可以使用它,但最终你将不得不重新实现SQL为你提供的许多功能。例如,我看到了许多关系。你还需要ACID(虽然一些NoSQL解决方案确实提供了这个)。

你可以同时使用两种数据库类型——在关系型数据库中保留关系型数据,在键值存储中保留非关系型数据,这没有问题。


这是我目前倾向于的(关系型+NoSQL),但在哪里划分边界?我能否将一些关系型业务逻辑迁移到NoSQL领域,以便可扩展性内置?我处于开发模式,所以如果值得的话,我可以接受变化。 - gladiator
等等 - 你是想用NoSQL来实现可扩展性吗?那可不是使用它的正确理由!SQL和NoSQL都可以进行扩展。将SQL迁移到NoSQL非常困难,而反过来则很容易。 - Ariel
不是技术,而是功能:如果你试图在巨大的表上执行复杂的连接操作,它不会足够快。没有银弹可以让这种工作变得更快。 - mnemosyn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接