From 86c26a7cf6fecd5a5f41b6a82c7aa372f3a50556 Mon Sep 17 00:00:00 2001 From: CyC2018 <1029579233@qq.com> Date: Mon, 6 Aug 2018 22:29:40 +0800 Subject: [PATCH] auto commit --- notes/Redis.md | 15 +++++++++------ notes/SQL.md | 24 ++++++++++++------------ notes/数据库系统原理.md | 27 ++++++++++++++++++--------- notes/正则表达式.md | 39 +++++++++++++++++++-------------------- 4 files changed, 58 insertions(+), 47 deletions(-) diff --git a/notes/Redis.md b/notes/Redis.md index c54287c8..0981abf0 100644 --- a/notes/Redis.md +++ b/notes/Redis.md @@ -416,7 +416,7 @@ Reids 具体有 6 种淘汰策略: | allkeys-random | 从所有数据集中任意选择数据进行淘汰 | | noeviction | 禁止驱逐数据 | -作为内存数据库,出于对性能和内存消耗的考虑,Redis 的淘汰算法实际实现上并非针对所有 key,而是抽样一小部分 key 从中选出被淘汰 key。 +作为内存数据库,出于对性能和内存消耗的考虑,Redis 的淘汰算法实际实现上并非针对所有 key,而是抽样一小部分并且从中选出被淘汰的 key。 使用 Redis 缓存数据时,为了提高缓存命中率,需要保证缓存数据都是热点数据。可以将内存最大使用量设置为热点数据占用的内存量,然后启用 allkeys-lru 淘汰策略,将最近最少使用的数据淘汰。 @@ -440,7 +440,7 @@ Redis 是内存型数据库,为了保证数据在断电后不会丢失,需 将写命令添加到 AOF 文件(Append Only File)的末尾。 -使用 AOF 持久化需要设置同步选项,从而确保写命令什么时候会同步到磁盘文件上。这是因为对硬盘的文件进行写入并不会马上将内容同步到磁盘文件上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到硬盘。有以下同步选项: +使用 AOF 持久化需要设置同步选项,从而确保写命令什么时候会同步到磁盘文件上。这是因为对文件进行写入并不会马上将内容同步到磁盘上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到磁盘。有以下同步选项: | 选项 | 同步频率 | | :--: | :--: | @@ -449,8 +449,8 @@ Redis 是内存型数据库,为了保证数据在断电后不会丢失,需 | no | 让操作系统来决定何时同步 | - always 选项会严重减低服务器的性能; -- everysec 选项比较合适,可以保证系统奔溃时只会丢失一秒左右的数据,并且 Redis 每秒执行一次同步对服务器性能几乎没有任何影响; -- no 选项并不能给服务器性能带来多大的提升,而且也会增加系统奔溃时数据丢失的数量。 +- everysec 选项比较合适,可以保证系统崩溃时只会丢失一秒左右的数据,并且 Redis 每秒执行一次同步对服务器性能几乎没有任何影响; +- no 选项并不能给服务器性能带来多大的提升,而且也会增加系统崩溃时数据丢失的数量。 随着服务器写请求的增多,AOF 文件会越来越大。Redis 提供了一种将 AOF 重写的特性,能够去除 AOF 文件中的冗余写命令。 @@ -553,9 +553,12 @@ Sentinel(哨兵)可以监听主服务器,并在主服务器进入下线状 # 十三、分片 -分片是将数据划分为多个部分的方法,可以将数据存储到多台机器里面,也可以从多台机器里面获取数据,这种方法在解决某些问题时可以获得线性级别的性能提升。 +分片是将数据划分为多个部分的方法,可以将数据存储到多台机器里面,这种方法在解决某些问题时可以获得线性级别的性能提升。 -假设有 4 个 Reids 实例 R0,R1,R2,R3,还有很多表示用户的键 user:1,user:2,... 等等,有不同的方式来选择一个指定的键存储在哪个实例中。最简单的方式是范围分片,例如用户 id 从 0\~1000 的存储到实例 R0 中,用户 id 从 1001\~2000 的存储到实例 R1 中,等等。但是这样需要维护一张映射范围表,维护操作代价很高。还有一种方式是哈希分片,使用 CRC32 哈希函数将键转换为一个数字,再对实例数量求模就能知道应该存储的实例。 +假设有 4 个 Reids 实例 R0,R1,R2,R3,还有很多表示用户的键 user:1,user:2,... 等等,有不同的方式来选择一个指定的键存储在哪个实例中。 + +- 最简单的方式是范围分片,例如用户 id 从 0\~1000 的存储到实例 R0 中,用户 id 从 1001\~2000 的存储到实例 R1 中,等等。但是这样需要维护一张映射范围表,维护操作代价很高。 +- 还有一种方式是哈希分片,使用 CRC32 哈希函数将键转换为一个数字,再对实例数量求模就能知道应该存储的实例。 根据执行分片的位置,可以分为三种分片方式: diff --git a/notes/SQL.md b/notes/SQL.md index ca9b7b29..4a44aee8 100644 --- a/notes/SQL.md +++ b/notes/SQL.md @@ -19,7 +19,7 @@ * [十八、存储过程](#十八存储过程) * [十九、游标](#十九游标) * [二十、触发器](#二十触发器) -* [二十一、事务处理](#二十一事务处理) +* [二十一、事务管理](#二十一事务管理) * [二十二、字符集](#二十二字符集) * [二十三、权限管理](#二十三权限管理) * [参考资料](#参考资料) @@ -553,7 +553,7 @@ WHERE col5 = val; # 十八、存储过程 -存储过程可以看成是对一系列 SQL 操作的批处理; +存储过程可以看成是对一系列 SQL 操作的批处理。 使用存储过程的好处: @@ -642,11 +642,11 @@ SELECT @result; -- 获取结果 DELETE 触发器包含一个名为 OLD 的虚拟表,并且是只读的。 -UPDATE 触发器包含一个名为 NEW 和一个名为 OLD 的虚拟表,其中 NEW 是可以被修改地,而 OLD 是只读的。 +UPDATE 触发器包含一个名为 NEW 和一个名为 OLD 的虚拟表,其中 NEW 是可以被修改的,而 OLD 是只读的。 MySQL 不允许在触发器中使用 CALL 语句,也就是不能调用存储过程。 -# 二十一、事务处理 +# 二十一、事务管理 基本术语: @@ -708,12 +708,12 @@ SELECT user FROM user; **创建账户** +新创建的账户没有任何权限。 + ```sql CREATE USER myuser IDENTIFIED BY 'mypassword'; ``` -新创建的账户没有任何权限。 - **修改账户名** ```sql @@ -734,18 +734,14 @@ SHOW GRANTS FOR myuser; **授予权限** +账户用 username@host 的形式定义,username@% 使用的是默认主机名。 + ```sql GRANT SELECT, INSERT ON mydatabase.* TO myuser; ``` -账户用 username@host 的形式定义,username@% 使用的是默认主机名。 - **删除权限** -```sql -REVOKE SELECT, INSERT ON mydatabase.* FROM myuser; -``` - GRANT 和 REVOKE 可在几个层次上控制访问权限: - 整个服务器,使用 GRANT ALL 和 REVOKE ALL; @@ -754,6 +750,10 @@ GRANT 和 REVOKE 可在几个层次上控制访问权限: - 特定的列; - 特定的存储过程。 +```sql +REVOKE SELECT, INSERT ON mydatabase.* FROM myuser; +``` + **更改密码** 必须使用 Password() 函数 diff --git a/notes/数据库系统原理.md b/notes/数据库系统原理.md index cabc2f97..151ffc0f 100644 --- a/notes/数据库系统原理.md +++ b/notes/数据库系统原理.md @@ -44,10 +44,10 @@ ## 概念 -

