feat: 整理图片

pull/21/merge
dunwu 2024-01-27 23:29:49 +08:00
parent 6c3031b874
commit a1d04b36e4
45 changed files with 169 additions and 169 deletions

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://dunwu.github.io/db-tutorial/" target="_blank" rel="noopener noreferrer">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/common/dunwu-logo.png" alt="logo" width="150px"/>
<img src="https://raw.githubusercontent.com/dunwu/images/master/common/dunwu-logo.png" alt="logo" width="150px"/>
</a>
</p>
@ -85,7 +85,7 @@
### Mysql
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200716103611.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200716103611.png)
- [Mysql 应用指南](docs/12.数据库/03.关系型数据库/02.Mysql/01.Mysql应用指南.md) ⚡
- [Mysql 工作流](docs/12.数据库/03.关系型数据库/02.Mysql/02.MySQL工作流.md) - 关键词:`连接`、`缓存`、`语法分析`、`优化`、`执行引擎`、`redo log`、`bin log`、`两阶段提交`
@ -128,7 +128,7 @@
### Redis
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200713105627.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200713105627.png)
- [Redis 面试总结](docs/12.数据库/05.KV数据库/01.Redis/01.Redis面试总结.md) 💯
- [Redis 应用指南](docs/12.数据库/05.KV数据库/01.Redis/02.Redis应用指南.md) ⚡ - 关键词:`内存淘汰`、`事件`、`事务`、`管道`、`发布与订阅`

View File

@ -56,7 +56,7 @@ module.exports = {
}
],
sidebarDepth: 2, // 侧边栏显示深度默认1最大2显示到h3标题
logo: 'https://raw.githubusercontent.com/dunwu/images/dev/common/dunwu-logo.png', // 导航栏logo
logo: 'https://raw.githubusercontent.com/dunwu/images/master/common/dunwu-logo.png', // 导航栏logo
repo: 'dunwu/db-tutorial', // 导航栏右侧生成Github链接
searchMaxSuggestions: 10, // 搜索结果显示最大数
lastUpdated: '上次更新', // 更新的时间,及前缀文字 string | boolean (取值为git提交时间)

View File

