MySQL的NoSQL转变:如何正确使用?

发表时间: 2015-09-29 21:08

【编者按】随着互联网和移动互联网的发展,各个机构都需要支撑远超过以往的数据。而在这个需求的刺激下,IT领域出现了大量数据处理技术,其中之一就是NoSQL。灵活的数据类型,高效的处理能力,让NoSQL已占据数据管理系统的一席之地,比如人气NoSQL数据库MongoDB。然而在Wix工程实践中,他们发现,大量场景中其实并不需要NoSQL,反而成熟的RDBMS更具效益,比如MySQL。下面一起看Wix工程主管 Aviran Mordo的分享,由OneAPM工程师翻译。

以下为译文

开发人员选择NoSQL数据库一般都是根据主观臆断,或者“关系型数据库性能不如NoSQL数据库”这个错误的理念。此外,在做数据库选型时,开发人员往往还忽视了运维上的开销。实际上根据Wix的实践发现,大部分情况下都不必去选择NoSQL数据库,而且如果使用得当的话,MySQL也可以是一个优秀的NoSQL数据库。

在可扩展系统构建时,一个很重要的考量是使用的技术是否成熟,选择成熟的技术意味着出错时能够迅速恢复。当然,开发者也可以在项目中使用最新最牛的NoSQL数据库,而这个数据库在理论上也可以良好地运行,然而在生产环境中出现了问题恢复需要多久?技术上已有的知识和经验积累对于问题缓解至关重要,当然这个积累也包括了Google可以搜索到的内容。相比之下,关系型数据库已经存在了超过四十年,业界对于关系型数据库的维护也积累了大量的经验。基于这些考虑,在新项目做技术选型时通常会选择MySQL,而不是NoSQL数据库,除非NoSQL真的有非常非常明显的优势,比如数据量太大就不适合使用MySQL。

必须承认MySQL也有自己的问题。在大规模系统中使用的话可能会碰到性能上的问题。为实现MySQL性能的最优化,这里总结了几条经验,其中之一是避免数据库级别的事务。因为事务需要数据库采用锁来实现,从而会影响数据库性能。通常情况下会使用逻辑应用程序级的锁来 替换,从而减少负载并获得一个更好的性能。

举个例子,以发票结构为例。如果某个发票有多个行项目,取代在单事务将所有行项目写入,这里更应该在非事务情况下逐行写入。在所有行全部写入数据库后,这里还会写入一个首记录,它包含了指向所有行项目ID的指针。这样一来,如果所有行中有一行写入失败,那么这行的首记录就会不存在,从而整个事务失败。这么做虽然可能会造成一些垃圾记录,但在存储介质如此便宜的今天这显然不是什么大问题,而这些垃圾记录也可以做定期删除。

下面也中介了一些MySQL实践经验:

  • 不要使用joins查询,只做主键或者索引查询。
  • 不要使用自增主键因为会有锁,取而代之,使用客户端生成键,比如GUIDs。同时,如果你使用主主备份,自增键还可能会冲突,因此你需要为每个实例都定制键的范围。
  • 没有索引的字段通通删掉或者使用JSON集合成单一字段。

在Wix,MySQL经常会被当做键值存储,比如在一列中储存JSON对象,从而在不改变数据库模式下对数据结构模式进行扩展。在MySQL中,使用主键读取也很快,Wix就通过这个方式获得了亚毫秒级的读取速度,完全可以支撑整个使用场景。基于以上这些原因,MySQL完全可以看作一个符合ACID原则的NoSQL数据库。至于数据库的大小,一个MySQL实例支持几亿条数据是没什么问题的。

关系型数据库的一个鲜明的优势是不用考虑最终一致性,而这个在NoSQL数据库中并不是原生支持的。本文也不是贬低NoSQL,因为关系型数据库已有限制也非常多:严格的数据结构和大小限制。这里只是想提醒开发人员,在选择新技术时不要忽视运维成本。

原文链接:MySQL is a Great NoSQL Database (责编/仲浩)