数据库类型
了解系统设计中各种数据库类型及其用途。
如前所述,数据库分为关系型和非关系型两种类型。让我们详细讨论这些类型。
关系型数据库
关系型数据库在存储数据之前遵循特定的模式。存储在关系型数据库中的数据具有先前的结构。通常,该模型将数据组织成一个或多个关系(也称为表格),每个元组(实例)具有唯一的键。数据的每个实体都由实例和属性组成,其中实例存储在行中,每个实例的属性存储在列中。由于每个元组都有一个唯一的键,一个表中的元组可以通过在其他表中存储主键来链接到其他表中的元组,通常称为外键。
用于操作数据库的结构化查询语言(SQL)包括插入、删除和检索数据等操作。
关系型数据库之所以广受欢迎且占主导地位,原因包括管理通用数据时的简单性、健壮性、灵活性、性能、可扩展性和兼容性。
关系型数据库提供原子性、一致性、隔离性和持久性(ACID)属性,以维护数据库的完整性。ACID是一个强大的抽象概念,可以简化与数据的复杂交互,并将许多异常(如脏读、脏写、读取偏差、丢失更新、写入偏差和幻读)隐藏在简单的事务中。
但ACID的设计是像一把大锤,可以适用于所有问题。如果某个特定的应用程序只需要处理少量异常,就有机会使用定制解决方案以获得更高的性能,但增加了复杂性。
让我们详细讨论ACID:
- 原子性: 事务被视为一个原子单元。因此,一个事务中的所有语句都将成功执行或都不执行。如果事务中的一个语句失败,则应该中止并回滚。
- 一致性: 在任何给定时间,数据库应处于一致状态,并且每个事务之后都应保持一致状态。例如,如果多个用户要从数据库中查看记录,则每次都应返回相似的结果。
- 隔离性: 在多个事务同时运行的情况下,它们不应相互影响。数据库的最终状态应与按顺序执行的事务相同。
- 持久性: 系统应确保已完成的事务将永久保存在数据库中,即使在系统故障事件中也是如此。
用于定义关系型数据库模式以及其他操作(例如存储、检索和运行SQL查询)的各种数据库管理系统(DBMS)被使用。以下是一些流行的DBMS:
- MySQL
- Oracle Database
- Microsoft SQL Server
- IBM DB2
- Postgres
- SQLite
为什么选择关系型数据库?
对于结构化数据存储,关系型数据库是软件专业人员的默认选择。这些数据库具有许多优点。
其中最大的优势之一是关系型数据库对ACID事务和相关编程语义的抽象,这使得使用关系型数据库非常方便。
让我们重新审视一下关系型数据库的一些重要特点:
灵活性
在SQL的上下文中,**数据定义语言(DDL)**提供了修改数据库的灵活性,包括表、列、重命名表以及其他更改。
即使其他查询正在执行且数据库服务器正在运行,DDL甚至也允许我们修改架构。
减少冗余
关系型数据库的最大优势之一是它可以消除数据冗余。
与特定实体相关的信息出现在一个表中,而与该特定实体相关的数据出现在通过外键链接的其他表中。
这个过程称为规范化,具有消除不一致依赖的额外好处。
并发
并发是设计企业数据库时的一个重要因素。在这种情况下,数据同时被许多用户读取和写入。
我们需要协调这些交互,以避免数据的不一致性,例如酒店房间的重复预订。
关系型数据库中的并发通过对数据的事务访问来处理。
如前所述,事务被视为原子操作,因此在成功执行时也可以处理错误处理以回滚或提交事务。
集成
从多个来源聚合数据的过程是企业应用程序中的常见做法。
执行此聚合的常见方法是集成共享数据库,其中多个应用程序存储其数据。
这样,所有应用程序都可以轻松访问彼此的数据,而并发控制措施则处理多个应用程序的访问。
备份和灾难恢复
关系型数据库保证数据的状态在任何时间都是一致的。
导出和导入操作使备份和恢复变得更加容易。
大多数基于云的关系型数据库执行持续镜像以避免数据丢失,并使恢复过程更加轻松和快捷。
缺点
阻抗不匹配
阻抗不匹配是关系模型和内存数据结构之间的差异。
关系模型将数据组织成关系和元组的表格结构。
在这个结构化数据上执行SQL操作产生与关系代数对齐的关系。
然而,它也有一些限制。
特别是,表格中的值只能是简单值,不能是结构或列表。而内存中的情况是不同的,可以存储复杂的数据结构。
为了使复杂结构与关系兼容,我们需要根据关系代数对数据进行翻译。因此,阻抗不匹配需要在两种表示之间进行翻译,如下图所示:
视图中的单个聚合值由关系数据库中的多个行和表组成。
为什么选择非关系型(NoSQL)数据库?
NoSQL数据库旨在支持各种数据模型来访问和管理数据。
有各种类型的NoSQL数据库,我们将在下一节中解释这些类型。
这些数据库用于需要大量半结构化和非结构化数据、低延迟和灵活数据模型的应用程序。
这可以通过放宽其他数据库的一些数据一致性限制来实现。以下是NoSQL数据库的一些特征:
简单的设计: 与关系型数据库不同,NoSQL不需要处理阻抗不匹配——例如,在一个文档中存储所有员工的数据,而不是多个需要连接操作的表格。这种策略使它的编写、调试和维护变得简单和容易。
水平扩展: 主要是由于NoSQL能够在大型集群上运行数据库,因此NoSQL更受欢迎。这解决了当并发用户数量增加时的问题。由于特定员工相关的数据存储在一个文档中而不是多个表格上的节点上,因此NoSQL更容易进行水平扩展。NoSQL数据库经常将数据分布在多个节点上,并自动平衡数据和查询。如果节点故障,则可以在不影响应用程序的情况下进行透明替换。
可用性: 为了增强数据的可用性,可以在不停机的情况下执行节点替换。大多数非关系型数据库的变体都支持数据复制,以确保高可用性和灾难恢复。
支持非结构化和半结构化数据: 许多NoSQL数据库处理在数据库配置或数据写入时没有架构的数据。例如,文档数据库是没有结构的,它们允许文档(JSON、XML、BSON等)具有不同的字段。例如,一个JSON文档可能比另一个JSON文档少一些字段。
成本: 许多关系型数据库管理系统的许可证费用相当昂贵,而许多NoSQL数据库是开源且免费提供的。同样,一些关系型数据库管理系统依赖于昂贵的专有硬件和存储系统,而NoSQL数据库通常使用廉价的商用服务器群集。
NoSQL数据库根据操作和特性的性质被分为各种类别,包括文档存储、列数据库、键值存储和图形数据库。
我们将在以下各节中讨论它们以及从系统设计的角度来看它们的用途。
NoSQL数据库类型
下面描述了各种类型的NoSQL数据库:
NoSQL数据库的类型
键值数据库
键值数据库使用键值方法(如哈希表)以键值对的形式存储数据。下面的段落中可以看到这一点的图示。在这里,键作为唯一或主键,而值可以是从简单标量值到复杂对象的任何值。这些数据库允许数据的易分区和水平扩展。一些流行的键值数据库包括Amazon DynamoDB,Redis和Memcached DB。
使用案例:键值数据库对于面向会话的应用程序非常高效。面向会话的应用程序(如Web应用程序)在会话期间将用户数据存储在主内存或数据库中。这些数据可能包括用户资料信息、推荐、定向促销、折扣等等。为了便于访问和存储,为每个用户的会话分配一个唯一的ID(一个键)。因此,更好的选择是使用键值数据库来存储此类数据。
下图显示了键值数据库的示例。商品的“产品ID”和“类型”被共同视为主键。这被视为该键值数据库的键。此外,存储项目属性的模式是基于项目的性质和它所拥有的属性数量来定义的。
在DynamoDB中以键值对的形式存储的数据,其中键是两个属性(产品ID和类型)的组合
文档数据库
文档数据库设计用于以XML、JSON、BSON等格式存储和检索文档。这些文档由可以包括映射、集合和标量值的分层树数据结构组成。
此类型数据库中的文档可能具有不同的结构和数据。
MongoDB和Google Cloud Firestore是文档数据库的示例。
使用案例:
文档数据库适用于非结构化的目录数据,例如JSON文件或其他复杂结构的分层数据。
例如,在电子商务应用程序中,一个产品有数千个属性,在关系数据库中存储这些属性会影响读取性能,因此文档数据库的角色就来了,它可以高效地将每个属性存储在单个文件中,以便进行易于管理和更快的读取速度。
此外,它还是内容管理应用程序(例如博客和视频平台)的良好选择。
在这样的应用程序中,用于应用程序的实体存储为单个文档。
以下示例显示存储在JSON文档中的数据。此数据是关于一个人的。文件中存储了各种属性,包括id
、name
、email
等等。
{ "id": 1001,
"name": "Brown",
"title": "Mr.",
"email": "brown@anyEmail.com",
"cell": "123-465-9999",
"likes": [
"designing",
"cycling",
"skiing"],
"businesses": [
{ "name": "ABC co.",
"partner": "Vike",
"status": "Bankrupt",
"date_founded": {
"$date": "2021-12-10" } }]}
一个包含商人数据的JSON文件。
图形数据库
图形数据库使用图形数据结构来存储数据,其中节点表示实体,边显示实体之间的关系。
基于关系组织节点会产生节点之间的有趣模式。
该数据库允许我们将数据存储一次,然后根据关系不同地解释它。
流行的图形数据库包括Neo4J、OrientDB和InfiniteGraph。
图形数据保存在存储文件中以进行持久化存储。每个文件都包含图的特定部分的数据,如节点、链接、属性等等。
在下图中,使用图形数据结构存储了一些数据,其中节点通过表示节点之间的关系的边连接在一起。
每个节点都有一些属性,如Name
、ID
和Age
。
具有ID: 2
的节点具有名称为James
和29
岁的年龄。
使用案例:图形数据库可以用于社交应用程序,并在不同类型的用户及其活动之间提供有趣的事实和数据。图形数据库的重点是存储数据并为基于实体之间的关系驱动分析和决策铺平道路。图形数据库的性质使它们适用于各种应用,例如数据规范和隐私、机器学习研究、基于金融服务的应用程序等等。
列式数据库
列式数据库将数据存储在列中而不是行中。它们可以快速高效地访问数据库列中的所有条目。流行的列式数据库包括Cassandra、HBase、Hypertable 和 Amazon SimpleDB。
使用案例:列式数据库对于大量聚合和数据分析查询非常高效。它大大减少了磁盘I/O需求和需要从磁盘加载的数据量。例如,在与金融机构相关的应用程序中,需要在一段时间内汇总财务交易。列式数据库通过仅读取金额列,忽略客户的其他属性,使此操作更快。
以下图显示了列式数据库的示例,其中数据以列式格式存储。这与关系数据库不同,后者以行为导向存储数据:
NoSQL数据库的缺点
缺乏标准化
NoSQL没有遵循任何特定的标准,例如关系数据库遵循关系代数。从一种类型的NoSQL数据库迁移应用程序可能是一个挑战。
一致性
当故障发生时,NoSQL数据库基于特定的一致性和可用性权衡提供不同的产品。
我们不会拥有强大的数据完整性,例如关系数据库中的主键和外键完整性。
数据可能不是强一致性的,而是使用弱模型(如最终一致性)缓慢收敛。
选择正确的数据库
选择应用程序中要使用的数据库受到各种因素的影响。
下表比较了关系数据库和非关系数据库,以帮助我们进行选择:
关系型和非关系型数据库
关系型数据库 | 非关系型数据库 |
---|---|
如果要存储的数据是结构化的 | 如果要存储的数据是非结构化的 |
如果需要ACID属性 | 如果需要序列化和反序列化数据 |
如果数据大小相对较小,可以放在一个节点上 | 如果要存储的数据大小较大 |
相关信息
注意:当NoSQL数据库首次出现时,它们与传统数据库相比在编程和使用方面有很大不同。
尽管在过去的多年中,学术界和工业界进行了广泛的研究,使得NoSQL和传统存储之间的面向程序员的差异变得模糊。
我们可以使用相同的SQL语句来访问NoSQL存储并获得与传统存储相似的性能和一致性。
Google的Cloud Spanner就是这样一种具有地理复制和自动水平分片能力以及高速全局数据快照的数据库。
测验
通过测验测试您对不同类型数据库的了解。
- 当我们有非结构化数据且需要高性能时,应该使用哪种数据库?
- 什么情况下应避免选择关系数据库作为应用程序的数据库?
- 如果制作一个需要以表格格式存储数据的零售店应用程序,应该使用哪种数据库?
- 制作类似Facebook的应用程序应该使用哪种数据库?
- 我们应该为哪些应用程序使用文档导向数据库?
- 我们应该为哪些场景使用键值数据库?