@ -13,7 +13,7 @@ permalink: /pages/0e1012/
# Nosql 技术选型
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209020702.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209020702.png)
## 一、Nosql 简介
@ -27,7 +27,7 @@ permalink: /pages/0e1012/
随着大数据时代的到来,越来越多的网站、应用系统需要支撑海量数据存储,高并发请求、高可用、高可扩展性等特性要求。传统的关系型数据库在应付这些调整已经显得力不从心,暴露了许多能以克服的问题。由此,各种各样的 NoSQLNot Only SQL数据库作为传统关系型数据的一个有力补充得到迅猛发展。
![nosql-history](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209005228.png)
![nosql-history](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209005228.png)
**NoSQL泛指非关系型的数据库**,可以理解为 SQL 的一个有力补充。
@ -56,7 +56,7 @@ permalink: /pages/0e1012/
将表放入存储系统中有两种方法,而我们绝大部分是采用行存储的。 行存储法是将各行放入连续的物理位置,这很像传统的记录和文件系统。 列存储法是将数据按照列存储到数据库中,与行存储类似,下图是两种存储方法的图形化解释:
![按行存储和按列存储模式](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209005316.png)
![按行存储和按列存储模式](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209005316.png)
### 列式数据库产品
@ -80,13 +80,13 @@ permalink: /pages/0e1012/
列式数据库由于其针对不同列的数据特征而发明的不同算法,使其**往往有比行式数据库高的多的压缩率**,普通的行式数据库一般压缩率在 31 到 51 左右,而列式数据库的压缩率一般在 81 到 301 左右。 比较常见的,通过字典表压缩数据: 下面中才是那张表本来的样子。经过字典表进行数据压缩后,表中的字符串才都变成数字了。正因为每个字符串在字典表里只出现一次了,所以达到了压缩的目的(有点像规范化和非规范化 Normalize 和 Denomalize)
![通过字典表压缩数据](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209005406.png)
![通过字典表压缩数据](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209005406.png)
- **查询效率高**
读取多条数据的同一列效率高,因为这些列都是存储在一起的,一次磁盘操作可以数据的指定列全部读取到内存中。 下图通过一条查询的执行过程说明列式存储(以及数据压缩)的优点
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209005611.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209005611.png)
```
执行步骤如下:
@ -127,19 +127,19 @@ KV 存储非常适合存储**不涉及过多数据关系业务关系的数据**
- Redis
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209010410.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209010410.png)
Redis 是一个使用 ANSI C 编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。从 2015 年 6 月开始Redis 的开发由 Redis Labs 赞助,而 2013 年 5 月至 2015 年 6 月期间,其开发由 Pivotal 赞助。在 2013 年 5 月之前,其开发由 VMware 赞助。根据月度排行网站 DB-Engines.com 的数据显示Redis 是最流行的键值对存储数据库。
- Cassandra
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209010451.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209010451.png)
Apache Cassandra社区内一般简称为 C\*)是一套开源分布式 NoSQL 数据库系统。它最初由 Facebook 开发,用于储存收件箱等简单格式数据,集 Google BigTable 的数据模型与 Amazon Dynamo 的完全分布式架构于一身。Facebook 于 2008 将 Cassandra 开源,此后,由于 Cassandra 良好的可扩展性和性能,被 Apple, Comcast,Instagram, Spotify, eBay, Rackspace, Netflix 等知名网站所采用,成为了一种流行的分布式结构化数据存储方案。
- LevelDB
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209011140.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209011140.png)
LevelDB 是一个由 Google 公司所研发的键值对Key/Value Pair嵌入式数据库管理系统编程库 以开源的 BSD 许可证发布。
@ -176,13 +176,13 @@ KV 存储非常适合存储**不涉及过多数据关系业务关系的数据**
- MongoDB
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209012320.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209012320.png)
**MongoDB**是一种面向文档的数据库管理系统,由 C++ 撰写而成以此来解决应用程序开发社区中的大量现实问题。2007 年 10 月MongoDB 由 10gen 团队所发展。2009 年 2 月首度推出。
- CouchDB
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209012418.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209012418.png)
Apache CouchDB 是一个开源数据库,专注于易用性和成为"**完全拥抱 web 的数据库**"。它是一个使用 JSON 作为存储格式JavaScript 作为查询语言MapReduce 和 HTTP 作为 API 的 NoSQL 数据库。其中一个显著的功能就是多主复制。CouchDB 的第一个版本发布在 2005 年,在 2008 年成为了 Apache 的项目。
@ -234,11 +234,11 @@ MongonDB 还是支持多文档事务的 Consistency(一致性)和 Durability(持
现在有如下文档集合:
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209014530.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209014530.png)
正排索引得到索引如下:
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209014723.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209014723.png)
可见,正排索引适用于根据文档名称查询文档内容
@ -248,7 +248,7 @@ MongonDB 还是支持多文档事务的 Consistency(一致性)和 Durability(持
带有单词频率信息的倒排索引如下:
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209014842.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209014842.png)
可见,倒排索引适用于根据关键词来查询文档内容
@ -262,7 +262,7 @@ MongonDB 还是支持多文档事务的 Consistency(一致性)和 Durability(持
- Solr
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209014947.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209014947.png)
Solr 是 Apache Lucene 项目的开源企业搜索平台。其主要功能包括全文检索、命中标示、分面搜索、动态聚类、数据库集成,以及富文本(如 Word、PDF的处理。Solr 是高度可扩展的,并提供了分布式搜索和索引复制
@ -296,7 +296,7 @@ MongonDB 还是支持多文档事务的 Consistency(一致性)和 Durability(持
## 六、图数据库
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209015751.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209015751.png)
**图形数据库应用图论存储实体之间的关系信息**。最常见例子就是社会网络中人与人之间的关系。关系型数据库用于存储“关系型”数据的效果并不好,其查询复杂、缓慢、超出预期,而图形数据库的独特设计恰恰弥补了这个缺陷,解决关系型数据库存储和处理复杂关系型数据功能较弱的问题。
@ -304,19 +304,19 @@ MongonDB 还是支持多文档事务的 Consistency(一致性)和 Durability(持
- Neo4j
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209015817.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209015817.png)
Neo4j 是由 Neo4jInc。开发的图形数据库管理系统。由其开发人员描述为具有原生图存储和处理的符合 ACID 的事务数据库,根据 DB-Engines 排名, Neo4j 是最流行的图形数据库。
- ArangoDB
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209015858.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209015858.png)
ArangoDB 是由 triAGENS GmbH 开发的原生多模型数据库系统。数据库系统支持三个重要的数据模型(键/值,文档,图形),其中包含一个数据库核心和统一查询语言 AQLArangoDB 查询语言。查询语言是声明性的允许在单个查询中组合不同的数据访问模式。ArangoDB 是一个 NoSQL 数据库系统,但 AQL 在很多方面与 SQL 类似。
- Titan
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200209015923.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200209015923.png)
Titan 是一个可扩展的图形数据库针对存储和查询包含分布在多机群集中的数百亿个顶点和边缘的图形进行了优化。Titan 是一个事务性数据库,可以支持数千个并发用户实时执行复杂的图形遍历。

View File

@ -41,13 +41,13 @@ permalink: /pages/d7cd88/
在有序数组上应用二分查找法如此高效,为什么几乎没有数据库直接使用数组作为索引?这是因为它的限制条件:**数据有序**——为了保证数据有序,每次添加、删除数组数据时,都必须要进行数据调整,来保证其有序,而 **数组的插入/删除操作,时间复杂度为 `O(n)`**。此外,由于数组空间大小固定,每次扩容只能采用复制数组的方式。数组的这些特性,决定了它不适合用于数据频繁变化的应用场景。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220320115836.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20220320115836.png)
**链表用不连续的内存空间来存储数据;并通过一个指针按顺序将这些空间串起来,形成一条链**。
区别于数组链表中的元素不是存储在内存中连续的一片区域链表中的数据存储在每一个称之为「结点」复合区域里在每一个结点除了存储数据以外还保存了到下一个节点的指针Pointer。由于不必按顺序存储**链表的插入/删除操作,时间复杂度为 `O(1)`**,但是,链表只支持顺序访问,其 **查找时间复杂度为 `O(n)`**。其低效的查找方式,决定了链表不适合作为索引。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220320174829.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20220320174829.png)
## 哈希索引
@ -55,7 +55,7 @@ permalink: /pages/d7cd88/
**哈希表** 使用 **哈希函数** 组织数据,以支持快速插入和搜索的数据结构。哈希表的本质是一个数组,其思路是:使用 Hash 函数将 Key 转换为数组下标,利用数组的随机访问特性,使得我们能在 `O(1)` 的时间代价内完成检索。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220320201844.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20220320201844.png)
有两种不同类型的哈希表:**哈希集合** 和 **哈希映射**。
@ -105,7 +105,7 @@ B+ 树索引适用于**全键值查找**、**键值范围查找**和**键前缀
- 第一,所有的关键字(可以理解为数据)都存储在叶子节点,非叶子节点并不存储真正的数据,所有记录节点都是按键值大小顺序存放在同一层叶子节点上。
- 其次,所有的叶子节点由指针连接。如下图为简化了的`B+Tree`。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200304235424.jpg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200304235424.jpg)
根据叶子节点的内容,索引类型分为主键索引和非主键索引。

View File

@ -20,7 +20,7 @@ permalink: /pages/5ed2a2/
ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar计划中这 3 款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如 Java 同构、异构语言、云原生等各种多样化的应用场景。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20201008151613.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20201008151613.png)
#### ShardingSphere-JDBC
@ -30,7 +30,7 @@ ShardingSphere 是一套开源的分布式数据库中间件解决方案组成
- 支持任何第三方的数据库连接池DBCP, C3P0, BoneCP, Druid, HikariCP 等。
- 支持任意实现 JDBC 规范的数据库,目前支持 MySQLOracleSQLServerPostgreSQL 以及任何遵循 SQL92 标准的数据库。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20201008151213.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20201008151213.png)
#### Sharding-Proxy
@ -39,7 +39,7 @@ ShardingSphere 是一套开源的分布式数据库中间件解决方案组成
- 向应用程序完全透明,可直接当做 MySQL/PostgreSQL 使用。
- 适用于任何兼容 MySQL/PostgreSQL 协议的的客户端。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20201008151434.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20201008151434.png)
#### Sharding-SidecarTODO
@ -47,7 +47,7 @@ ShardingSphere 是一套开源的分布式数据库中间件解决方案组成
Database Mesh 的关注重点在于如何将分布式的数据访问应用与数据库有机串联起来,它更加关注的是交互,是将杂乱无章的应用与数据库之间的交互进行有效地梳理。 使用 Database Mesh访问数据库的应用和数据库终将形成一个巨大的网格体系应用和数据库只需在网格体系中对号入座即可它们都是被啮合层所治理的对象。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20201008151557.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20201008151557.png)
| _Sharding-JDBC_ | _Sharding-Proxy_ | _Sharding-Sidecar_ | |
| :-------------- | :--------------- | :----------------- | ------ |
@ -64,7 +64,7 @@ ShardingSphere-JDBC 采用无中心化架构,适用于 Java 开发的高性能
Apache ShardingSphere 是多接入端共同组成的生态圈。 通过混合使用 ShardingSphere-JDBC 和 ShardingSphere-Proxy并采用同一注册中心统一配置分片策略能够灵活的搭建适用于各种场景的应用系统使得架构师更加自由地调整适合与当前业务的最佳系统架构。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20201008151658.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20201008151658.png)
### 功能列表

View File

@ -22,7 +22,7 @@ shardingsphere-jdbc 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供
- 支持任何第三方的数据库连接池DBCP, C3P0, BoneCP, Druid, HikariCP 等。
- 支持任意实现 JDBC 规范的数据库,目前支持 MySQLOracleSQLServerPostgreSQL 以及任何遵循 SQL92 标准的数据库。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20201008151213.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20201008151213.png)
## 快速入门
@ -88,7 +88,7 @@ DataSource dataSource = ShardingSphereDataSourceFactory.createDataSource(dataSou
ShardingSphere 的 3 个产品的数据分片主要流程是完全一致的。 核心由 `SQL 解析 => 执行器优化 => SQL 路由 => SQL 改写 => SQL 执行 => 结果归并`的流程组成。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20201008153551.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20201008153551.png)
- QL 解析:分为词法解析和语法解析。 先通过词法解析器将 SQL 拆分为一个个不可再分的单词。再使用语法解析器对 SQL 进行理解,并最终提炼出解析上下文。 解析上下文包括表、选择项、排序项、分组项、聚合函数、分页信息、查询条件以及可能需要修改的占位符的标记。
- 执行器优化:合并和优化分片条件,如 OR 等。

View File

@ -397,7 +397,7 @@ migrations 最常用的编写形式就是 SQL。
为了被 Flyway 自动识别SQL migrations 的文件命名必须遵循规定的模式:
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/flyway/sql-migrations.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/flyway/sql-migrations.png)
- **Prefix** - `V` 代表 versioned migrations (可配置), `U` 代表 undo migrations (可配置)、 `R` 代表 repeatable migrations (可配置)
- **Version** - 版本号通过`.`(点)或`_`(下划线)分隔 (repeatable migrations 不需要)
@ -416,7 +416,7 @@ migrations 最常用的编写形式就是 SQL。
为了被 Flyway 自动识别JAVA migrations 的文件命名必须遵循规定的模式:
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/flyway/java-migrations.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/flyway/java-migrations.png)
- **Prefix** - `V` 代表 versioned migrations (可配置), `U` 代表 undo migrations (可配置)、 `R` 代表 repeatable migrations (可配置)
- **Version** - 版本号通过`.`(点)或`_`(下划线)分隔 (repeatable migrations 不需要)

View File

@ -86,7 +86,7 @@ permalink: /pages/9bb28f/
对于任意结点,其内部的关键字 Key 是升序排列的。每个节点中都包含了 data。
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/B-TREE.png" />
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/B-TREE.png" />
</div>
对于每个结点,主要包含一个关键字数组 `Key[]`,一个指针数组(指向儿子)`Son[]`。
@ -105,7 +105,7 @@ B+Tree 是 B-Tree 的变种:
- 非叶子节点不存储 data只存储 key叶子节点不存储指针。
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/B+TREE.png" />
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/B+TREE.png" />
</div>
由于并不是所有节点都具有相同的域,因此 B+Tree 中叶节点和内节点一般大小不同。这点与 B-Tree 不同,虽然 B-Tree 中不同节点存放的 key 和指针可能数量不一致,但是每个节点的域和上限是一致的,所以在实现中 B-Tree 往往对每个节点申请同等大小的空间。
@ -115,7 +115,7 @@ B+Tree 是 B-Tree 的变种:
一般在数据库系统或文件系统中使用的 B+Tree 结构都在经典 B+Tree 的基础上进行了优化,增加了顺序访问指针。
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/带有顺序访问指针的B+Tree.png" />
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/带有顺序访问指针的B+Tree.png" />
</div>
在 B+Tree 的每个叶子节点增加一个指向相邻叶子节点的指针,就形成了带有顺序访问指针的 B+Tree。
@ -341,7 +341,7 @@ MVCC 不能解决幻读问题,**Next-Key 锁就是为了解决幻读问题**
> 事务简单来说:**一个 Session 中所进行所有的操作,要么同时成功,要么同时失败**。具体来说,事务指的是满足 ACID 特性的一组操作,可以通过 `Commit` 提交一个事务,也可以使用 `Rollback` 进行回滚。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库事务.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库事务.png)
### ACID
@ -354,7 +354,7 @@ ACID — 数据库事务正确执行的四个基本要素:
**一个支持事务Transaction中的数据库系统必需要具有这四种特性否则在事务过程Transaction processing当中无法保证数据的正确性交易过程极可能达不到交易。**
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库ACID.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库ACID.png)
### 并发一致性问题
@ -364,25 +364,25 @@ ACID — 数据库事务正确执行的四个基本要素:
T<sub>1</sub> 和 T<sub>2</sub> 两个事务都对一个数据进行修改T<sub>1</sub> 先修改T<sub>2</sub> 随后修改T<sub>2</sub> 的修改覆盖了 T<sub>1</sub> 的修改。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库并发一致性-丢失修改.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库并发一致性-丢失修改.png)
- **脏读**
T<sub>1</sub> 修改一个数据T<sub>2</sub> 随后读取这个数据。如果 T<sub>1</sub> 撤销了这次修改,那么 T<sub>2</sub> 读取的数据是脏数据。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库并发一致性-脏数据.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库并发一致性-脏数据.png)
- **不可重复读**
T<sub>2</sub> 读取一个数据T<sub>1</sub> 对该数据做了修改。如果 T<sub>2</sub> 再次读取这个数据,此时读取的结果和第一次读取的结果不同。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库并发一致性-不可重复读.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库并发一致性-不可重复读.png)
- **幻读**
T<sub>1</sub> 读取某个范围的数据T<sub>2</sub> 在这个范围内插入新的数据T<sub>1</sub> 再次读取这个范围的数据,此时读取的结果和和第一次读取的结果不同。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库并发一致性-幻读.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库并发一致性-幻读.png)
并发一致性解决方案:
@ -462,7 +462,7 @@ T<sub>1</sub> 读取某个范围的数据T<sub>2</sub> 在这个范围内插
> **垂直切分**,是 **把一个有很多字段的表给拆分成多个表,或者是多个库上去**。一般来说,会 **将较少的、访问频率较高的字段放到一个表里去**,然后 **将较多的、访问频率较低的字段放到另外一个表里去**。因为数据库是有缓存的,访问频率高的行字段越少,就可以在缓存里缓存更多的行,性能就越好。这个一般在表层面做的较多一些。
![image-20200114211639899](https://raw.githubusercontent.com/dunwu/images/dev/snap/image-20200114211639899.png)
![image-20200114211639899](https://raw.githubusercontent.com/dunwu/images/master/snap/image-20200114211639899.png)
一般来说,满足下面的条件就可以考虑扩容了:
@ -475,7 +475,7 @@ T<sub>1</sub> 读取某个范围的数据T<sub>2</sub> 在这个范围内插
> **水平拆分** 又称为 **Sharding**,它是将同一个表中的记录拆分到多个结构相同的表中。当 **单表数据量太大** 时,会极大影响 **SQL 执行的性能** 。分表是将原来一张表的数据分布到数据库集群的不同节点上,从而缓解单点的压力。
![image-20200114211203589](https://raw.githubusercontent.com/dunwu/images/dev/snap/image-20200114211203589.png)
![image-20200114211203589](https://raw.githubusercontent.com/dunwu/images/master/snap/image-20200114211203589.png)
一般来说,**单表有 200 万条数据** 的时候,性能就会相对差一些了,需要考虑分表了。但是,这也要视具体情况而定,可能是 100 万条,也可能是 500 万条SQL 越复杂,就最好让单表行数越少。
@ -594,7 +594,7 @@ Mysql 支持两种复制:基于行的复制和基于语句的复制。
- **I/O 线程** :负责从主服务器上读取二进制日志文件,并写入从服务器的日志中。
- **SQL 线程** :负责读取日志并执行 SQL 语句以更新数据。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/mysql/master-slave.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/mysql/master-slave.png)
### 读写分离
@ -608,7 +608,7 @@ MySQL 读写分离能提高性能的原因在于:
- 从服务器可以配置 `MyISAM` 引擎,提升查询性能以及节约系统开销;
- 增加冗余,提高可用性。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/mysql/master-slave-proxy.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/mysql/master-slave-proxy.png)
## 数据库优化
@ -880,7 +880,7 @@ SQL 关键字尽量大写Oracle 默认会将 SQL 语句中的关键字
高级别范式的依赖于低级别的范式1NF 是最低级别的范式。
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库范式.png"/>
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库范式.png"/>
</div>
#### 第一范式 (1NF)

View File

@ -18,7 +18,7 @@ permalink: /pages/b71c9e/
>
> 本文语法主要针对 Mysql但大部分的语法对其他关系型数据库也适用。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200115160512.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200115160512.png)
## SQL 简介
@ -227,7 +227,7 @@ SELECT * FROM products LIMIT 2, 3;
- 内部查询首先在其父查询之前执行,以便可以将内部查询的结果传递给外部查询。执行过程可以参考下图:
<p align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/mysql/sql-subqueries.gif" alt="sql-subqueries">
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/mysql/sql-subqueries.gif" alt="sql-subqueries">
</p>
**子查询的子查询**

View File

@ -18,7 +18,7 @@ permalink: /pages/1ae1ca/
>
> 本文语法主要针对 Mysql但大部分的语法对其他关系型数据库也适用。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200115160512.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200115160512.png)
## 连接和组合
@ -33,7 +33,7 @@ permalink: /pages/1ae1ca/
`JOIN` 有两种连接类型:内连接和外连接。
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/mysql/sql-join.png" alt="sql-join">
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/mysql/sql-join.png" alt="sql-join">
</div>
#### 内连接INNER JOIN

View File

@ -194,7 +194,7 @@ Mysql 支持两种复制:基于行的复制和基于语句的复制。
- **SQL 线程** :负责读取中继日志并重放其中的 SQL 语句。
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/mysql/master-slave.png" />
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/mysql/master-slave.png" />
</div>
### 读写分离
@ -210,7 +210,7 @@ MySQL 读写分离能提高性能的原因在于:
- 增加冗余,提高可用性。
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/mysql/master-slave-proxy.png" />
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/mysql/master-slave-proxy.png" />
</div>
## 参考资料

View File

@ -22,7 +22,7 @@ permalink: /pages/8262aa/
**存储引擎层负责数据的存储和提取**。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB它从 MySQL 5.5.5 版本开始成为了默认存储引擎。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200227201908.jpg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200227201908.jpg)
## 查询过程
@ -140,7 +140,7 @@ MySQL 更新过程和 MySQL 查询过程类似,也会将流程走一遍。不
InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB那么这块“粉板”总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200630180342.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200630180342.png)
有了 redo logInnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为**crash-safe**。
@ -172,7 +172,7 @@ binlog 是可以追加写入的,即写到一定大小后会切换到下一个
这里我给出这个 update 语句的执行流程图,图中浅色框表示是在 InnoDB 内部执行的,深色框表示是在执行器中执行的。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200714133806.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200714133806.png)
### 两阶段提交

View File

@ -19,13 +19,13 @@ permalink: /pages/00b04d/
>
> 用户可以根据业务是否需要事务处理(事务处理可以保证数据安全,但会增加系统开销),选择合适的存储引擎。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220721072721.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20220721072721.png)
## 事务简介
> 事务简单来说:**一个 Session 中所进行所有的操作,要么同时成功,要么同时失败**。进一步说,事务指的是满足 ACID 特性的一组操作,可以通过 `Commit` 提交一个事务,也可以使用 `Rollback` 进行回滚。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库事务.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库事务.png)
**事务就是一组原子性的 SQL 语句**。具体来说,事务指的是满足 ACID 特性的一组操作。
@ -37,7 +37,7 @@ permalink: /pages/00b04d/
T<sub>1</sub> 和 T<sub>2</sub> 两个线程都对一个数据进行修改T<sub>1</sub> 先修改T<sub>2</sub> 随后修改T<sub>2</sub> 的修改覆盖了 T<sub>1</sub> 的修改。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库并发一致性-丢失修改.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库并发一致性-丢失修改.png)
## 事务用法
@ -143,7 +143,7 @@ ACID 是数据库事务正确执行的四个基本要素。
- 在并发的情况下,多个事务并行执行,事务不仅要满足原子性,还需要满足隔离性,才能满足一致性。
- 事务满足持久化是为了能应对系统崩溃的情况。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库ACID.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库ACID.png)
> MySQL 默认采用自动提交模式(`AUTO COMMIT`)。也就是说,如果不显式使用 `START TRANSACTION` 语句来开始一个事务,那么每个查询操作都会被当做一个事务并自动提交。
@ -192,7 +192,7 @@ SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
T<sub>1</sub> 修改一个数据T<sub>2</sub> 随后读取这个数据。如果 T<sub>1</sub> 撤销了这次修改,那么 T<sub>2</sub> 读取的数据是脏数据。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库并发一致性-脏数据.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库并发一致性-脏数据.png)
### 读提交
@ -204,7 +204,7 @@ T<sub>1</sub> 修改一个数据T<sub>2</sub> 随后读取这个数据。如
T<sub>2</sub> 读取一个数据T<sub>1</sub> 对该数据做了修改。如果 T<sub>2</sub> 再次读取这个数据,此时读取的结果和第一次读取的结果不同。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库并发一致性-不可重复读.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库并发一致性-不可重复读.png)
### 可重复读
@ -214,7 +214,7 @@ T<sub>2</sub> 读取一个数据T<sub>1</sub> 对该数据做了修改。如
可重复读的问题:事务 T1 读取某个范围内的记录时,事务 T2 在该范围内插入了新的记录T1 再次读取这个范围的数据,此时读取的结果和和第一次读取的结果不同,即为 **幻读Phantom Read**。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/RDB/数据库并发一致性-幻读.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/RDB/数据库并发一致性-幻读.png)
### 串行化
@ -266,17 +266,17 @@ T<sub>2</sub> 读取一个数据T<sub>1</sub> 对该数据做了修改。如
> INSERT INTO `demo`.`order_record`(`order_no`, `status`, `create_date`) VALUES (5, 1, 2019-07-13 10:57:03);
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200630153139.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200630153139.png)
**另一个死锁场景**
InnoDB 存储引擎的主键索引为聚簇索引,其它索引为辅助索引。如果使用辅助索引来更新数据库,就需要使用聚簇索引来更新数据库字段。如果两个更新事务使用了不同的辅助索引,或一个使用了辅助索引,一个使用了聚簇索引,就都有可能导致锁资源的循环等待。由于本身两个事务是互斥,也就构成了以上死锁的四个必要条件了。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200630154606.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200630154606.png)
出现死锁的步骤:
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200630154619.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200630154619.png)
综上可知,在更新操作时,我们应该尽量使用主键来更新表字段,这样可以有效避免一些不必要的死锁发生。
@ -360,7 +360,7 @@ MySQLQueryInterruptedException: Query execution was interrupted
又因为锁的竞争是不公平的,当多个事务同时对一条记录进行更新时,极端情况下,一个更新操作进去排队系统后,可能会一直拿不到锁,最后因超时被系统打断踢出。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200630112600.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200630112600.png)
如上图中的操作,虽然都是在一个事务中,但锁的申请在不同时间,只有当其他操作都执行完,才会释放所有锁。因为扣除库存是更新操作,属于行锁,这将会影响到其他操作该数据的事务,所以我们应该尽量避免长时间地持有该锁,尽快释放该锁。又因为先新建订单和先扣除库存都不会影响业务,所以我们可以将扣除库存操作放到最后,也就是使用执行顺序 1以此尽量减小锁的持有时间。

View File

@ -15,7 +15,7 @@ permalink: /pages/f1f151/
# Mysql 锁
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200716064947.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200716064947.png)
## 悲观锁和乐观锁
@ -137,7 +137,7 @@ UPDATE t SET x="c" WHERE id=1;
MVCC 维护了一个一致性读视图 `consistent read view` ,主要包含了当前系统**未提交的事务列表** `TRX_IDs {TRX_ID_1, TRX_ID_2, ...}`,还有该列表的最小值 `TRX_ID_MIN``TRX_ID_MAX`
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200715135809.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200715135809.png)
这样,对于当前事务的启动瞬间来说,一个数据版本的 row trx_id有以下几种可能

View File

@ -19,7 +19,7 @@ permalink: /pages/fcb19c/
>
> 接下来将向你展示一系列创建高性能索引的策略,以及每条策略其背后的工作原理。但在此之前,先了解与索引相关的一些算法和数据结构,将有助于更好的理解后文的内容。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200715172009.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200715172009.png)
## 索引简介
@ -85,7 +85,7 @@ B 树是最常见的索引,按照顺序存储数据,所以 Mysql 可以用
**哈希表** 使用 **哈希函数** 组织数据,以支持快速插入和搜索的数据结构。哈希表的本质是一个数组,其思路是:使用 Hash 函数将 Key 转换为数组下标,利用数组的随机访问特性,使得我们能在 `O(1)` 的时间代价内完成检索。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220320201844.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20220320201844.png)
有两种不同类型的哈希表:**哈希集合** 和 **哈希映射**。
@ -137,7 +137,7 @@ B+ 树索引适用于**全键值查找**、**键值范围查找**和**键前缀
- 第一,所有的关键字(可以理解为数据)都存储在叶子节点,非叶子节点并不存储真正的数据,所有记录节点都是按键值大小顺序存放在同一层叶子节点上。
- 其次,所有的叶子节点由指针连接。如下图为简化了的`B+Tree`。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200304235424.jpg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200304235424.jpg)
根据叶子节点的内容,索引类型分为主键索引和非主键索引。

View File

@ -232,7 +232,7 @@ mysql>
连接完成后,如果你没有后续的动作,这个连接就处于空闲状态,你可以在 `show processlist` 命令中看到它。客户端如果太长时间没动静,连接器就会自动将它断开。这个时间是由参数 `wait_timeout` 控制的,默认值是 8 小时。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200714115031.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200714115031.png)
### 创建用户

View File

@ -15,7 +15,7 @@ hidden: true
# Mysql 教程
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200716103611.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200716103611.png)
## 📖 内容
@ -27,19 +27,19 @@ hidden: true
> 关键词:`ACID`、`AUTOCOMMIT`、`事务隔离级别`、`死锁`、`分布式事务`
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220721072721.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20220721072721.png)
### [Mysql 锁](04.Mysql锁.md)
> 关键词:`乐观锁`、`表级锁`、`行级锁`、`意向锁`、`MVCC`、`Next-key 锁`
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200716064947.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200716064947.png)
### [Mysql 索引](05.Mysql索引.md)
> 关键词:`Hash`、`B 树`、`聚簇索引`、`回表`
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200715172009.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200715172009.png)
### [Mysql 性能优化](06.Mysql性能优化.md)

View File

@ -18,7 +18,7 @@ permalink: /pages/52609d/
>
> 关键词Database, RDBM, psql
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20180920181010182614.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20180920181010182614.png)
## 安装
@ -28,7 +28,7 @@ permalink: /pages/52609d/
官方下载页面要求用户选择相应版本,然后动态的给出安装提示,如下图所示:
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20180920181010174348.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20180920181010174348.png)
前 3 步要求用户选择,后 4 步是根据选择动态提示的安装步骤

View File

@ -28,11 +28,11 @@ H2 允许用户通过浏览器接口方式访问 SQL 数据库。
2. 启动方式:在 bin 目录下,双击 jar 包;执行 `java -jar h2*.jar`;执行脚本:`h2.bat` 或 `h2.sh`
3. 在浏览器中访问:`http://localhost:8082`,应该可以看到下图中的页面:
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/h2/h2-console.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/h2/h2-console.png)
点击 **Connect** ,可以进入操作界面:
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/h2/h2-console-02.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/h2/h2-console-02.png)
操作界面十分简单,不一一细说。

