其中 HTAP 并不能算一种底层数据模型,但是其行列一体、存储计算分离的设计值得借鉴。参考 db rank:https://db-engines.com/en/ranking
层次数据库 IMS
▐ 层次模型
-
特征
-
树形结构:数据以层次分明的树状结构展现,每个节点有零个或多个子节点,但只有一个父节点(根节点除外)。
-
明确的层次关系:通过节点间的连接明确表达了实体间的上下级或包含关系,适合表达如组织结构、家族谱等自然的层次数据。
-
一对多联系:直接支持并强调一对多的数据关系,便于处理具有明显上下层级的数据。
-
数据表示与操作:数据操作遵循严格的层次顺序,从根节点开始逐层访问,需要记录类型码和顺序域来定位数据。
-
完整性约束:确保数据一致性的规则,如插入记录时需指定双亲、删除双亲时子节点随之删除等。
-
局限性
-
多对多关系处理困难:不直接支持多对多关系,需通过引入冗余节点和结构来间接实现,导致数据冗余和管理复杂。
-
查询效率与灵活性受限:查询操作通常从根节点开始,对于深层次节点的访问效率较低,且不易进行反向查询。
-
数据更新复杂性:插入、删除操作可能影响整个层次结构,特别是删除操作可能导致大量相关数据的变动。
-
物理结构依赖:层次命令要求用户了解底层数据结构,降低了数据抽象级别和应用程序的独立性。
-
数据独立性差:由于紧密依赖于特定的层次结构,当数据结构发生变化时,可能需要对应用程序进行较大调整。
网状数据库 IDS
▐ 网状模型
-
特征
-
灵活性高:能够描述和处理复杂多变的数据关系,包括一对多、多对一及多对多关系。
-
结点多样性:允许节点有多个父节点或无父节点,适应更广泛的数据关联场景。
-
数据表示与操作:采用记录和记录值来表示实体集和实体,支持基本的数据操作如查询、插入、删除和更新,但在操作上比层次模型更为复杂。
-
完整性约束相对宽松:相比层次模型,网状模型在完整性约束上较为灵活,但具体实现时仍会加入必要的约束条件以维护数据一致性。
-
局限性
-
复杂性:网状模型的结构复杂,理解和维护成本较高,对用户不友好。
-
导航式数据访问:数据访问依赖于从一个记录到另一个记录的指针链接,缺乏直接访问数据的简单机制,这使得编写和执行查询变得复杂。
-
设计与实施难度:设计一个有效的网状数据库结构需要深入理解数据间的关系,实施过程中容易出现设计不当,导致数据冗余或一致性问题。
-
数据独立性差:数据结构的改变往往需要应用程序做出相应调整,降低了数据的物理独立性和逻辑独立性。
-
标准化程度低:网状模型倾向于直接反映复杂的数据关系,可能导致数据结构不够规范化,影响数据管理的效率和一致性。
关系数据库 MySQL
▐ 关系模型
-
特征
-
局限性
关系模型的三种约束完整性
1. 实体完整性:确保表中的主键字段不允许有空值,保证了每个实体的唯一可识别性。
2. 参照完整性:维护表间引用的准确性,确保外键值要么为空,要么在被引用表的主键中存在,保持数据间的一致性。
3. 用户定义完整性:根据具体应用需求定义的额外约束条件,如唯一性约束、值的范围限制等,以满足特定业务规则。
▐ MySQL
逻辑架构
-
日志系统
-
事务隔离
-
索引
-
InnoDB 的 B+ 树索引模型:此模型适配磁盘读写特性,减少查询所需的磁盘 I/O。主键索引(聚簇索引)直接存储数据行,而非主键索引(二级索引)存储主键值,并在查询时可能涉及 “回表” 操作,即先查二级索引再查主键索引。主键索引因需维护唯一性约束,在插入性能上有时逊于非主键索引。 -
索引维护与优化:包括页分裂与页合并机制,以及使用自增主键减少页分裂、优化存储空间。索引重建能整理碎片,提升索引紧凑度和查询效率。 -
覆盖索引:指查询所需数据全部包含在索引中,无需额外访问表数据,可显著加速查询过程,是常见的性能调优策略。 -
最左前缀原则:指导联合索引构建,确保索引高效利用,避免冗余索引。MySQL 解析查询时遵循从左到右匹配索引字段,合理安排索引顺序以减少索引数量。 -
索引下推优化(Index Condition Pushdown, ICP):MySQL 5.6 后引入的特性,允许在索引遍历时提前过滤不满足条件的记录,减少不必要的回表查询,进一步提升查询效率。 -
索引失效场景:包括对索引字段进行函数操作、索引字段类型隐式转换不匹配、以及字符集不同的情况,这些都会导致优化器放弃使用索引。此外,InnoDB 中的行锁依赖于索引,非索引条件查询将退化为表锁,可能增加锁竞争,影响并发性能。
-
锁
▐ 列存模型
-
特征
-
局限性
▐ HBase
-
概述
-
HBase 数据模型
-
行键(RowKey):唯一标识每一条记录,决定了数据的存储位置,对查询性能至关重要。 -
列族(Column Family):逻辑上组织列的集合,所有列都属于某个列族,列族是预定义的,且创建表时必须指定。 -
列(Columns):在列族内,列标识符用来区分不同的列,列的数量和内容在不同行间可以灵活变化。 -
时间戳(Timestamp):每条数据记录会自动附带时间戳,用于实现多版控制。
-
HBase 存储结构
-
键值对(KV)存储:底层实现为键值存储,Key 由 RowKey、Column Family、Column Qualifier、Timestamp 组成。 -
HFile:实际存储在 HDFS 上的数据文件格式,高效压缩,适合顺序读取。 -
MemStore & StoreFile:数据先写入内存中的 MemStore,达到阈值后刷写到磁盘上的 StoreFile 中,优化写入效率。 -
Write-Ahead Log (WAL):预写日志,确保数据的持久性和容错性。
-
HBase 架构
HRegionServer 工作原理
Region:表按行键范围被水平切分成多个 Region,分布在不同 RegionServer 上。
Store:每个 Region 根据列族划分 Store,每个 Store 包含 MemStore(内存缓存)和 StoreFile(磁盘存储)。
数据写入流程:数据先写入 MemStore,然后定期合并至 StoreFile,并同步更新到 HLog,确保数据不丢失。
文档数据库 MangoDB
▐ 文档模型
-
特征
-
灵活性与半结构化:文档数据库允许每条记录(文档)有不同的字段和结构,适合存储复杂和不断变化的数据模式。 -
易用性:JSON 文档直接映射到大多数编程语言中的对象,简化了开发过程,提高了开发效率。 -
层级数据模型:支持嵌套和层次化的数据结构,能够自然地表示和查询复杂的关联数据。 -
动态模式:不需要预先定义严格的数据库模式,可以在运行时轻松添加或修改字段。 -
高性能与可扩展性:通过内置的分布式和复制功能,文档数据库能够水平扩展以处理大量数据和高并发访问,同时保证数据的可用性和容错性。
-
局限性
-
事务处理能力:相对于关系数据库,文档数据库在处理涉及多个文档的复杂事务时可能不够强大,虽然一些高级的文档数据库开始支持多文档事务,但这仍然是其相对的局限之一。 -
数据一致性:为了实现高性能和高可用性,文档数据库通常采用最终一致性模型,不适合那些需要强一致性的应用场景。 -
查询复杂性:虽然文档数据库支持丰富的查询功能,但对于高度关联的查询或者需要跨文档进行复杂联接操作的场景,查询设计可能变得复杂且效率低下。 -
过度灵活可能导致混乱:缺乏统一的模式约束会导致数据不一致性和维护困难,特别是随着应用规模的扩大,管理非标准化的数据模型会变得更加复杂。
▐ MongoDB
-
概述
-
索引
-
MongoDB 是非关系型数据库,schema-less 存储,使用 BSON 存放整条数据,使用 B - 树做索引,但查询从结构上要快于 B + 树。 -
MySql 是关系型数据库、数据间的关联性很强,区间访问很常见,为了减少磁盘 IO 提升效率,所以 MySql 使用 B+ 树做索引。
-
MongoDB 架构
-
存储引擎 WiredTiger
-
文档空间分配方式:WiredTiger 使用 BTree 存储,MMAPV1 使用线性存储,需要 Padding; -
并发级别:WiredTiger 支持文档级别锁,MMAPV1 引擎使用表级锁; -
数据压缩:WiredTiger 支持 snappy (默认) 和 zlib,相比 MMAPV1(无压缩))空间节省数倍; -
内存使用:WiredTiger 可以指定内存的使用大小,同时 WiredTiger 使用了二阶缓存 WiredTiger Cache,File System Cache 来保证 Disk 上的数据的最终一致性,而 MMAPv1 只有 journal 日志。
-
Checkpoint 机制
-
Checkpoint 执行流程
-
事务的数据结构
-
MVCC 并发控制机制
-
应用场景与优势
-
敏捷开发与快速迭代:适合需求频繁变化、数据模型不确定的新应用,MongoDB 的 schema-less 特性降低了数据库设计的前期成本。 -
高并发写入:对于需要高写入吞吐量(如大于 2000-3000 QPS)的应用,MongoDB 提供了高效的写操作处理能力。 -
大数据存储与处理:适合处理 TB 乃至 PB 级别的海量数据,且随着数据量的增长,可通过分片轻松扩展。 -
实时分析与内容管理:MongoDB 支持地理位置查询、全文检索等功能,适合构建实时数据分析、内容管理系统等。 -
微服务与云原生应用:MongoDB 的分布式特性与云环境天然契合,易于集成到微服务架构中,支持自动伸缩和高可用部署。
结键值数据库 Redis
▐ 键值对模型
-
特征
-
简洁性:数据模型简单,不涉及复杂的表结构和关系,降低了设计和维护的复杂度。 -
高性能:由于数据结构简单,通常支持高速的读写操作,尤其在内存中实现时性能更为突出。 -
易扩展性:支持水平扩展,能够通过增加更多存储节点来应对数据量的增长和访问量的增加。 -
灵活性:键值对可以存储任意类型的数据,没有固定的模式约束,适应性强。 -
分区和复制:支持数据分区和复制机制,提高系统的可用性和容错能力。
-
局限性
-
缺乏复杂查询能力:键值数据库不支持复杂的查询语句和多表联查,对于需要复杂数据分析和关联操作的应用不太适用。 -
数据一致性问题:虽然一些键值数据库支持事务处理,但相比关系型数据库,一致性保证可能较弱,特别是在分布式环境中。 -
数据模型的局限:键值对模型适合存储松散结构的数据,但对于需要严格结构化数据和复杂关系的应用,可能需要额外的逻辑来维护数据间的关系。 -
过度依赖键的设计:高效的数据访问依赖于良好的键设计,否则可能导致数据分布不均,影响性能。数据管理困难:缺乏强制的模式约束,容易导致数据不一致性和管理混乱,尤其是在团队协作时。
▐ Redis
-
Redis 高速原因
-
基于内存:数据存储在内存中,极大减少了磁盘 I/O 操作的延迟,使得读写操作几乎达到内存访问速度。 -
高效数据结构:内置多种优化过的数据结构,如列表、集合、哈希表等,这些结构专门设计用于快速存取和操作,提高数据处理效率。 -
单线程模型:避免了多线程环境下的上下文切换和锁的开销,简化了编程模型并降低了并发控制的复杂度。(官方原因:CPU 不是性能瓶颈) -
IO 多路复用:利用 epoll 等技术,单线程能高效管理多个网络连接,非阻塞地处理并发请求,减少闲置等待时间。 -
自定义 VM 机制:优化了内存管理和数据处理流程,减少系统调用开销。
-
数据结构
-
底层数据结构
-
缓存相关问题
-
事前预防:均匀过期;分级缓存;热点数据永不过期;Redis 高可用,部署主从架构 + 哨兵或 Redis 集群,确保 Redis 服务稳定。 -
事中控制:互斥锁 / 队列;熔断限流 -
事后恢复:Redis 持久化,确保 Redis 故障后能快速从磁盘恢复数据。
-
互斥锁 / 队列: 控制重建缓存的并发线程。 -
热点数据永不过期: 采用逻辑或物理不过期策略。
-
缓存空值: 将查无结果的 key 以 null 值存入缓存,并设置较短过期时间。 -
布隆过滤器: 前置判断 key 是否存在,减少无效数据库查询。
-
数据过期清除策略
-
noeviction:不淘汰任何数据,写操作导致超出内存时返回错误。 -
volatile-ttl、volatile-random、volatile-lru、volatile-lfu:仅针对设置了过期时间的 key。 -
allkeys-random、allkeys-lru、allkeys-lfu:考虑所有 key。
-
事务
-
持久化机制
-
定义:RDB 是通过创建某一时间点的内存数据快照来实现持久化,生成一个二进制文件(如 dump.rdb),包含数据的序列化表示。 -
触发方式:save 命令:直接在主线程执行,会导致 Redis 阻塞,不建议生产环境使用。bgsave 命令:创建一个子进程进行快照生成,主进程继续处理请求,推荐使用。自动触发:根据配置文件中的规则自动执行 bgsave,例如基于时间间隔和键修改次数。 -
优劣势:优势:简单、恢复速度快、文件紧凑,适合备份和灾难恢复。劣势:数据可能丢失(最后一次快照到故障期间的数据)、fork 操作可能导致内存瞬间翻倍、频繁执行可能影响性能。
-
定义:AOF 通过记录执行的写命令日志来实现持久化,保证每条写操作都被记录,文件为纯文本格式(如 appendonly.aof)。 -
重写机制:当 AOF 文件过大时,通过 bgrewriteaof 命令触发重写,创建一个更精简的日志文件以替代原有文件,保持文件大小可控。 -
同步策略:appendfsync always:每条写命令都同步到磁盘,安全性最高,但性能影响大。appendfsync everysec:默认设置,每秒同步一次,平衡了性能和安全性。appendfsync no:完全依赖操作系统决定何时同步,性能最好但数据最不安全。 -
优劣势:优势:数据丢失最少、日志可读性强、方便手动修复、支持更精细的数据恢复。劣势:文件体积通常比 RDB 大、恢复速度慢、频繁写操作会增加磁盘 I/O 压力。
-
介绍:结合 RDB 和 AOF 的优点,持久化时先生成 RDB 快照,然后在 AOF 日志中仅记录从快照生成后到持久化结束之间的增量操作。 -
优势:利用 RDB 快速恢复和 AOF 的低数据丢失风险,优化了启动时间和数据安全性。
-
主从复制
-
哨兵机制
图数据库 Neo4j
▐ 图模型
-
特点
-
直观的数据模型:图模型以节点(代表实体)、边(代表关系)和属性(附加信息)为基础,直接映射现实世界中的对象及其关系,使得数据结构更加直观易懂。 -
高效的关系查询:由于直接在图中表达实体间的关系,图模型可以快速地进行复杂的路径查询、模式匹配等操作,这些在传统关系型数据库中可能需要多表连接和复杂的 SQL 语句才能完成。 -
支持灵活的数据结构:图数据库对数据结构的约束较少,容易适应不断变化的数据模型,特别适合那些关系复杂且多变的应用场景。 -
强大的遍历能力:强大的图遍历功能能够轻松实现多跳关系的查询,非常适合发现数据中的隐藏关联和模式。
-
局限性
-
资源消耗:与关系型数据库相比,图数据库在存储空间和内存使用上可能更为昂贵,尤其是在处理大量节点和边的密集图时。 -
数值计算和聚合操作:虽然图模型在处理复杂关系数据方面表现出色,但在执行大规模的数值计算、统计分析或聚合操作时可能不如传统关系型数据库或专门的分析工具高效。 -
学习曲线:对于习惯于使用 SQL 的开发者来说,学习图数据库的思维方式可能需要一定时间,尤其是对于复杂的图遍历和模式匹配。 -
事务处理限制:但在某些高级特性(如分布式事务)的支持上可能不如成熟的 SQL 数据库,这可能限制了它在某些金融或银行领域中的应用。 -
数据导入 / 导出:由于图模型的独特性,将现有数据导入图数据库或从图数据库导出数据到其他系统会比关系型数据库更复杂,需要专门的 ETL 工具或自定义脚本。
▐ Neo4j
-
原生图处理
-
原生图存储
-
遍历算法
-
逻辑架构
-
集群架构
时序数据库 InfluxDB
▐ 时序模型
-
特征
-
局限性
▐ InfluxDB
-
存储原理
-
LSM 树
-
TSM 存储引擎改进与机构
HTAP数据库 TiDB
▐ HTAP 模型
-
特征
-
局限性
▐ TiDB
-
计算引擎层
-
存储引擎层
-
分布式协调层
-
数据映射
-
为了保证同一张表的数据放在一起,方便查找,TiDB 会为每个表分配一个 表 ID,用 TableID 表示。表 ID 是一个整数,在整个 集群内唯一。 -
TiDB 会为表中每行数据分配一个 行 ID,用 RowID 表示。行 ID 也是一个整数,在表内唯一。对于行 ID,TiDB 做了一个小优化,如果某个表有整数型的主键,TiDB 会使用主键的值当做这一行数据的行 ID。
Value:[col1, col2, col3, col4]
Value:RowID
Value:null
-
集群架构和数据架构
向量数据库 Milvus
▐ 向量模型
-
特征
-
局限性
-
应用场景
▐ Milvus
-
架构
-
存储模型
-
索引类型
-
距离计算公式
参考文献
本文分享自微信公众号 - 大淘宝技术(AlibabaMTT)。
如有侵权,请联系 [email protected] 删除。
本文参与 “OSC 源创计划”,欢迎正在阅读的你也加入,一起分享。
评论记录:
回复评论: