<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>数据库 on 清水泥沙</title>
    <link>https://869413421.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/</link>
    <description>Recent content in 数据库 on 清水泥沙</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-zh</language>
    <lastBuildDate>Tue, 07 Feb 2023 15:52:40 +0800</lastBuildDate><atom:link href="https://869413421.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>MySql（事务，锁）</title>
      <link>https://869413421.github.io/post/mysql_t/</link>
      <pubDate>Tue, 07 Feb 2023 15:52:40 +0800</pubDate>
      
      <guid>https://869413421.github.io/post/mysql_t/</guid>
      <description>事务是什么 事务是数据库一个不可以分隔的操作序列。在事务中执行的操作，会使结果从一个一致性状态到达另一个一致性状态。要么是产生操作结果，要么就是不产生结果
事务的四个特性（ACID） 原子性：一个事务是是一个执行单位，它要么就是全部执行，要么就是全部不执行。 一致性：事务执行的前后，多个事务对数据的读取是一致的。 隔离性：并发访问数据库是，一个事务中读取的数据是不受其他事务所影响的。 持久性：一个事务在提交之后，他作出的改变是持久的。 脏读 在一个事务中更新了一部分数据，这个时候另外一个事务读取了这一部分数据。而这个时候，第一个事务中回滚了数据，第二个事务中读取到的数据就是错误的了，这就是脏读。 幻读 在一个事务当中，两次查询的数据行数不一致。原因可能是在第一次读取后另外一个事务又插入了几行数据。 不可重复读 在一个事务当中，由于在两次查询中有另外一个事务更新了数据，所以导致两次查询的数据不一致。 事务隔离级别 READ-UNCOMMITTED(读取未提交)： 读取尚未提交的数据，可能造成脏读，幻读，不可重复读
READ-COMMITTED(读取已提交)： 读取已经提交的事务数据，能防止数据脏读，但仍然有可能会幻读，不可重复度。
REPEATABLE-READ(可重复读) 对数据同一个字段读取是保持一致的，当够避免脏读和不可重复读，但幻读依然可能存在。
SERIALIZABLE(可串行化)： 事务最高隔离级别，允许事务串行化，完成一个事务再继续下一个事务。所有事务都是逐个执行，可以避免脏读，幻读，不可重复读。
MySql事务的隔壁界别是REPEATABLE-READ（可重复读），MySql的事务机制是基于锁机制和并发调度实现的，隔离级别越低，使用的锁就越少。InnoDB 存储引擎在 分布式事务 的情况下一般会用到**SERIALIZABLE(可串行化)**隔离级别。
隔离级别与锁的关系 在READ-UNCOMMITTED(读取未提交)隔离级别下，数据不会进行加锁。 在READ-COMMITTED(读取已提交)隔离级别下，会加共享锁，语句执行完之后就会释放锁。 在REPEATABLE-READ(可重复读)，在读操作下会加共享锁，并且在事务结束之后才会进行释放。 SERIALIZABLE(可串行化)，会锁定整个范围的键，并且一直到事务结束。 锁粒度 在关系型数据库中，锁粒度一共有三种。
表级锁（table-level-locking） 表级锁是粒度最大的锁表方式，表示对当前操作的整张表进行加锁。锁资源消耗较少，MyIsAm和InnoDb都支持表级锁。
特点 开销小，加锁快。不会出现死锁，但是锁冲突率高，同时并发能力低。 行级锁（row-level-locking） 行级锁是颗粒度最小的锁表方式，它只会对当前操作的的记录进行锁定。行级锁，分为共享锁和排他锁。
特点 开销大，加锁慢。会出现死锁，锁冲突率低，并发能力高。 页级别锁 页级别锁，是表级别和行级别的一种折中方案。他会锁定当前操作的数据相邻的一组数据。
特点 开销和加锁时间介于行级和表级之间，会出现死锁，并发能力一般 共享锁与排他锁 共享锁：共享锁能同时存在多个，对数据加上共享锁之后，其他事务只能加共享锁对数据进行读取而不能进行修改。 排它锁 锁定的数据只能有一个排它锁，排他锁与其他类型的锁互斥，锁定的数据不能被其他操作进行读取或修改。 乐观锁和悲观锁 悲观锁： 假设数据冲突一定会发生，屏蔽掉一切可能违反数据完整性的操作，事务开启直接将数据锁死，直到事务完成。
乐观锁 ：假设数据冲突一定不会发生，只在最后持久化之前对数据完整性进行检查，如果不一致取消操作。</description>
    </item>
    
    <item>
      <title>MySql（查询优化）</title>
      <link>https://869413421.github.io/post/mysql_search/</link>
      <pubDate>Tue, 07 Feb 2023 15:52:40 +0800</pubDate>
      
      <guid>https://869413421.github.io/post/mysql_search/</guid>
      <description>mysql数据类型 (1) 整数类型
① tinyint
② smallint
③ mediumint
④ int
⑤ bigint
(2) 实数类型
① float
② double
③ decimal 可以存储比bigint还大的整数，可以用于存储精确的小数点
(3) 字符串类型
① varchar 可变长度的字符串类型，对于经常变更的数据char比varchar更好，char不容易产生碎片
② char 定长字符串类型，对于较短的数据varchar存储空间更有效率
③ blob
④ text 查询回使用临时表导致严重的性能开销
(4) 枚举
① 有时可以把常用的字符串替换成枚举类型
② 把不重复的集合存储成一个预定义的集合
③ 尽量避免使用数字作为enum作为常量，容易混乱
(5) 日期类型
① timestamp 存储的是整形，相对空间效率更高
② Datetime
(6) 列属性
① auto_increment自增
② default 默认值
③ not null 非空
④ zerofill 无符号填充
索引 (1) 索引对性能的影响
① 减少数据检索数量</description>
    </item>
    
    <item>
      <title>MySql（系统基础篇）</title>
      <link>https://869413421.github.io/post/mysql/</link>
      <pubDate>Tue, 07 Feb 2023 15:52:40 +0800</pubDate>
      
      <guid>https://869413421.github.io/post/mysql/</guid>
      <description>数据库三大范式是什么 第一范式：每个列不可拆分 第二范式：在第一范式基础上，所有非主键列完全依赖主键列，而不是主键的一部分 第三范式：在第二范式基础上，所有非主键列只依赖主键列，不依赖其他的非主键。 MySql自带的权限表 user权限表：记录允许连接到服务器的用户帐号信息，里面的权限是全局级的。 db权限表：记录各个帐号在各个数据库上的操作权限。 table_priv权限表：记录数据表级的操作权限。 columns_priv权限表：记录数据列级的操作权限。 host权限表：配合db权限表对给定主机上数据库级操作权限作更细致的控制。这个权限表不受GRANT和REVOKE语句的影响。 MySql的binlog binlog是MySql存储的二进制日志，用于记录用户操作Sql语句的信息
binlog具备三种模式
STATMENT模式 在STATMENT模式中用户每一条 修改数据的SQL都会记录到日志当中 优点： 不需要记录每一条SQL语句和每行的数据变化，减少磁盘的读写IO,减少数据库开销。
缺点： 在某些情况下会导致master-slave中的数据不一致(如sleep()函数， last_insert_id()，以及user-defined functions(udf)等会出现问题)
ROW模式 不记录每一条SQL的上下文的信息，只记录那一行被修改了，修改成什么样。 优点：不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发 无法被正确复制的问题。
缺点：会产生大量的日志，尤其是alter table的时候会让日志暴涨。
混合模式 一般情况下使用STATMENT模式记录日志，在无法使用STATMENT模式时，切换为ROW模式。MySql会根据执行的SQL来选择日志保存的方式。 binlog的设置 在MySQL配置文件my.cnf文件中的mysqld节中添加下面的配置文件：
[mysqld]
#设置日志格式
binlog_format = mixed 设置日志路径，注意路经需要mysql用户有权限写 log-bin = /data/mysql/logs/mysql-bin.log 设置binlog清理时间 expire_logs_days = 7 binlog每个日志文件大小 max_binlog_size = 100m binlog缓存大小 binlog_cache_size = 4m 最大binlog缓存大小 max_binlog_cache_size = 512m 重启MySQL生效，如果不方便重启服务，也可以直接修改对应的变量即可。
引擎 常用的引擎
InnoDB InnoDB提供了ACID的事务支持，并且支持行级别锁，外键约束。 MyIASM MyIASM不支持事务，行级别锁。但是支持表级别锁 MEMORY MyIASM所有数据存储在内存中，读取速度快，但是安全性低 MyIAM索引和InnoDB索引的区别 InnoDB索引是聚簇索引，MyISAM索引是非聚簇索引。 InnoDB索引的叶子节点上存储着索引和行数据，所以InnoDB的主键索引数据非常高效 MyIASM索引的叶子节点上存储着行数据距的指向地址，需要再根据地址去进行查找 InnoDB的非主键索引的叶子节点存储着主键和其他非主键索引的列数据 InnoDB的四大特性 插入缓冲 插入缓冲在非唯一索引非聚合索引才生效，当第一次插入时，MySQL会先检查buffer中是否包含索引页，如果有直接插入，如果没有先放置到buffer中，等到一定频率再合并操作。</description>
    </item>
    
    <item>
      <title>MySql（索引）</title>
      <link>https://869413421.github.io/post/mysql_index/</link>
      <pubDate>Tue, 07 Feb 2023 15:52:40 +0800</pubDate>
      
      <guid>https://869413421.github.io/post/mysql_index/</guid>
      <description>索引是什么 索引是一个特殊的文件，他是实际存在在文件系统中的，记录着数据表里所有数据的引用指针