View File

@ -25,7 +25,7 @@ hidden: true
### Mysql
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200716103611.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200716103611.png)
- [Mysql 应用指南](02.Mysql/01.Mysql应用指南.md) ⚡
- [Mysql 工作流](02.Mysql/02.MySQL工作流.md) - 关键词:`连接`、`缓存`、`语法分析`、`优化`、`执行引擎`、`redo log`、`bin log`、`两阶段提交`

View File

@ -27,7 +27,7 @@ MongoDB 提供以下操作向一个 collection 插入 document
> 注:以上操作都是原子操作。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200924112342.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200924112342.svg)
插入操作的特性:
@ -76,7 +76,7 @@ db.inventory.insertMany([
MongoDB 提供 [`db.collection.find()`](https://docs.mongodb.com/manual/reference/method/db.collection.find/#db.collection.find) 方法来检索 document。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200924113832.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200924113832.svg)
### Update 操作
@ -92,7 +92,7 @@ MongoDB 提供以下操作来更新 collection 中的 document
- [`db.collection.updateMany(<filter>, <update>, <options>)`](https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/#db.collection.updateMany)
- [`db.collection.replaceOne(<filter>, <update>, <options>)`](https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/#db.collection.replaceOne)
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200924114043.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200924114043.svg)
【示例】插入测试数据
@ -201,7 +201,7 @@ MongoDB 提供以下操作来删除 collection 中的 document
- [`db.collection.deleteOne()`](https://docs.mongodb.com/manual/reference/method/db.collection.deleteOne/#db.collection.deleteOne):删除一条 document
- [`db.collection.deleteMany()`](https://docs.mongodb.com/manual/reference/method/db.collection.deleteMany/#db.collection.deleteMany):删除多条 document
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200924120007.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200924120007.svg)
删除操作的特性:

View File

@ -29,7 +29,7 @@ MongoDB Pipeline 由多个阶段([stages](https://docs.mongodb.com/manual/refe
同一个阶段可以在 pipeline 中出现多次,但 [`$out`](https://docs.mongodb.com/manual/reference/operator/aggregation/out/#pipe._S_out)、[`$merge`](https://docs.mongodb.com/manual/reference/operator/aggregation/merge/#pipe._S_merge),和 [`$geoNear`](https://docs.mongodb.com/manual/reference/operator/aggregation/geoNear/#pipe._S_geoNear) 阶段除外。所有可用 pipeline 阶段可以参考:[Aggregation Pipeline Stages](https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/#aggregation-pipeline-operator-reference)。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200921092725.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200921092725.png)
- 第一阶段:[`$match`](https://docs.mongodb.com/manual/reference/operator/aggregation/match/#pipe._S_match) 阶段按状态字段过滤 document然后将状态等于“ A”的那些 document 传递到下一阶段。
- 第二阶段:[`$group`](https://docs.mongodb.com/manual/reference/operator/aggregation/group/#pipe._S_group) 阶段按 cust_id 字段对 document 进行分组,以计算每个唯一 cust_id 的金额总和。
@ -239,7 +239,7 @@ Pipeline 的内存限制为 100 MB。
Map-reduce 是一种数据处理范式,用于将大量数据汇总为有用的聚合结果。为了执行 map-reduce 操作MongoDB 提供了 [`mapReduce`](https://docs.mongodb.com/manual/reference/command/mapReduce/#dbcmd.mapReduce) 数据库命令。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200921155546.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200921155546.svg)
在上面的操作中MongoDB 将 map 阶段应用于每个输入 document即 collection 中与查询条件匹配的 document。 map 函数分发出多个键-值对。对于具有多个值的那些键MongoDB 应用 reduce 阶段该阶段收集并汇总聚合的数据。然后MongoDB 将结果存储在 collection 中。可选地reduce 函数的输出可以通过 finalize 函数来进一步汇总聚合结果。
@ -255,7 +255,7 @@ MongoDB 支持一下单一目的的聚合操作:
所有这些操作都汇总了单个 collection 中的 document。尽管这些操作提供了对常见聚合过程的简单访问但是它们相比聚合 pipeline 和 map-reduce缺少灵活性和丰富的功能性。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200921155935.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200921155935.svg)
## SQL 和 MongoDB 聚合对比
@ -386,7 +386,7 @@ db.orders.insertMany([
SQL 和 MongoDB 聚合方式对比:
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200921200556.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200921200556.png)
## 参考资料

View File

@ -120,7 +120,7 @@ This looks very different from the tabular data structure you started with in St
嵌入式 document 通过将相关数据存储在单个 document 结构中来捕获数据之间的关系。 MongoDB document 可以将 document 结构嵌入到另一个 document 中的字段或数组中。这些非规范化的数据模型允许应用程序在单个数据库操作中检索和操纵相关数据。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200910193231.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200910193231.png)
对于 MongoDB 中的很多场景,非规范化数据模型都是最佳的。
@ -132,7 +132,7 @@ This looks very different from the tabular data structure you started with in St
引用通过包含从一个 document 到另一个 document 的链接或引用来存储数据之间的关系。 应用程序可以解析这些引用以访问相关数据。 广义上讲,这些是规范化的数据模型。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200910193234.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200910193234.png)
通常,在以下场景使用引用式的数据模型:

View File

@ -370,7 +370,7 @@ review collection 存储所有的评论
## 树形结构模型
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200911194846.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200911194846.svg)
### 具有父节点的树形结构模型
@ -524,7 +524,7 @@ db.categories.insertMany([
### 具有嵌套集的树形结构模型
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200911204252.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200911204252.svg)
```javascript
db.categories.insertMany([
@ -553,7 +553,7 @@ db.categories.find({
解决方案是:列转行
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200919225901.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200919225901.png)
### 管理文档不同版本

View File

@ -27,7 +27,7 @@ permalink: /pages/10c674/
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200921210621.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200921210621.svg)
### createIndex() 方法

View File

@ -27,15 +27,15 @@ MongoDB 中的副本集是一组维护相同数据集的 mongod 进程。一个
**主节点负责接收所有写操作**。副本集只能有一个主副本,能够以 [`{ w: "majority" }`](https://docs.mongodb.com/manual/reference/write-concern/#writeconcern."majority") 来确认集群中节点的写操作成功情况;尽管在某些情况下,另一个 MongoDB 实例可能会暂时认为自己也是主要的。主节点在其操作日志(即 [oplog](https://docs.mongodb.com/manual/core/replica-set-oplog/))中记录了对其数据集的所有更改。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920165054.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920165054.svg)
**从节点复制主节点的操作日志,并将操作应用于其数据集**,以便同步主节点的数据。如果主节点不可用,则符合条件的从节点将选举新的主节点。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920165055.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920165055.svg)
在某些情况下(例如,有一个主节点和一个从节点,但由于成本限制,禁止添加另一个从节点),您可以选择将 mongod 实例作为仲裁节点添加到副本集。仲裁节点参加选举但不保存数据(即不提供数据冗余)。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920165053.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920165053.svg)
仲裁节点将永远是仲裁节点。在选举期间,主节点可能会降级成为次节点,而次节点可能会升级成为主节点。
@ -61,7 +61,7 @@ MongoDB 中的副本集是一组维护相同数据集的 mongod 进程。一个
当主节点与集群中的其他成员通信的时间超过配置的 `electionTimeoutMillis`(默认为 10 秒)时,符合选举要求的从节点将要求选举,并提名自己为新的主节点。集群尝试完成选举新主节点并恢复正常工作。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920175429.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920175429.svg)
选举完成前,副本集无法处理写入操作。如果将副本集配置为:在主节点处于脱机状态时,在次节点上运行,则副本集可以继续提供读取查询。
@ -79,7 +79,7 @@ MongoDB 中的副本集是一组维护相同数据集的 mongod 进程。一个
默认情况下,客户端从主节点读取数据;但是,客户端可以指定读取首选项,以将读取操作发送到从节点。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920204024.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920204024.svg)
异步复制到从节点意味着向从节点读取数据可能会返回与主节点不一致的数据。

View File

@ -37,7 +37,7 @@ MongoDB 分片集群含以下组件:
- [mongos](https://docs.mongodb.com/manual/core/sharded-cluster-query-router/)mongos 充当查询路由器,在客户端应用程序和分片集群之间提供接口。从 MongoDB 4.4 开始mongos 可以支持 [hedged reads](https://docs.mongodb.com/manual/core/sharded-cluster-query-router/#mongos-hedged-reads) 以最大程度地减少延迟。
- [config servers](https://docs.mongodb.com/manual/core/sharded-cluster-config-servers/):提供集群元数据存储和分片数据分布的映射。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920210057.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920210057.svg)
### 分片集群的分布
@ -49,7 +49,7 @@ MongoDB 数据库可以同时包含分片和未分片的集合的 collection。
分片和未分片的 collection
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920212159.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920212159.svg)
### 路由节点 mongos
@ -57,7 +57,7 @@ MongoDB 数据库可以同时包含分片和未分片的集合的 collection。
连接 [`mongos`](https://docs.mongodb.com/manual/reference/program/mongos/#bin.mongos) 的方式和连接 [`mongod`](https://docs.mongodb.com/manual/reference/program/mongod/#bin.mongod) 相同,例如通过 [`mongo`](https://docs.mongodb.com/manual/reference/program/mongo/#bin.mongo) shell 或 [MongoDB 驱动程序](https://docs.mongodb.com/drivers/?jump=docs)。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920212157.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920212157.svg)
路由节点的作用:
@ -104,7 +104,7 @@ Hash 分片策略会先计算分片 Key 字段值的哈希值;然后,根据
> 注意使用哈希索引解析查询时MongoDB 会自动计算哈希值,应用程序不需要计算哈希。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920213343.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920213343.svg)
尽管分片 Key 范围可能是“接近”的,但它们的哈希值不太可能在同一 [chunk](https://docs.mongodb.com/manual/reference/glossary/#term-chunk) 上。基于 Hash 的数据分发有助于更均匀的数据分布,尤其是在分片 Key 单调更改的数据集中。
@ -114,7 +114,7 @@ Hash 分片策略会先计算分片 Key 字段值的哈希值;然后,根据
范围分片根据分片 Key 值将数据划分为多个范围。然后,根据分片 Key 值为每个 [chunk](https://docs.mongodb.com/manual/reference/glossary/#term-chunk) 分配一个范围。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920213345.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920213345.svg)
值比较近似的一系列分片 Key 更有可能驻留在同一 [chunk](https://docs.mongodb.com/manual/reference/glossary/#term-chunk) 上。范围分片的效率取决于选择的分片 Key。分片 Key 考虑不周全会导致数据分布不均,这可能会削弱分片的某些优势或导致性能瓶颈。
@ -126,7 +126,7 @@ Hash 分片策略会先计算分片 Key 字段值的哈希值;然后,根据
每个区域覆盖一个或多个分片 Key 值范围。区域覆盖的每个范围始终包括其上下边界。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200920214854.svg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200920214854.svg)
在定义要覆盖的区域的新范围时,必须使用分片 Key 中包含的字段。如果使用复合分片 Key则范围必须包含分片 Key 的前缀。

View File

@ -253,7 +253,7 @@ Redis 集群基于复制特性实现节点间的数据一致性。
由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200131135847.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200131135847.png)
## Redis vs. Memcached

View File

@ -184,7 +184,7 @@ Redis 基于 Reactor 模式开发了自己的网络时间处理器。
文件事件处理器有四个组成部分套接字、I/O 多路复用程序、文件事件分派器、事件处理器。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200130172525.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200130172525.png)
### 时间事件
@ -246,7 +246,7 @@ def main():
从事件处理的角度来看,服务器运行流程如下:
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-event.png" />
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-event.png" />
</div>
## 六、Redis 事务

View File

@ -21,7 +21,7 @@ permalink: /pages/ed757c/
## 一、Redis 基本数据类型
![Redis 数据类型](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200226113813.png)
![Redis 数据类型](https://raw.githubusercontent.com/dunwu/images/master/snap/20200226113813.png)
| 数据类型 | 可以存储的值 | 操作 |
| -------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------- |
@ -36,7 +36,7 @@ permalink: /pages/ed757c/
### STRING
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-datatype-string.png" width="400"/>
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-datatype-string.png" width="400"/>
</div>
**适用场景:缓存、计数器、共享 Session**
@ -68,7 +68,7 @@ OK
### HASH
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-datatype-hash.png" width="400"/>
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-datatype-hash.png" width="400"/>
</div>
**适用场景:存储结构化数据**,如一个对象:用户信息、产品信息等。
@ -113,7 +113,7 @@ OK
### LIST
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-datatype-list.png" width="400"/>
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-datatype-list.png" width="400"/>
</div>
**适用场景:用于存储列表型数据**。如:粉丝列表、商品列表等。
@ -157,7 +157,7 @@ OK
### SET
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-datatype-set.png" width="400"/>
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-datatype-set.png" width="400"/>
</div>
**适用场景:用于存储去重的列表型数据**。
@ -203,7 +203,7 @@ OK
### ZSET
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-datatype-zset.png" width="400"/>
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-datatype-zset.png" width="400"/>
</div>
适用场景:由于可以设置 score且不重复。**适合用于存储各种排行数据**,如:按评分排序的有序商品集合、按时间排序的有序文章集合。
@ -432,7 +432,7 @@ redis> PFCOUNT databases # 估计数量增一
使用 `HASH` 类型存储文章信息。其中key 是文章 IDfield 是文章的属性 keyvalue 是属性对应值。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200225143038.jpg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200225143038.jpg)
操作:
@ -444,7 +444,7 @@ redis> PFCOUNT databases # 估计数量增一
使用 `ZSET` 类型分别存储按照时间排序和按照评分排序的文章 ID 集合。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200225145742.jpg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200225145742.jpg)
操作:
@ -454,7 +454,7 @@ redis> PFCOUNT databases # 估计数量增一
3为了防止重复投票使用 `SET` 类型记录每篇文章 ID 对应的投票集合。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200225150105.jpg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200225150105.jpg)
操作:
@ -463,7 +463,7 @@ redis> PFCOUNT databases # 估计数量增一
4假设 user:115423 给 article:100408 投票,分别需要高更新评分排序集合以及投票集合。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200225150138.jpg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200225150138.jpg)
当需要对一篇文章投票时,程序需要用 ZSCORE 命令检查记录文章发布时间的有序集合,判断文章的发布时间是否超过投票有效期(比如:一星期)。
@ -579,7 +579,7 @@ redis> PFCOUNT databases # 估计数量增一
取出群组里的文章:
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200225214210.jpg)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200225214210.jpg)
- 通过对存储群组文章的集合和存储文章评分的有序集合执行 `ZINTERSTORE` 命令,可以得到按照文章评分排序的群组文章。
- 通过对存储群组文章的集合和存储文章发布时间的有序集合执行 `ZINTERSTORE` 命令,可以得到按照文章发布时间排序的群组文章。

View File

@ -90,7 +90,7 @@ RDB 文件是一个经过压缩的二进制文件,由多个部分组成。
对于不同类型STRING、HASH、LIST、SET、SORTED SET的键值对RDB 文件会使用不同的方式来保存它们。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-rdb-structure.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-rdb-structure.png)
Redis 本身提供了一个 RDB 文件检查工具 redis-check-dump。
@ -170,7 +170,7 @@ AOF 载入过程如下:
6. 载入完毕。
<div align="center">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-aof-flow.png" />
<img src="https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-aof-flow.png" />
</div>
### AOF 的重写
@ -192,7 +192,7 @@ AOF 重写并非读取和分析现有 AOF 文件的内容,而是直接从数
- 由于彼此不是在同一个进程中工作AOF 重写不影响 AOF 写入和同步。当子进程完成创建新 AOF 文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾,使得新旧两个 AOF 文件所保存的数据库状态一致。
- 最后,服务器用新的 AOF 文件替换就的 AOF 文件,以此来完成 AOF 重写操作。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200130153716.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200130153716.png)
可以通过设置 `auto-aof-rewrite-percentage``auto-aof-rewrite-min-size`,使得 Redis 在满足条件时,自动执行 `BGREWRITEAOF`
@ -284,7 +284,7 @@ Redis 的容灾备份基本上就是对数据进行备份,并将这些备份
## 五、要点总结
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200224214047.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200224214047.png)
## 参考资料

View File

@ -19,7 +19,7 @@ permalink: /pages/379cd8/
>
> Redis 2.8 以前的复制不能高效处理断线后重复制的情况,而 Redis 2.8 新添的部分重同步可以解决这个问题。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200712182603.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200712182603.png)
## 一、复制简介
@ -56,7 +56,7 @@ Redis 的复制功能分为同步sync和命令传播command propagate
3. 主服务器执行 `BGSAVE` 完毕后,主服务器会将生成的 RDB 文件发送给从服务器。从服务器接收并载入 RDB 文件,更新自己的数据库状态。
4. 主服务器将记录在缓冲区中的所有写命令发送给从服务器,从服务器执行这些写命令,更新自己的数据库状态。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200224220353.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200224220353.png)
### 命令传播
@ -101,7 +101,7 @@ Redis 的复制功能分为同步sync和命令传播command propagate
- 如果主从服务器的复制偏移量相同,则说明二者的数据库状态一致;
- 反之,则说明二者的数据库状态不一致。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-replication-offset.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-replication-offset.png)
#### 复制积压缓冲区
@ -148,7 +148,7 @@ Redis 的复制功能分为同步sync和命令传播command propagate
- 假如主从服务器的 **master run id 相同**,并且**指定的偏移量offset在内存缓冲区中还有效**,复制就会从上次中断的点开始继续。
- 如果其中一个条件不满足,就会进行完全重新同步(在 2.8 版本之前就是直接进行完全重新同步)。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-psync-workflow.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-psync-workflow.png)
## 四、心跳检测

View File

@ -19,13 +19,13 @@ permalink: /pages/615afe/
>
> Redis 哨兵是 [Raft 算法](https://dunwu.github.io/blog/pages/4907dc/) 的具体实现。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200713072747.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200713072747.png)
## 一、哨兵简介
Redis 哨兵Sentinel是 Redis 的**高可用性**Hight Availability解决方案由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200131135847.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200131135847.png)
Sentinel 的主要功能如下:
@ -85,7 +85,7 @@ Sentinel 模式下 Redis 服务器只支持 `PING`、`SENTINEL`、`INFO`、`SUBS
对于每个与 Sentinel 连接的服务器Sentinel 既会向服务器的 `__sentinel__:hello` 频道发送消息,也会订阅服务器的 `__sentinel__:hello` 频道的消息。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200131153842.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200131153842.png)
### 向服务器发送消息

View File

@ -23,7 +23,7 @@ permalink: /pages/77dfbe/
> - Redis 集群采用主从模型,提供复制和故障转移功能,来保证 Redis 集群的高可用。
> - 根据 CAP 理论Consistency、Availability、Partition tolerance 三者不可兼得,而 Redis 集群的选择是 AP。Redis 集群节点间采用异步通信方式,不保证强一致性,尽力达到最终一致性。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200713100613.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200713100613.png)
## 1. Redis Cluster 分区
@ -99,7 +99,7 @@ Redis 集群的重新分区操作由 Redis 集群管理软件 **redis-trib** 负
重新分区的实现原理如下图所示:
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-cluster-trib.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-cluster-trib.png)
### 1.5. ASK 错误
@ -107,7 +107,7 @@ Redis 集群的重新分区操作由 Redis 集群管理软件 **redis-trib** 负
判断 ASK 错误的过程如下图所示:
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/database/redis/redis-ask.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/database/redis/redis-ask.png)
## 2. Redis Cluster 故障转移

View File

@ -619,11 +619,11 @@ rebalance表明让 Redis 自动根据节点数进行均衡哈希槽分配。
--cluster-use-empty-masters表明
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200712125827.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200712125827.png)
执行结束后,查看状态:
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200712130234.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200712130234.png)
## 四、Redis 命令

View File

@ -29,25 +29,25 @@ hidden: true
> 关键词:`内存淘汰`、`事件`、`事务`、`管道`、`发布与订阅`
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200713105627.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200713105627.png)
### [Redis 数据类型和应用](03.Redis数据类型和应用.md)
> 关键词:`STRING`、`HASH`、`LIST`、`SET`、`ZSET`、`BitMap`、`HyperLogLog`、`Geo`
![Redis 数据类型](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200226113813.png)
![Redis 数据类型](https://raw.githubusercontent.com/dunwu/images/master/snap/20200226113813.png)
### [Redis 持久化](04.Redis持久化.md)
> 关键词:`RDB`、`AOF`、`SAVE`、`BGSAVE`、`appendfsync`
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200224214047.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200224214047.png)
### [Redis 复制](05.Redis复制.md)
> 关键词:`SLAVEOF`、`SYNC`、`PSYNC`、`REPLCONF ACK`
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200712182603.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200712182603.png)
### [Redis 哨兵](06.Redis哨兵.md)
@ -57,13 +57,13 @@ hidden: true
>
> 关键词:`Sentinel`、`PING`、`INFO`、`Raft`
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200713072747.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200713072747.png)
### [Redis 集群](07.Redis集群.md)
> 关键词:`CLUSTER MEET`、`Hash slot`、`MOVED`、`ASK`、`SLAVEOF no one`、`redis-trib`
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200713100613.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200713100613.png)
### [Redis 实战](08.Redis实战.md)

