介绍
您应该选择文档数据库还是关系数据库?
这种选择对应用程序性能、成本和代码可读性有广泛的影响,应该仔细考虑。在这篇文章中,我想解释一下我认为的“需要考虑的点”。
需要考虑的要点
1. 哪种数据模型最适合您的应用程序代码?
是否应该将数据记录存储为文档(即 JSON 对象)而不施加架构约束?或者我应该规范化模式并将数据分成几个表?
为了做出这样的判断,最好看一下你正在开发的应用程序的模型关系(例如User和Task之间的关系是1:N)和一次读取的数据类型。
推荐使用 Document DB 时
应用程序数据能否以如下所示的树形结构表示?您通常一次加载所有数据吗?
如果两者的答案都是肯定的,那么将这些数据作为单个“文档”存储在文档数据库中可以简化使用它的应用程序代码。
可以以树结构表示并且通常一次读取的数据与文档数据库兼容。
{
"id": "bbc16639-c082-47e8-b9c0-2d59579c7336",
"first_name": "taro",
"last_name": "momo",
"lastLoggedIn": "2022-07-31T06:03:37+00:00",
"email": "taro@example.com",
"skills": [
{"name": "python"},
{"name": "golang"},
{"name": "英語"}
],
"work_history": [
{
"company": "ENECHANGE",
"position": "Software Developer",
"start_date": "2018-03-26",
"end_date": null
},
{
"company": "Company Inc.",
"position": "Software Developer",
"start_date": "2016-01-06",
"end_date": "2018-03-20"
}
]
}
何时推荐使用 RDB
您的应用程序的数据记录是否具有多对多关系,例如:
如果是这样,RDB(或 Graph DB)可能更适合您的应用程序。原因是文档DB几乎没有JOIN语句的概念,这是因为应用程序需要执行绑定过程。.如果您将文档数据库(作为主数据库)引入需要进行许多连接的应用程序,则连接过程会使代码变得复杂。
另一方面,RDB 在数据库内执行连接处理。许多 JOIN 语句不应该使您的应用程序代码的可读性降低。
2. 你需要架构灵活性吗?
典型的文档数据库不会对记录施加模式限制或数据类型限制。您可以自由添加任何结构的文档。另一方面,在RDB中,在插入记录的同时,会详细检查数据类型和与其他记录的关系。
推荐使用 Document DB 时
文档数据库是读模式叫。这是因为“模式”只有在从数据库中检索到数据之后才诞生。如果您的模式是动态的(或根本未知),文档数据库的灵活性将派上用场。
你什么时候遇到“未知模式的数据”?
例如,假设您正在构建一个 IoT 应用程序,用于存储智能家居设备(插头、恒温器、空调等)的状态日志。这是一个不断向许多物联网设备发送状态确认请求的图像。
智能插头有简单的状态信息,ON或OFF,但恒温器有温度和湿度,所以它们拥有的信息是不同的。 2016年生产的空调只有温度、风向和风量等设定信息,但最近的空调配备了耗电量和二氧化碳排放量传感器。当然,API 规范和架构因制造商而异。而且没有人知道未来会出现什么样的新智能设备。
在这种情况下,很难“规范化”模式,对吧?
//
// 各レコードが同じようなものだけど、スキーマが違う
//
[
// スマートプラグ
{
"id": "ac63decb-87c8-4f28-a5a0-64a1afd71ed9",
"type": "smart_device",
"name": "smart_plug",
"power_status": true,
"timestamp": "2022-07-31T12:34:56+00:00"
},
// サーモスタット
{
"id": "d8e7e28a-49d6-4a63-9c13-ca5e2cc2b70d"
"type": "smart_device",
"name": "thermostat",
"temperature_actual": 24.2,
"temperature_setting": 24.5,
"humidity": 0.45,
"timestamp": "2022-07-31T12:34:56+00:00"
},
// エアコン(2016年製)
{
"id": "7810f3ef-cc90-45ab-8954-553066b84b02",
"type": "appliance",
"name": "ac",
"device_id": "d8e7e28a-49d6-4a63-9c13-ca5e2cc2b70d",
"model_name": "ナパソニック2016",
"timestamp": "2022-07-31T12:34:56+00:00"
},
// エアコン(2022年製) << 使用電力量や室温が分かる最新モデル
{
"id": "5580355b-6d14-46a6-abb5-c4ba4f10d0d7",
"type": "appliance",
"name": "ac",
"device_id": "d8e7e28a-49d6-4a63-9c13-ca5e2cc2b70d",
"power_usage_kw": 1.1,
"temperature": 24.3,
"model_name": "ナパソニック2022",
"timestamp": "2022-07-31T12:34:56+00:00"
}
]
Document DB 允许您将以上所有记录存储在一个集合(即表)中。当新的智能设备和家电出现时,不需要CREATE TABLE查询,因此不需要维护工作来维护模式。
如果您使用 RDB,您可能会尝试为每个智能设备或家用电器创建一个表,以实现模式的“规范化”。但是,这会创建很多表,并且由于添加新设备导致架构更改而需要维护,这将是一个沉重的负担。简而言之,在某些情况下,归一化更不利。
使用文档数据库时,应用程序负责检查数据类型,类似于 Python 或 Ruby 等解释型语言。
何时推荐使用 RDB
RDB 在插入记录的同时,会检查数据类型、唯一性、外键记录之间的关系等各种事情。写时模式叫。如果 1. 提前知道数据的结构 2. 期望所有记录都具有相同的结构,我认为 RDB 带来的数据完整性和“模式文档效应”会很有用。。
使用 RDB 时,DB 负责检查数据类型和外键,类似于 Java 或 Go 等编译语言。
3. 可扩展性要求
那里的应用程序必须支持数百万并发用户,执行 10,000+ 并发写入,并在不影响记录检索速度的情况下存储 TB 级数据。
另一方面,有应用支持10个用户,读/写速度“压力不大”,但数据绝不能处于不一致的状态,因为这会危及生命。我有。
选择数据库时,请考虑以下可伸缩性要求:
- 预期的最大并发连接数
- 数据完整性还是可用性更重要?
- 记录检索速度是最重要的问题吗?
推荐使用 Document DB 时
需要同时连接超过 10,000 台主机?无论您的数据有多大,您是否都需要满足记录检索时间 SLA?如果答案是肯定的,文档数据库可能更适合您的需求。
文档数据库一般是向外扩展(水平缩放)。换句话说,您可以通过添加更多数据库主机来提高性能和可用性。 DynamoDB、Firestore 和 MongoDB Atlas 等托管文档数据库可随需求扩展。
一个易于引用的模式作为如何使用文档数据库的示例是一次从多个 Lambda 函数写入数据这才是重点。 Lambda x 文档数据库的组合对于创建批处理和分布式计数器很有用。
如果要将 1,000 个 Lambda 函数中的数据写入 RDB,最少PgBouncer或者RDS 代理您需要使用一个处理大量连接的中间件,称为“连接池”,例如然而,这需要花钱并且增加了维护负担。
另一方面,像 DynamoDB 和 Firestore 这样的托管文档数据库可以处理数千个同时写入,而您无需弄乱任何设置。例如,Firestore 允许多达 100 万个并发连接和每秒 10,000 次写入。有计划在未来取消此限制。
而且正如我在开头提到的,文档数据库一般不支持 JOIN 语句,因此它们通常将数据存储为自包含对象。因此,在很多情况下,只需要检索一条记录,并且无论由于数据的增加导致分片数量增加多少,记录检索时间都不应该有太大变化。
何时推荐 RDB
您的应用程序是否同时连接到大约 3 个 Web 服务器上的数据库?您是否实施了计算客户帐单的逻辑?如果答案是肯定的,RDB 可能适合您。
RDB 最重要的是,优先考虑数据完整性.如果主数据不正确,管理货币计算和预订的系统可能会导致投诉。
将 RDB 用于喜欢临时数据库关闭而不是数据处于不一致状态的应用程序。
正因为如此,RDB 通常比文档 DB 更难扩展并且往往更昂贵。 RDB 通常通过提高机器性能来扩展。这个放大(垂直缩放)。
通过复制数据向外扩展尽管可以这样做,但在维护目标上数据的完整性方面存在开销。还有一种称为“分片”的横向扩展方法,它只将部分表划分到不同的 DB 服务器中,但由于需要遍历网络,因此 JOIN 语句的性能很可能会下降。
但是,在一个只要有钱,一键就可以买到128个vCPU x 4TB内存的超高规格机器的时代,RDB的可扩展性问题是(大部分时间)可以用一团解决我不这么认为。
这个基准测试因此,我能够在 12 核机器上获得接近每秒 30,000 个事务的 PostgreSQL 性能。这个 PostgreSQL 12.1 基准测试我们能够在 GCP 8 核机器上获得接近每秒 4000 个事务的性能。更多参数奥特调我认为您可以通过使用以下工具进行调整来进一步提高性能
4. 你的预算是多少?
你有付费客户吗?您是否将开发应用程序作为一种爱好?
如果您不想花尽可能多的钱(每个人都是......),我认为使用 DynamoDB 或 Firestore 等文档 DB 可以比 RDS 或 Cloud SQL 等托管 RDB 更便宜。
使用 RDS,您必须以每小时 0.101 美元(每月 72 美元)的价格在东京地区租用 2 个 vCPU x 4GB 内存的 PostgreSQL 实例。对于我作为爱好制作的应用程序来说,这有点贵,不是吗?
另一方面,Firestore 每天有 50,000 次读取、20,000 次写入和 20,000 次删除。自由的,存储费约为每 1GB 每月 0.115 美元。 DynamoDB 还以 10 美元的价格提供 1,000,000 次按需读取和 1,000,000 次写入。
如果您真的不想花钱,我推荐使用 DynamoDB 或 Firestore 之类的托管文档数据库。
在最后
到目前为止,我已经介绍了我在选择文档 DB 和 RDB 时认为的“要考虑的要点”。如果你能帮助我,我会很高兴。
你愿意和我一起工作吗
在 ENECHANGE,我们正在计划和开发以分析大量电力时间序列数据为中心的各种应用程序。例如,我正在做这样的事情......
- 开发根据市场电价远程操作家用电器的服务
- 大型家庭/企业用电行业聚类分析及需求预测
- 使用 Airflow 进行数据管道开发
- 将弹性容器服务扩展到 1,000 多个 Fargate 节点
等等。
我们正在寻找一位学习积极性高并希望接受技术挑战的 Python 工程师,因此请随时进行非正式面试。
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308622434.html