mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-16 18:10:13 +08:00
[docs update]规范markdown格式
This commit is contained in:
parent
a7cff6ef6e
commit
8440af732b
@ -68,7 +68,7 @@ star: 2
|
||||
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
加入星球之后,记得抽时间把星球精华主题看看,相信你一定会有所收货!
|
||||
|
||||
|
@ -55,11 +55,9 @@ tag:
|
||||
好了,再来说回:“为什么网络要分层?”。我觉得主要有 3 方面的原因:
|
||||
|
||||
1. **各层之间相互独立**:各层之间相互独立,各层之间不需要关心其他层是如何实现的,只需要知道自己如何调用下层提供好的功能就可以了(可以简单理解为接口调用)**。这个和我们对开发时系统进行分层是一个道理。**
|
||||
2. **提高了整体灵活性**:每一层都可以使用最适合的技术来实现,你只需要保证你提供的功能以及暴露的接口的规则没有改变就行了。**这个和我们平时开发系统的时候要求的高内聚、低耦合的原则也是可以对应上的。**
|
||||
2. **提高了灵活性和可替换性**:每一层都可以使用最适合的技术来实现,你只需要保证你提供的功能以及暴露的接口的规则没有改变就行了。并且,每一层都可以根据需要进行修改或替换,而不会影响到整个网络的结构。**这个和我们平时开发系统的时候要求的高内聚、低耦合的原则也是可以对应上的。**
|
||||
3. **大问题化小**:分层可以将复杂的网络问题分解为许多比较小的、界线比较清晰简单的小问题来处理和解决。这样使得复杂的计算机网络系统变得易于设计,实现和标准化。 **这个和我们平时开发的时候,一般会将系统功能分解,然后将复杂的问题分解为容易理解的更小的问题是相对应的,这些较小的问题具有更好的边界(目标和接口)定义。**
|
||||
|
||||
网络分层的另一个主要目的是为了实现可替换性(interchangeability)。这意味着在一个网络中的一个层次的组件可以被替换为不同厂家的实现,只要它们遵循相同的标准和接口规范,不至于被卡脖子。
|
||||
|
||||
我想到了计算机世界非常非常有名的一句话,这里分享一下:
|
||||
|
||||
> 计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决,计算机整个体系从上到下都是按照严格的层次结构设计的。
|
||||
|
@ -6,23 +6,33 @@ tag:
|
||||
---
|
||||
|
||||
## 多版本并发控制 (Multi-Version Concurrency Control)
|
||||
|
||||
MVCC 是一种并发控制机制,用于在多个并发事务同时读写数据库时保持数据的一致性和隔离性。它是通过在每个数据行上维护多个版本的数据来实现的。当一个事务要对数据库中的数据进行修改时,MVCC 会为该事务创建一个数据快照,而不是直接修改实际的数据行。
|
||||
|
||||
1. 读操作(SELECT):
|
||||
1、读操作(SELECT):
|
||||
|
||||
当一个事务执行读操作时,它会使用快照读取。快照读取是基于事务开始时数据库中的状态创建的,因此事务不会读取其他事务尚未提交的修改。具体工作情况如下:
|
||||
* 对于读取操作,事务会查找符合条件的数据行,并选择符合其事务开始时间的数据版本进行读取。
|
||||
* 如果某个数据行有多个版本,事务会选择不晚于其开始时间的最新版本,确保事务只读取在它开始之前已经存在的数据。
|
||||
* 事务读取的是快照数据,因此其他并发事务对数据行的修改不会影响当前事务的读取操作。
|
||||
2. 写操作(INSERT、UPDATE、DELETE):
|
||||
|
||||
- 对于读取操作,事务会查找符合条件的数据行,并选择符合其事务开始时间的数据版本进行读取。
|
||||
- 如果某个数据行有多个版本,事务会选择不晚于其开始时间的最新版本,确保事务只读取在它开始之前已经存在的数据。
|
||||
- 事务读取的是快照数据,因此其他并发事务对数据行的修改不会影响当前事务的读取操作。
|
||||
|
||||
2、写操作(INSERT、UPDATE、DELETE):
|
||||
|
||||
当一个事务执行写操作时,它会生成一个新的数据版本,并将修改后的数据写入数据库。具体工作情况如下:
|
||||
* 对于写操作,事务会为要修改的数据行创建一个新的版本,并将修改后的数据写入新版本。
|
||||
* 新版本的数据会带有当前事务的版本号,以便其他事务能够正确读取相应版本的数据。
|
||||
* 原始版本的数据仍然存在,供其他事务使用快照读取,这保证了其他事务不受当前事务的写操作影响。
|
||||
3. 事务提交和回滚:
|
||||
* 当一个事务提交时,它所做的修改将成为数据库的最新版本,并且对其他事务可见。
|
||||
* 当一个事务回滚时,它所做的修改将被撤销,对其他事务不可见。
|
||||
4. 版本的回收:
|
||||
为了防止数据库中的版本无限增长,MVCC会定期进行版本的回收。回收机制会删除已经不再需要的旧版本数据,从而释放空间。
|
||||
|
||||
- 对于写操作,事务会为要修改的数据行创建一个新的版本,并将修改后的数据写入新版本。
|
||||
- 新版本的数据会带有当前事务的版本号,以便其他事务能够正确读取相应版本的数据。
|
||||
- 原始版本的数据仍然存在,供其他事务使用快照读取,这保证了其他事务不受当前事务的写操作影响。
|
||||
|
||||
3、事务提交和回滚:
|
||||
|
||||
- 当一个事务提交时,它所做的修改将成为数据库的最新版本,并且对其他事务可见。
|
||||
- 当一个事务回滚时,它所做的修改将被撤销,对其他事务不可见。
|
||||
|
||||
4、版本的回收:
|
||||
|
||||
为了防止数据库中的版本无限增长,MVCC 会定期进行版本的回收。回收机制会删除已经不再需要的旧版本数据,从而释放空间。
|
||||
|
||||
MVCC 通过创建数据的多个版本和使用快照读取来实现并发控制。读操作使用旧版本数据的快照,写操作创建新版本,并确保原始版本仍然可用。这样,不同的事务可以在一定程度上并发执行,而不会相互干扰,从而提高了数据库的并发性能和数据一致性。
|
||||
|
||||
|
@ -56,7 +56,7 @@ index = hash % array_size
|
||||
|
||||
为了减少 Hash 冲突的发生,一个好的哈希函数应该“均匀地”将数据分布在整个可能的哈希值集合中。
|
||||
|
||||
MySQL的InnoDB存储引擎不直接支持常规的哈希索引,但是,InnoDB存储引擎中存在一种特殊的“自适应哈希索引”(Adaptive Hash Index),自适应哈希索引并不是传统意义上的纯哈希索引,而是结合了B+Tree和哈希索引的特点,以便更好地适应实际应用中的数据访问模式和性能需求。自适应哈希索引的每个哈希桶实际上是一个小型的B+Tree结构。这个B+Tree结构可以存储多个键值对,而不仅仅是一个键。这有助于减少哈希冲突链的长度,提高了索引的效率。
|
||||
MySQL 的 InnoDB 存储引擎不直接支持常规的哈希索引,但是,InnoDB 存储引擎中存在一种特殊的“自适应哈希索引”(Adaptive Hash Index),自适应哈希索引并不是传统意义上的纯哈希索引,而是结合了 B+Tree 和哈希索引的特点,以便更好地适应实际应用中的数据访问模式和性能需求。自适应哈希索引的每个哈希桶实际上是一个小型的 B+Tree 结构。这个 B+Tree 结构可以存储多个键值对,而不仅仅是一个键。这有助于减少哈希冲突链的长度,提高了索引的效率。
|
||||
|
||||
既然哈希表这么快,**为什么 MySQL 没有使用其作为索引的数据结构呢?** 主要是因为 Hash 索引不支持顺序和范围查询。假如我们要对表中的数据进行排序或者进行范围查询,那 Hash 索引可就不行了。并且,每次 IO 只能取一个。
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user