View File

@ -37,7 +37,7 @@ Hadoop 的缺陷在于:它只能执行批处理,并且只能以顺序方式
HBase 是一种类似于 `Googles Big Table` 的数据模型,它是 Hadoop 生态系统的一部分,它将数据存储在 HDFS 上,客户端可以通过 HBase 实现对 HDFS 上数据的随机访问。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200601170449.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200601170449.png)
HBase 的**核心特性**如下:
@ -102,7 +102,7 @@ HBase 的典型应用场景
- Cell单元格是行、列族和列限定符的组合包含一个值和一个时间戳代表值的版本。
- Timestamp时间戳写在每个值旁边是给定版本值的标识符。 默认情况下,时间戳表示写入数据时 RegionServer 上的时间,但您可以在将数据放入单元格时指定不同的时间戳值。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/bigdata/hbase/1551164224778.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/bigdata/hbase/1551164224778.png)
### 特性比较

View File

@ -40,7 +40,7 @@ HBase 是一个面向 `列` 的数据库管理系统,这里更为确切的而
-
- **`Timestamp`**`Cell` 的版本通过时间戳来索引,时间戳的类型是 64 位整型,时间戳可以由 HBase 在数据写入时自动赋值,也可以由客户显式指定。每个 `Cell` 中,不同版本的数据按照时间戳倒序排列,即最新的数据排在最前面。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/bigdata/hbase/1551164224778.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/bigdata/hbase/1551164224778.png)
## HBase 物理存储结构
@ -54,7 +54,7 @@ HBase 自动将表水平划分成区域Region。每个 Region 由表中 Ro
- 该表具有两个列族,分别是 personal 和 office;
- 其中列族 personal 拥有 name、city、phone 三个列,列族 office 拥有 tel、addres 两个列。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200601172926.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200601172926.png)
> _图片引用自 : HBase 是列式存储数据库吗_ *https://www.iteblog.com/archives/2498.html*