- 事务指的是满足 ACID 特性的一组操作,可以通过 Commit 提交一个事务,也可以使用 Rollback 进行回滚。 +

+ ## ACID ### 1. 原子性(Atomicity) @@ -77,7 +77,7 @@ 事务的 ACID 特性概念简单,但不是很好理解,主要是因为这几个特性不是一种平级关系: - 只有满足一致性,事务的执行结果才是正确的。 -- 在无并发的情况下,事务串行执行,隔离性一定能够满足。此时要只要能满足原子性,就一定能满足一致性。 +- 在无并发的情况下,事务串行执行,隔离性一定能够满足。此时只要能满足原子性,就一定能满足一致性。 - 在并发的情况下,多个事务并发执行,事务不仅要满足原子性,还需要满足隔离性,才能满足一致性。 - 事务满足持久化是为了能应对数据库崩溃的情况。 @@ -123,7 +123,6 @@ T1 读取某个范围的数据,T2 在这个范围内插 ## 封锁粒度 -

MySQL 中提供了两种封锁粒度:行级锁以及表级锁。 @@ -133,6 +132,8 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。 在选择封锁粒度时,需要在锁开销和并发程度之间做一个权衡。 +

+ ## 封锁类型 ### 1. 读写锁 @@ -304,7 +305,11 @@ SELECT ... FOR UPDATE; # 五、多版本并发控制 -多版本并发控制(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现提交读和可重复读这两种隔离级别。而未提交读隔离级别总是读取最新的数据行,无需使用 MVCC;可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。 +多版本并发控制(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现提交读和可重复读这两种隔离级别。 + +而未提交读隔离级别总是读取最新的数据行,无需使用 MVCC。 + +可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。 ## 版本号 @@ -372,11 +377,15 @@ delete; # 六、Next-Key Locks -Next-Key Locks 也是 MySQL 的 InnoDB 存储引擎的一种锁实现。MVCC 不能解决幻读的问题,Next-Key Locks 就是为了解决这个问题而存在的。在可重复读(REPEATABLE READ)隔离级别下,使用 MVCC + Next-Key Locks 可以解决幻读问题。 +Next-Key Locks 是 MySQL 的 InnoDB 存储引擎的一种锁实现。 + +MVCC 不能解决幻读的问题,Next-Key Locks 就是为了解决这个问题而存在的。在可重复读(REPEATABLE READ)隔离级别下,使用 MVCC + Next-Key Locks 可以解决幻读问题。 ## Record Locks -锁定整个记录(行)。锁定的对象是记录的索引,而不是记录本身。如果表没有设置索引,InnoDB 会自动在主键上创建隐藏的聚集索引,因此 Record Locks 依然可以使用。 +锁定的对象是记录的索引,而不是记录本身。 + +如果表没有设置索引,InnoDB 会自动在主键上创建隐藏的聚集索引,因此 Record Locks 依然可以使用。 ## Gap Locks @@ -420,7 +429,7 @@ SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE; 如果 {A1,A2,... ,An} 是关系的一个或多个属性的集合,该集合函数决定了关系的其它所有属性并且是最小的,那么该集合就称为键码。 -对于 A->B,如果能找到 A 的真子集 A',使得 A'-> B,那么 A->B 就是部分函数依赖,否则就是完全函数依赖; +对于 A->B,如果能找到 A 的真子集 A',使得 A'-> B,那么 A->B 就是部分函数依赖,否则就是完全函数依赖。 对于 A->B,B->C,则 A->C 是一个传递函数依赖。 @@ -452,7 +461,7 @@ SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE; ### 1. 第一范式 (1NF) -属性不可分; +属性不可分。 ### 2. 第二范式 (2NF) diff --git a/notes/正则表达式.md b/notes/正则表达式.md index c6c21f2c..c713da63 100644 --- a/notes/正则表达式.md +++ b/notes/正则表达式.md @@ -23,11 +23,11 @@ # 二、匹配单个字符 -正则表达式一般是区分大小写的,但是也有些实现是不区分。 - **.** 可以用来匹配任何的单个字符,但是在绝大多数实现里面,不能匹配换行符; -**\\** 是元字符,表示它有特殊的含义,而不是字符本身的含义。如果需要匹配 . ,那么要用 \ 进行转义,即在 . 前面加上 \ 。 +**.** 是元字符,表示它有特殊的含义,而不是字符本身的含义。如果需要匹配 . ,那么要用 \ 进行转义,即在 . 前面加上 \ 。 + +正则表达式一般是区分大小写的,但是也有些实现是不区分。 **正则表达式** @@ -43,11 +43,11 @@ My **name** is Zheng. **[ ]** 定义一个字符集合; -0-9、a-z 定义了一个字符区间,区间使用 ASCII 码来确定,字符区间只能用在 [ ] 之间。 +0-9、a-z 定义了一个字符区间,区间使用 ASCII 码来确定,字符区间在 [ ] 中使用。 -**-** 元字符只有在 [ ] 之间才是元字符,在 [ ] 之外就是一个普通字符; +**-** 只有在 [ ] 之间才是元字符,在 [ ] 之外就是一个普通字符; -**^** 在 [ ] 字符集合中是取非操作。 +**^** 在 [ ] 中是取非操作。 **应用** @@ -78,9 +78,9 @@ abc[^0-9] | \t | 制表符 | | \v | 垂直制表符 | -\r\n 是 Windows 中的文本行结束标签,在 Unix/Linux 则是 \n ;\r\n\r\n 可以匹配 Windows 下的空白行,因为它将匹配两个连续的行尾标签,而这正是两条记录之间的空白行; +\r\n 是 Windows 中的文本行结束标签,在 Unix/Linux 则是 \n。 -. 是元字符,前提是没有对它们进行转义;f 和 n 也是元字符,但是前提是对它们进行了转义。 +\r\n\r\n 可以匹配 Windows 下的空白行,因为它将匹配两个连续的行尾标签,而这正是两条记录之间的空白行; ## 匹配特定的字符类别 @@ -105,11 +105,13 @@ abc[^0-9] | \s | 任何一个空白字符,等价于 [\f\n\r\t\v] | | \S | 对 \s 取非 | -\x 匹配十六进制字符,\0 匹配八进制,例如 \x0A 对应 ASCII 字符 10 ,等价于 \n,也就是它会匹配 \n 。 +\x 匹配十六进制字符,\0 匹配八进制,例如 \x0A 对应 ASCII 字符 10,等价于 \n。 # 五、重复匹配 -**\+** 匹配 1 个或者多个字符, **\*** 匹配 0 个或者多个,**?** 匹配 0 个或者 1 个。 +- **\+** 匹配 1 个或者多个字符 +- **\** * 匹配 0 个或者多个 +- **?** 匹配 0 个或者 1 个 **应用** @@ -127,16 +129,11 @@ abc[^0-9] **abc.def@qq.com** -为了可读性,常常把转义的字符放到字符集合 [ ] 中,但是含义是相同的。 +- **{n}** 匹配 n 个字符 +- **{m, n}** 匹配 m\~n 个字符 +- **{m,}** 至少匹配 m 个字符 -``` -[\w.]+@\w+\.\w+ -[\w.]+@[\w]+[\.][\w]+ -``` - -**{n}** 匹配 n 个字符,**{m, n}** 匹配 m\~n 个字符,**{m,}** 至少匹配 m 个字符; - -\* 和 + 都是贪婪型元字符,会匹配最多的内容,在元字符后面加 ? 可以转换为懒惰型元字符,例如 \*?、+? 和 {m, n}? 。 +\* 和 + 都是贪婪型元字符,会匹配最多的内容。在后面加 ? 可以转换为懒惰型元字符,例如 \*?、+? 和 {m, n}? 。 **正则表达式** @@ -220,7 +217,9 @@ a.+c **应用** -匹配 IP 地址。IP 地址中每部分都是 0-255 的数字,用正则表达式匹配时以下情况是合法的: +匹配 IP 地址。 + +IP 地址中每部分都是 0-255 的数字,用正则表达式匹配时以下情况是合法的: - 一位数字 - 不以 0 开头的两位数字