当你需要ACID属性来维护数据间的关系时,可以用关系型数据库。对于其他的数据存储,需要考虑更合适的工具。适用于在系统架构中引入新数据或数据结构时。在选择最合适的存储工具时,要考虑数据量、存储空间响应时间的要求、关系以及其他多种因素。
RDBMS提供了最好的事务完整性,但相对于其他存储选择,这种数据库很难扩愚且扩展成本高,可用性低。为数据选择正确的存储工具。不要因为你习惯用数据库访问数据,就总用关系数据库存储数据。
关系数据库管理系统(RDBMS)(如Oracle i和 MYSQL)是以Edgar F.Codd于1970年发布的论文“大型共享数据库数据的关系模型”(“A Relational Model of Data for Large Shared Data Banks”)中的关系模型为基础的。大多数 RDBMS对于存储数据有两大好处。第一个好处是利用ACID属性确保了事务完整性,关于ACID的定义,请参阅表2-1。第二个好处在于表内和表间的关系型结构。为了最小化数据冗余,提高事务的处理能力,大多数联机事务处理理(OLTP)系统中的表都被规范化为第三范式即表中的所有记录都有相同的字段,所有非主关键字的字段都不能只依赖于组合关键字的一部分,所有非主关键字字段必须依赖于主关键字。
表中的每一列数据都要依赖于表中的其他列数据。表之间的关系通常以外键表示。虽然使用 RDBMS有这两点好处,但它们也是限制了扩展性的原因。为了确保ACID属性,扩展RDBMS比扩展其他数据存储难得多。为了在具有多个节点的 RDBMS集群(如 MYSQL NDB)中确保数据致性,要采用同步复制的功能才能保证所有数据在提交时被写入多个节点。采用 Oracle RAC,会有一个中央数据库,但是数据库域的所有权却是所有节点共享的。因此,对于写请求,要把数据所有权转移到相应的节点,而对于读请求,则要依次从请求者发送到主节点,再从主节点发送到拥有要读的数据的节点,再从它发回到请求者。最终,你会受到同步复制数据的节点数或它们的地理位置的限制。
RDBMS中表内和表间的关系结构使得很难对数据库进行分片或分区操作。关于把工作分发到多台机器上的原则。在把表拆分到多个数据库的应用中,原来在单一数据中连接两个表的简单査询就要被转换成两个查询来连接数据。
总而言之,只有要求事务完整性或数据间有关系的数据,才需要使用 RDBMS。既不要求数据间的关系,也不要求事务完整性的数据,最好采用其他的存储系统。我们来简单讨论几个可用的解决方案,以及如何用它们代替数据库,以达到更好的、性价比更高的、扩展性更高的效果种常常被忽略的存储系统是文件系统。也许这是一种简单的存储方式,因为大多数程序员最初编程时,访问的都是文件而不是数据库中的数据。一旦我们学会了在数据库中存储或获取数据,就再也不用文件。文件系统已经发展很久了,而且许多文件系统是专门为处理非常大量的文件和数据而设计的。
这些文件系统包括 Google File System(GFS)、Mogilefs和Ceph等。如果你的系统是“一次写,多次读”的,那么文件系统是个很好的选择。换句话说,如果不会发生读写冲突,不需要维护大量的数据关系,并不真正需要用到数据库事务,那么采用文件系统才是最好的选择。另一种存储策略叫做 NOSQL。这一类存储技术通常被划分为键一值存储、可扩展记录存储和文档存储。关于这种技术分类,并没有统一的标准,很多技术可以被分到多个种类中。在下面的介绍中,我们加入了一些技术的示例,但不要把它们当做最终的解释。考虑到这些项目发展的速度,那么将来这种分类很可能更加模糊。
键一值存储技术包括 Memcached、 Tokyo Tyrant和 Voldemort。这些产品中的数据都有一个键一值索引存储在内存中。有些产品能够把健值异步复制。通过简化的数据存储模型和键一值对,这类产品能够提供很高 写人硬盘永久存储。有些产品会在节点间进行同步复制,而有的则进行的可扩展性和性能,但在能存储什么数据方面具有很大的限制。此外,依赖同步复制的键一值数据存储仍然具有与 RDBMS集群一样的限制,即在节点数量和地理位置方面的限制。
可扩展记录存储技术包括 Google公司专有的 Big Table和 Facebook公司的(现在已经是开源的) Cassandra。这些产品采用的是可以拆分到节点的行列数据模型。可以根据主键对行进行拆分或分片,再对列进行分组,存放到不同的节点上。这种扩展方法与展示的AKF扩展立方中的X轴和Y轴拆分方法相似,X轴拆分是读取数据副本,Y轴是根据支持的服务来分割表。在这些产品中,行分片是自动执行的,但是列拆分则需要用户定义,与在 RDBMS中的操作类似。这些产品使用的是异步复制,最终能达到一致性。这意味着,也许几毫秒或几小时后,最终所有节点上的数据将是一致的。
文档存储技术包括 COUCHDB、亚马逊的 Simpledb和雅虎的 PNUTS。这种技术采用的数据模型虽然被称为“文档”,但其实称为多索引对象模型更确切。这些多索引对象(或者说“文档”)可以聚集到多索引对象的集合(通常称为“城”)中,然后可以对这比值合成情由查询。文档存储技术不支持ACID属性,相反地,它们采用的是异步复制方法,最终能使数据达到一致。
NOSQL解决方案把对象和实体之间的关系限制到了最少。正是因为减少了关系,所以能够把系统分发到多个节点上,在维持事务完整性和解决读写冲突的同时,实现了更大的可扩展性。
通常情况下,我们都需要对系统的可扩展性和灵活性进行权衡,在读过前面的介绍之后,也许你已经有了决定。数据实体之间的关系是进行衡量的关键,随着关系增多,灵活性会增加。灵活性增加,会使成本增加,可扩展性降低。从扩展系统的成本(和限制)与数据实体之间的关系程度这两个方面对比了 RDBMS、 NOSQL和文件系统这三种解决方案。图4-2则从灵活性和系统允许使用的关系程度两方面进行了对比。结果很显然,关系带来了灵活性,但降低了可扩展性。正因如此,我们不想滥用关系数据库,而是要采用适合任何的工具,使系统得到更大的扩展性。
在这个原则中,我们要介绍的另一种数据存储方法是Goge的Mapreduce方法リ。简而言之, Mapreduce方法具有两个功能,即Map 和 Reduce。Map功能的输入是一个键一值对,生成一个中间键一值对。输入的键可能是一个文档名或者指向文档中的某一段的指针。值可能是文档中的所有文字。Map功能的输出将输入到 Reduce功能,该功能使用个程序对文字和文字段分组,并且把值添加到一个列表中。这是个不算复杂的程序,根据键对数据进行排序和分组。这种技术最大的好处是能够把非常大的数据集的计算分发到许多服务器上。
Apache的 Hadoop则是采用两种存储方法的组合的一个实例。它采用了 Google的 Mapreduce技术和 Google File System,这两种方法前面都介绍过。 Hadoop既是具有高可扩展性的文件系统,又能够分布式地存储和获取数据。
许多替代数据库的数据存储方法,那么在决定选择哪种方法时,应该考虑数据的哪些特征呢?与存储方法有很多选择一样,需要考虑的数据特征也有很多。最重要的几个是数据元素间的关联程度,解决方案的发展速度以及数据的读写比例(可能还有数据是否更新)。最后,我们关心的是如何把数据变现(换句话说,是否有利可图),因为我们不想让自己的系统成本超出收益。
成本和开发时间。例如,假设把一个涉及用户、付款、采购等信息的事务存储在一个键一值存储中,然后在采购报告内体现其中的信息片段,想象一下有多么困难吧。虽然你可以采用文件系统或者 NOSQL存储方法实现它,但向用户交付结果需要的开发投入和时间成本都很高。
预期的增长速度非常重要,原因很多。最终,这个增长速度会影响系统的成本和客户响应时间。如果数据实体间需要高度的联系,那么我们可能需要利用所有的硬件和处理能力来支持单一的整合数据库,促使我们把数据库拆分成多个实例。
读写比例非常重要,因为它有助于我们理解需要什么样的系统。只写一次而读多次的数据可以采用文件系统外加某种应用、文件或对象缓存。图像就是采用文件系统进行存储的典型例子。写过之后需要更新的数据,或者具有很高写读比例的数据,最好采用 NOSQL存储或 RDBMS。这些需要考虑的因素构成了另一个立方体,分别用X轴、Y轴和Z轴表示了这三个因素。随着这三个因素的值增加,最终解决方案的成本也会增加。如果我们要求系统间有高度的关联、高速增长、能够解决读写冲突,那么最好采用几个较小的 RDBMS系统,这样在开发、系统维护甚至数据库许可方面的成本可能相对较高。如果增长速度较慢,规模较小,但是关系很多需要解决读写冲突,那么可以使用单个的大型数据库(具有高可用性的集群)。
如果数据间的关系不是非常多,那么在任何水平的读写冲突和几乎任何水平的增长速度下,都可以使用 NOSQL存储技术。这里,我们再次看到了关系对成本和复杂度的影响程度,我们将在第8章中探讨这个主题。采用 NOSQL技术的成本较低。最后,如果数据关系不多,不关心读写冲突,那么可以采用成本更低的文件系统。
我们必须理解
网站制作数据的货币价值,因为许多公司在艰难起步时期都经历过,用A级存储免费存放TB级的用户数据,很快就会把资金消耗完。较好的方法是分层存储数据,根据访问日期,不停地把较老的数据下推到较便宜的访问较慢的存储媒体上。这种情况叫做成本一数据价值的困境,即随着时间流逝,数据价值会降低,但是保存数据的成本会增加。