View File

@ -21,7 +21,7 @@ permalink: /pages/62f8d9/
### 概览
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200612151239.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200612151239.png)
HBase 主要处理两种文件预写日志WAL和实际数据文件 HFile。一个基本的流程是客户端首先联系 ZooKeeper 集群查找行键。上述过程是通过 ZooKeeper 获取欧含有 `-ROOT-` 的 region 服务器来完成的。通过含有 `-ROOT-` 的 region 服务器可以查询到含有 `.META.` 表中对应的 region 服务器名,其中包含请求的行键信息。这两种内容都会被缓存下来,并且只查询一次。最终,通过查询 .META. 服务器来获取客户端查询的行键数据所在 region 的服务器名。
@ -29,13 +29,13 @@ HBase 主要处理两种文件预写日志WAL和实际数据文件 HFil
HBase Table 中的所有行按照 `Row Key` 的字典序排列。HBase Table 根据 Row Key 的范围分片,每个分片叫做 `Region`。一个 `Region` 包含了在 start key 和 end key 之间的所有行。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/bigdata/hbase/1551165887616.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/bigdata/hbase/1551165887616.png)
**HBase 支持自动分区**:每个表初始只有一个 `Region`,随着数据不断增加,`Region` 会不断增大,当增大到一个阀值的时候,`Region` 就会分裂为两个新的 `Region`。当 Table 中的行不断增多,就会有越来越多的 `Region`
`Region` 是 HBase 中**分布式存储和负载均衡的最小单元**。这意味着不同的 `Region` 可以分布在不同的 `Region Server` 上。但一个 `Region` 是不会拆分到多个 Server 上的。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200601181219.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200601181219.png)
### Region Server
@ -54,13 +54,13 @@ HBase Table 中的所有行按照 `Row Key` 的字典序排列。HBase Table 根
- Flush 发生时,创建 HFile Writer第一个空的 Data Block 出现,初始化后的 Data Block 中为 Header 部分预留了空间Header 部分用来存放一个 Data Block 的元数据信息。
- 而后,位于 MemStore 中的 KeyValues 被一个个 append 到位于内存中的第一个 Data Block 中:
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/bigdata/hbase/1551166602999.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/bigdata/hbase/1551166602999.png)
Region Server 存取一个子表时,会创建一个 Region 对象,然后对表的每个列族创建一个 `Store` 实例,每个 `Store` 会有 0 个或多个 `StoreFile` 与之对应,每个 `StoreFile` 则对应一个 `HFile`HFile 就是实际存储在 HDFS 上的文件。
## HBase 系统架构
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/bigdata/hbase/1551164744748.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/bigdata/hbase/1551164744748.png)
和 HDFS、YARN 一样,**HBase 也遵循 master / slave 架构**
@ -80,14 +80,14 @@ Region Server 存取一个子表时,会创建一个 Region 对象,然后对
- GFS 上的垃圾文件回收;
- 处理 Schema 的更新请求。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/bigdata/hbase/1551166513572.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/bigdata/hbase/1551166513572.png)
### Region Server
- Region Server 负责维护 Master Server 分配给它的 Region并处理发送到 Region 上的 IO 请求;
- 当 Region 过大Region Server 负责自动分区,并通知 Master Server 记录更新。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200612151602.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200612151602.png)
### ZooKeeper
@ -100,7 +100,7 @@ ZooKeeper 的作用:
- 实时监控 Region Server 的状态,将 Region Server 的上线和下线信息实时通知给 Master
- 存储 HBase 的 Schema包括有哪些 Table每个 Table 有哪些 Column Family 等信息。
![img](https://raw.githubusercontent.com/dunwu/images/dev/cs/bigdata/hbase/1551166447147.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/cs/bigdata/hbase/1551166447147.png)
以上,最重要的一点是 ZooKeeper 如何保证 HBase 集群中只有一个 Master Server 的呢?
@ -136,7 +136,7 @@ HBase 内部保留名为 hbase:meta 的特殊目录表catalog table。它
注:`META` 表是 HBase 中一张特殊的表,它保存了所有 Region 的位置信息META 表自己的位置信息则存储在 ZooKeeper 上。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200601182655.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200601182655.png)
> 更为详细读取数据流程参考:
>