索引是一个数据结构，是数据库操作系统的一种排序数据结构，能帮助我们快速查询，更新我们数据表的数据
优点 创建索引的原因是为了帮助用户快速地检索数据 缺点 创建索引能加快检索速度，但是也意味着数据库增删改时需要对索引进行维护，会增加增删改的性能消耗，降低执行效率。 索引是实际存在系统中的，会占用系统的存储空间。 索引使用场景 where 因为主键索引中存储或者包含了行数据的引用地址，一般情况下，主键索引是最快的。如果一个where 语句中包含多个索引，MySql会选择最优的命中。
orderBy 在我们对某个字段进行orderBy时，如果这个字段没有建立索引，MySql会使用外部排序，即是将查询到的结果集分批从硬盘当中读取内存中进行排序,这个操作不仅要进行IO操作还要占用内存进行排序所以它是非常影响性能的。
如果存在索引的情况下，MySql会直接根据索引的排序和映射逐条取出数据。如果是分页的话直接取索引某个范围进行读取。不再需要读入内存中排序后再进行截取某一部分数据。
join 在我们设计表结构的时候，我们要join的字段应该是一个外键并且应该加上索引，这样能提高join时的查询效率，如果外键不存在索引的情况下，join的表可能会出现全表扫描。严重损耗检索效率
索引覆盖 如果我们一个select语句中，需要查询的字段都建立过索引，那么MySql会直接从索引页中获取数据，而不再去查询原始数据，这个就是索引覆盖。索引我们在写查询语句的时候尽量select需要的字段，提高索引覆盖的几率。
索引的几种类型 主键索引：数据表中的唯一标识，不允许为null
唯一索引：数据表的的列不允许重复，多个列可以聚合，允许为null
普通索引：基础的索引，多个列可以聚合，允许为null
全文索引： 一种全文搜索索引
索引的两种算法 b+tree BTree是最常用的mysql数据库索引算法，也是mysql默认的算法。因为它不仅可以被用在=,&amp;gt;,&amp;gt;=,&amp;lt;,&amp;lt;=和between这些比较操作符上，而且还可以用于like操作符，只要它的查询条件是一个不以通配符开头的常量， 例如：
hash算法 Hash索引只能用于对等比较，例如=,&amp;lt;=&amp;gt;（相当于=）操作符。由于是一次定位数据，不像BTree索引需要从根节点到枝节点，最后才能访问到页节点这样多次IO访问，所以检索效率远高于BTree索引。
索引的设计原则 适合索引的字段应该是出现在where语句中，或者join连接的列中。
数据过少的表不适合创建索引
尽量是用短索引，有时需要索引很长的字符列，它会使索引变大并且变慢。索引字符串的前半部分能有效地节约索引空间。
不要过度索引，索引会占用磁盘空间，并且会降低写性能。索引的创建只要保证查询性能即可。
索引的创建原则 最左前匹配原则，是聚合索引中非常重要的原则，MySql会一直向右匹配直到遇到范围查询(&amp;gt;、&amp;lt;、between、like)就停止匹配。例如组合索引abc,查询语句为a=1,b&amp;gt;2,c=3。这样c是使用不了索引的。
字段较为频繁查询的应该使用索引。
频繁更新的字段不适合创建索引。
不能有效区分的列不适合创建索引。(如性别，男女未知，最多也就三种，区分度实在太低)
尽量扩展索引，而不是去新建索引。如系统上有a索引，要增加一个ab索引，应该直接拓展索引，将a索引修改为ab索引。
有外键的列一定要建立索引。
对text,image,bit或者数据过长的字段不要建立索引
创建索引需要注意什么 不要设置可空字段，因为可空字段很难被查询优化，同事会使索引排序运算更加复杂，可以使用一个特殊的值或者0或者空字符串代替。
取离散值最大的字段（数据表值唯一值越多的离散值越大）
索引字段越小越好，字段过长影响索引效率，占用更多内存空间。
最左前缀原则，最左前匹配原则 顾名思义，就是最左优先，在创建多列索引时，要根据业务需求，where子句中使用最频繁的一列放在最左边。
最左前缀匹配原则，非常重要的原则，mysql会一直向右匹配直到遇到范围查询(&amp;gt;、&amp;lt;、between、like)就停止匹配，比如a = 1 and b = 2 and c &amp;gt; 3 and d = 4 如果建立(a,b,c,d)顺序的索引，d是用不到索引的，如果建立(a,b,d,c)的索引则都可以用到，a,b,d的顺序可以任意调整。
=和in可以乱序，比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序，mysql的查询优化器会帮你优化成索引可以识别的形式</description>
    </item>
    
    <item>
      <title>MySql（高可用，高拓展）</title>
      <link>https://869413421.github.io/post/mysql_build/</link>
      <pubDate>Tue, 07 Feb 2023 15:52:40 +0800</pubDate>
      
      <guid>https://869413421.github.io/post/mysql_build/</guid>
      <description>* 分区表原理 工作原理
