【CSDN编者按】据不完全统计,目前已有340多个处于活跃且仍在更新的数据库供开发者选择。但事实上,这些方案的目的只有一个:解决存储和读取基于文本的信息。本文试图在乱象中指出一条路,带你看尽最受欢迎的数据库推荐榜单。
以下为译文:
有一天我在午饭时遇到个朋友,于是聊起了数据库和数据存储解决方案方面的乱象。所谓乱象是指,在我写这篇文章时,《数据库引擎排名》(https://db-/en/ranking)上已经列出了340多个处于活跃且仍在更新的数据库供选择,而每种方案其实都在用略微不同的方案试图解决同一个问题:存储和读取基于文本的信息。本文试图在乱象中指出一条路,找出一种方案来帮你选择最适合项目的数据库。
当谈论数据库时,我们其实在谈论什么?
本文中所说的数据库是指数据库管理系统(Database Management Systems),其目的是在硬盘或SSD上存储文本信息,以提供立即访问数据的能力(通常在几秒内)。
也就是说,我们的谈论并不包括:
纯粹的内存缓存,如Memcached(/)这种进程停止时会丢失全部数据的系统;
文件存储,或其他任何形式的存储,如AWS S3(/s3/)或Azure Managed Disks(/en-us/services/managed-disks/);
长期的备份和数据仓库解决方案,如AWS Glacier(/glacier/)。
那么,怎样才能为项目选择合适的数据库呢?
私有还是开源?
首先从一个无聊的商业问题说起:你想为数据库花钱吗?这里不包括那些云服务的账单(我们会在下一段讨论),而是指自己搭建服务器的情况下,数据库所需的授权费用。
等等,不是有能免费使用的开源数据库吗?而且还很好用不是吗?对,不过许多公司希望数据库能提供99.999%的稳定性保证,以及能在清晨五点拨打的技术支持电话。实际上,前十大最流行的数据库中的四个都有商业授权(Oracle(/database/index.html),Microsoft SQL Server(/en-us/sql-server),IBM DB2(/analytics/us/en/db2/)和Microsoft Access(/en/access)),其中Oracle还是所有数据库中的第一名。
云服务还是自己搭建服务器?
运行数据库非常容易,只需要点击一个可执行文件,或者启动服务,数据库服务器就能跑起来了。但在生产环境中真正地运营一个服务器却非常困难。分片(sharding)、创建读写副本(replica)、持续备份、热更新……这也是数据库管理员这个职位存在的原因。
如果你不想干这些,那最好还是使用云服务吧。这里我们还需要区分两大类数据库——姑且称之为“被管理的”数据库和“无服务器”数据库。
被管理的数据库云服务能够以完全受管理的服务的方式为你提供最流行的开源数据库。例如AWS RDS(/rds/),它可以提供MySQL/MariaDB/Postgres等实例。这种数据库的问题是,你还得自己决定一些问题,诸如“数据库要多大”、“需要多少个实例”、“多长时间做一次备份,备份存放在哪里”等问题。
如果连这些你也不想做,那可以使用现在越来越流行的“无服务器”数据库,或者叫做“数据库即服务”。这些通常是云服务供应商的私有数据库,你只需要连接到某个API上存储数据就行了。如AWS DynamoDB(/dynamodb/)、Azure CosmusDB(/en-us/services/cosmos-db/)和Google Firebase(/)等均属此类。
数据模型
现在来讨论下最重要的问题:哪种数据模型最适合你的数据结构?可选项有:
关系型 / 表
关系型数据库在表中存储数据,表有多个列,每列都有自己的数据结构(文本、数字、日期等)。每行都由唯一的ID确定,称为“主键”。数据之间的关系通过引用其他行的主键来实现。
数据通常由“结构化查询语言”(即SQL)负责创建和读取,这种语言有丰富的功能。
选择关系型数据库的理由
关系型数据库是最常见也是应用最广泛的数据库,这是有原因的。这种模型尽管不灵活,但很稳定,能避免数据重复,还可以给开发者提供可预测的结果。此外,这个分类下有大量非常成熟的数据库系统,如PostgreSQL(/)和MySQL(/),而成熟、稳定的结果和安全可能是选择数据库时需要考虑的最重要的因素。
不选择关系型数据库的理由
关系型数据库需要预先定义表结构,这种表结构通常是静态的。尽管可以修改已有表的列定义,但通常需要额外的开销。而且,每个列只能保存一种数据类型。这种方式可以让数据库管理系统减少存储空间并避免数据重复,但NoSQL的提议(见下一段)认为,存储空间已经十分廉价,牺牲灵活性换取存储空间已经没有必要。
对象 / 文档 / NoSQL数据库
除了一些例外情况,这类数据库会将所有相关信息保存在对象中(比如应用程序的用户,或者唱片目录中的一张专辑),使用一个结构松散的JSON数据块保存,这个数据块被称为“对象”或“文档”。同类型的多个文档以“列表”或“集合”的方式组织。对象数据库的数据建立、读取和搜索方式多种多样,有的提供RESTful API(如CouchDB(/)),有的以Map-Reduce等函数式编程概念提供(MongoDB(/))。
选择对象数据库的理由
倒退几年,NoSQL的热潮像暴风雨一样席卷了整个数据库世界。NoSQL不是一个概念,而是一次运动,口号就是“打倒关系型数据库”。今天,在经历了无数的运维危机和莽撞的系统转换之后,NoSQL在大量存储解决方案中间找到了应属于它的位置。NoSQL是个伟大的工具,而不是根治一切的灵丹妙药。它的灵活性给开发者带来了极大方便,如在同一个集合内存储不同结构的文档,无需担心数据类型和数据的强关联并由DBMS搞定一切等。
不选择对象数据库的理由
有一点混乱是好事儿,但对象数据库在原则上的缺失使得它在大公司里并不受欢迎。而且,高度关系型的数据依然更适合保存在关系型数据库或者图数据库中,只有一小部分数据被孤立的情况下才能很好地应用文档数据库。
图数据库
图数据库提供了另一种对数据间关系进行抽象的方式,在严格的表和松散的文档之间找到了很好的平衡。在图数据库中,每个实体(节点)是个独立的文档,其中包含一系列可以嵌套的属性。这些节点由“边”连接起来,这些边构成了节点之间的关系。边可以拥有自己的属性。听上去似乎很复杂,但可以这样考虑:“John有四个红苹果”这个事实可以分解为:John(节点A)有(边)四个(边属性)红(节点B的属性)苹果(节点B)。
大多数图数据库都提供了丰富的工具用于对复杂网络的节点进行查询、遍历和求值,如找出所有连接的节点、找出连接最多的节点、找出最近的邻居等。
选择图数据库的理由
图数据库是组织高度互联的数据的绝佳方法。比如要构建一个支付系统,在每笔交易中钱可以在多个账户之间转手,那么图数据库可以显著降低复杂度,如在多个交易步骤中跟踪每笔支付等。
不选择图数据库的理由
图数据库在相对简单的情况下会有很大的额外开销。特别是线性数据系列(如会话日志)非常不适合图模型。而且图模型的最大难点就是它需要对数据模型进行深度思考,通常这会给开发人员带来相当大的压力。
键值数据库
有些情况下,你只需要简单地保存些数据,这些数据可以用键来标识。这种情况下应该使用键值数据库。键值数据库非常简单,因此访问非常快,特别适合非关系型数据。比如像bit.ly这种短地址生成器,它只需要使用一个代码查找原始地址,而不需要任何复杂的查询。
使用键值数据库的理由
如果数据很简单,那么使用键值数据库可以很方便扩容。
不使用键值数据库的理由
关系型数据、拥有复杂结构的数据,或者需要查询或搜索的情况。
宽列数据库
宽列数据库就像是有第二个维度的键值数据库,或者更恰当的比喻就是拥有无限的动态行和列的Excel数据表。宽列数据库可以快速查找行、列或行列交点,并可以快速读写大量数据。
使用宽列数据库的理由
如果数据可以放到一个巨大的Excel表中,那么宽列数据库简单的数据模型可以实现方便的扩展,并且很容易进行复制(replication)和分片(sharding)。
不使用宽列数据库的理由
尽管Apache Cassandra(/)等数据库支持简单的查询,但如汇总(求和、求数量、求平均值)等更高层次的功能依然受限。而且,许多宽列数据库仅提供结果一致,并不提供强一致,因此很难用于事务型应用。
时间序列数据库
时间序列数据库只做一件事,而且做得很好。这种数据库以二维形式存储线性数据序列,两个维度之一通常为时间,另一个维度是一个或多个值。时间序列通常用于服务器监视或财务记录,但并不是通用的解决方案。
使用时间序列数据库的理由
如果需要有效地存储并查询时间序列数据,就可以使用时间序列数据库。如果应用中的数据只有少量时间序列,那么关系型数据库一般够用。多数情况下,时间序列数据库能提供更高层次的功能,如当特定的值被破坏时发出警告等。
不使用时间序列数据库的理由
如果数据不是时间序列,或在一个大型应用中只需要存储少量时间序列数据,那就不要使用时间序列数据库。
还有什么?
这些基本上覆盖了主要的数据库类型。但还有相当数量的特殊类型数据库,如Elasticsearch(https://www.elastic.co/)等代表底层数据数据的搜索引擎,或用于XML、YAML等特殊格式的数据库。除此之外,还有一些多概念的数据库,比如结合关系型和图数据的数据库,或允许动态表结构,从而可以支持像对象一样的灵活性的数据库等。有些情况下,这些数据库也许更合适。
在商用方案与开源方案、云服务于自行架设服务器方面做出决定,并确定了数据模型之后,还有一些因素需要考虑:
可扩展性和一致性
许多数据库提供“强”一致性,即在数据读取时,即使数据库集群中的部分节点失效,或发生任何灾难性的事件,也能保证所有的写操作都已完成,所有数据都是最新的。这种一致性会对性能造成可观的影响,但对于多数应用来说,这是绝对必要的。要想知道某个数据库是否满足一致性需求,可以看看“ACID依从性”(即原子性、一致性、隔离性、持久性)。关于更深入的测试以及理解失败情况下的数据库行为,可以看看与此相关的Jepsen报告(https://jepsen.io/analyses)。
实时查询,报警,触发器和其他特性
许多数据库在纯粹的存储和数据获取之外还提供其他特性。例如RethinkDB(/)提供的实时查询(在底层数据发生改变时自动更新结果的查询)功能,还有Elasticsearch(https://www.elastic.co/)、Algolia(/)提供的支持词干提取和同义词等复杂全文搜索功能,甚至连PostgreSQL(/)这样的数据库(作者最喜爱的数据库)都提供了完整的可编程数据环境、完整的触发器功能和发布者/订阅者方式的消息功能。
接下来干什么?
有了上面这些知识,你可以去看看DB Engines Ranking(https://db-/en/ranking)网站,上面列出了你能想到的所有数据库,并根据流行度进行评分。可以从这个网站上根据你的条件选一两个流行的数据库,来帮助你的项目获得成功吧。
原文:/blog/choosing-a-database-in-/
作者:Wolfram Hempel,Arcentry的创始人,DeepstreamIO的联合创始人。
译者:弯月,责编:郭芮