View File

@ -326,11 +326,11 @@ Connection 是一个集群连接封装了与多台服务器Matser/Region S
- **HBase Master** :主要用于执行 HBaseAdmin 接口的一些操作,例如建表等;
- **HBase RegionServer** :用于读、写数据。
![](https://raw.githubusercontent.com/dunwu/images/dev/snap/20230315202403.png)
![](https://raw.githubusercontent.com/dunwu/images/master/snap/20230315202403.png)
Connection 对象和实际的 Socket 连接之间的对应关系如下图:
![](https://raw.githubusercontent.com/dunwu/images/dev/snap/20230315202426.png)
![](https://raw.githubusercontent.com/dunwu/images/master/snap/20230315202426.png)
在 HBase 客户端代码中,真正对应 Socket 连接的是 `RpcConnection` 对象。HBase 使用 `PoolMap` 这种数据结构来存储客户端到 HBase 服务器之间的连接。`PoolMap` 的内部有一个 `ConcurrentHashMap` 实例,其 key 是 `ConnectionId`(封装了服务器地址和用户 ticket)value 是一个 `RpcConnection` 对象的资源池。当 HBase 需要连接一个服务器时,首先会根据 `ConnectionId` 找到对应的连接池,然后从连接池中取出一个连接对象。

View File

@ -114,7 +114,7 @@ Document 使用 JSON 格式表示,下面是一个例子。
- 实际的 node 上的 `primary shard` 处理请求,然后将数据同步到 `replica node`
- `coordinating node` 如果发现 `primary node` 和所有 `replica node` 都搞定之后,就返回响应结果给客户端。
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20210712104055.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20210712104055.png)
### ES 读数据过程

View File

@ -122,7 +122,7 @@ Elasticsearch 是一个近乎实时的搜索平台。这意味着**从索引文
#### 倒排索引
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220108215559.PNG)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20220108215559.PNG)
#### index template

View File

@ -46,11 +46,11 @@ ElasticSearch Rest API 分为两种:
URI Search 示例:
![](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220530072511.png)
![](https://raw.githubusercontent.com/dunwu/images/master/snap/20220530072511.png)
Request Body Search 示例:
![](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220530072654.png)
![](https://raw.githubusercontent.com/dunwu/images/master/snap/20220530072654.png)
## 索引 API

View File

@ -11,7 +11,7 @@ hidden: true
<p align="center">
<a href="https://dunwu.github.io/db-tutorial/" target="_blank" rel="noopener noreferrer">
<img src="https://raw.githubusercontent.com/dunwu/images/dev/common/dunwu-logo.png" alt="logo" width="150px"/>
<img src="https://raw.githubusercontent.com/dunwu/images/master/common/dunwu-logo.png" alt="logo" width="150px"/>
</a>
</p>
@ -96,7 +96,7 @@ hidden: true
### Mysql
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200716103611.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200716103611.png)
- [Mysql 应用指南](03.关系型数据库/02.Mysql/01.Mysql应用指南.md) ⚡
- [Mysql 工作流](03.关系型数据库/02.Mysql/02.MySQL工作流.md) - 关键词:`连接`、`缓存`、`语法分析`、`优化`、`执行引擎`、`redo log`、`bin log`、`两阶段提交`
@ -139,7 +139,7 @@ hidden: true
### Redis
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200713105627.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200713105627.png)
- [Redis 面试总结](05.KV数据库/01.Redis/01.Redis面试总结.md) 💯
- [Redis 应用指南](05.KV数据库/01.Redis/02.Redis应用指南.md) ⚡ - 关键词:`内存淘汰`、`事件`、`事务`、`管道`、`发布与订阅`

View File

@ -87,7 +87,7 @@ footer: CC-BY-SA-4.0 Licensed | Copyright © 2018-Now Dunwu
### Mysql
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200716103611.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200716103611.png)
- [Mysql 应用指南](12.数据库/03.关系型数据库/02.Mysql/01.Mysql应用指南.md) ⚡
- [Mysql 工作流](12.数据库/03.关系型数据库/02.Mysql/02.MySQL工作流.md) - 关键词:`连接`、`缓存`、`语法分析`、`优化`、`执行引擎`、`redo log`、`bin log`、`两阶段提交`
@ -130,7 +130,7 @@ footer: CC-BY-SA-4.0 Licensed | Copyright © 2018-Now Dunwu
### Redis
![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200713105627.png)
![img](https://raw.githubusercontent.com/dunwu/images/master/snap/20200713105627.png)
- [Redis 面试总结](12.数据库/05.KV数据库/01.Redis/01.Redis面试总结.md) 💯
- [Redis 应用指南](12.数据库/05.KV数据库/01.Redis/02.Redis应用指南.md) ⚡ - 关键词:`内存淘汰`、`事件`、`事务`、`管道`、`发布与订阅`