对用户而言，分区表是一个独立的逻辑表，mysql底层将其分成了多个物理子表，每一个分区表都是一个独立的文件
适用场景
表非常大，无法全部存放在内存中，或者表的最后有热点数据，其他的都是历史数据 分区表更容易维护，可以对独立的分区进行操作 分区表可以分布在不同的服务器上 可以使用分区表避免某些特殊的瓶颈 可以恢复和备份独立的分区 限制
一个表只能有1024个分区 5.1版本中，分区表达式必须是整数 分区表字段中如果包含主键和唯一所以，那么主键和唯一列必须包含进去 分区表中不能使用外键约束 如果需要对现有表进行修改 所有分区表虚使用相同的存储引擎 某些引擎不支持分区 分库分表 工作原理 通过一些hash算法和工具实现将一张表的数据，垂直拆分和水平拆分 使用场景 单表记录数到达百万或者千万级别时候 解决表锁的问题 分表方式 水平分割 表很大，分割后降低在查询时候所需要读取的数据和索引的页数 使用场景 表中的数据具有独立性，比如说表中记录各个地区的数据或者不同时期的数据 需要把不同的数据存放在不同的介质 缺点 给应用增加复杂度，查询某些数据的时候需要定位到数据在某张表 垂直分割 将数据表的列进行分割，常用的列和不常用的列拆分成两个表 使用场景 一个表中一些列不常用，列外一些列常用 可以使数据行变小，一个数据也能存储更多的数据，查询时候减少IO次数 缺点 查询冗余，查询需要进行join操作 mysql主从复制 工作原理 在主库上把数据更改记录到二进制文件，从库将 主库的日志复制到自己的中继日志当中。从库读取日志，将数据重写到从库数据当中。 主从复制解决的问题 数据分布：随意停止或开始复制 负载均衡：降低单个服务器压力 高可用和故障切换：某个节点失败后其他节点顶替其工作，避免程序崩溃 异步复制：也是默认的主从同步方式。这种方式的优点是效率高。缺点是不能保证数据一定会到达slave。可能会受到网络等原因出现延迟，导致主从数据不一致。当前对master中的表进行数据操作，master将事务Binlog事件写入到Binlog文件中，此时主库只会通知一下Dump线程发送这些新的Binlog到slave（slave的 I/O 线程读取并将事件写入relay-log中）然后主库就会继续处理提交操作，而此时不会保证这些Binlog传到任何一个从库节点上。 全同步复制：优点是能够保证数据的强一致性，缺点是效率太低。当master上有提交事务之后，Dump线程发送这些新的Binlog到slave上，并且必须等待所有的slave回复成功（所有从库将事件写入中继日志，并将数据写入数据库）才能继续下一步操作。 半同步复制：优点是在耗费少量性能的基础上能在一定程度上保证数据的一致性。当master上有提交事务之后，Dump线程发送这些新的Binlog到slave上，并且必须等待其中一个slave回复成功（slave将事件写入relay-log）才能继续下一步操作。 </description>
    </item>
    
  </channel>
</rss>
