数据库技术
2022-07-30 21:05:19   0  举报             
     
         
 AI智能生成
  数据库技术
    作者其他创作
 大纲/内容
  数据库系统原理    
     事务ACID    
     原子性:事务被视为不可分割的最小单元,事务的所有操作要么全部提交成功,要么全部失败回滚。  
     一致性:数据库在事务执行前后都保持一致性状态。在一致性状态下,所有事务对一个数据的读取结果都是相同的。  
     隔离性:一个事务所做的修改在最终提交以前,对其它事务是不可见的。  
     持久性:一旦事务提交,则其所做的修改将会永远保存到数据库中。即使系统发生崩溃,事务执行的结果也不能丢失。 使用重做日志来保证持久性。  
     并发一致性问题    
     丢失修改:T1 和 T2 两个事务都对一个数据进行修改,T1 先修改,T2 随后修改,T2 的修改覆盖了 T1 的修改。  
     读肮数据:T1 修改一个数据,T2 随后读取这个数据。如果 T1 撤销了这次修改,那么 T2 读取的数据是脏数据。  
     不可重复读:T2 读取一个数据,T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。  
     幻影读:T1 读取某个范围的数据,T2 在这个范围内插入新的数据,T1 再次读取这个范围的数据,此时读取的结果和和第一次 读取的结果不同。  
     产生并发不一致性问题主要原因是破坏了事务的隔离性,解决方法是通过并发控制来保证隔离性。并发控制可以通过
封锁来实现,但是封锁操作需要用户自己控制,相当复杂。数据库管理系统提供了事务的隔离级别,让用户以一种更
轻松的方式处理并发一致性问题。
    封锁来实现,但是封锁操作需要用户自己控制,相当复杂。数据库管理系统提供了事务的隔离级别,让用户以一种更
轻松的方式处理并发一致性问题。
 隔离级别    
     未提交读(READ UNCOMMITTED)    
     事务中的修改,即使没有提交,对其它事务也是可见的。  
     提交读(READ COMMITTED)    
     一个事务只能读取已经提交的事务所做的修改。换句话说,一个事务所做的修改在提交之前对其它事务是不可见的。  
     可重复读(REPEATABLE READ)    
     保证在同一个事务中多次读取同样数据的结果是一样的。  
     可串行化(SERIALIZABLE)    
     强制事务串行执行。
需要加锁实现,而其它隔离级别通常不需要。
    需要加锁实现,而其它隔离级别通常不需要。
 图示           
     封锁    
     封锁粒度  
     封锁类型    
     1. 读写锁    
     排它锁(Exclusive),简写为 X 锁,又称写锁。 共享锁(Shared),简写为 S 锁,又称读锁。  
                                      一个事务对数据对象 A 加了 X 锁,就可以对 A 进行读取和更新。加锁期间其它事务不能对 A 加任何锁。                                                                                   一个事务对数据对象 A 加了 S 锁,可以对 A 进行读取操作,但是不能进行更新操作。加锁期间其它事务能对 A 加 S 锁,但是不能加 X 锁。  
     2.意向锁  
     封锁协议    
     1. 三级封锁协议    
     一级封锁协议    
     事务 T 要修改数据 A 时必须加 X 锁,直到 T 结束才释放锁。 可以解决丢失修改问题,因为不能同时有两个事务对同一个数据进行修改,那么事务的修改就不会被覆盖。  
     二级封锁协议    
     在一级的基础上,要求读取数据 A 时必须加 S 锁,读取完马上释放 S 锁。
可以解决读脏数据问题,因为如果一个事务在对数据 A 进行修改,根据 1 级封锁协议,会加 X 锁,那么就不能再加 S 锁了,也就是不会读入数据。
    可以解决读脏数据问题,因为如果一个事务在对数据 A 进行修改,根据 1 级封锁协议,会加 X 锁,那么就不能再加 S 锁了,也就是不会读入数据。
 三级封锁协议    
     在二级的基础上,要求读取数据 A 时必须加 S 锁,直到事务结束了才能释放 S 锁。 可以解决不可重复读的问题,因为读 A 时,其它事务不能对 A 加 X 锁,从而避免了在读的期间数据发生改变。  
     2.两段锁协议    
     加锁和解锁分为两个阶段进行。  
     可串行化调度是指,通过并发控制,使得并发执行的事务结果与某个串行执行的事务结果相同。
事务遵循两段锁协议是保证可串行化调度的充分条件。例如以下操作满足两段锁协议,它是可串行化调度。
    事务遵循两段锁协议是保证可串行化调度的充分条件。例如以下操作满足两段锁协议,它是可串行化调度。
 MySQL 隐式与显示锁定    
     MySQL 的 InnoDB 存储引擎采用两段锁协议,会根据隔离级别在需要的时候自动加锁,并且所有的锁都是在同一时
刻被释放,这被称为隐式锁定。
InnoDB 也可以使用特定的语句进行显示锁定:
    刻被释放,这被称为隐式锁定。
InnoDB 也可以使用特定的语句进行显示锁定:
 数据库设计    
     三大范式    
     第一范式1NF    
     列的原子性  
      第二范式 2NF    
     满足第一范式,必须有主键列  
     第三范式3NF    
     满足第二范式,主外健引用  
     完整性约束    
     约束是表级的强制规定,有以下五中:not null,unique,primary key,foreign key,check 。
  
     数据库模型    
     概念模型    
     ER图  
     逻辑模型    
     关系:二维表  
     物理模型    
     表结构,包括字段,长度,非空等  
     mysql    
     存储引擎    
     InnoDB    
     问题1:innoDB是使用主键构建B+TREE的。使用整型会比UUID好很多,比较会减少,内存会较小  
     MyISAM    
     索引和数据是分开的。  
     比较           
     事务:InnoDB 是事务型的,可以使用 Commit 和 Rollback 语句。 并发:MyISAM 只支持表级锁,而 InnoDB 还支持行级锁。 外键:InnoDB 支持外键。
备份:InnoDB 支持在线热备份。
崩溃恢复:MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢。 其它特性:MyISAM 支持压缩表和空间数据索引。
    备份:InnoDB 支持在线热备份。
崩溃恢复:MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢。 其它特性:MyISAM 支持压缩表和空间数据索引。
 MyISANM适合做读库,InnoDB写多读少  
     索引    
     索引类型(按数据结构分)    
     1. B+Tree 索引    
     B+ Tree 原理    
     1.数据结构    
     B Tree 指的是 Balance Tree,也就是平衡树。平衡树是一颗查找树,并且所有叶子节点位于同一层。(看图理解)
B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具有 B Tree 的平衡性,并且通过顺序访问指针来提高 区间查询的性能。
在 B+ Tree 中,一个节点中的 key 从左到右非递减排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,且不 为 null,则该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。
    B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具有 B Tree 的平衡性,并且通过顺序访问指针来提高 区间查询的性能。
在 B+ Tree 中,一个节点中的 key 从左到右非递减排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,且不 为 null,则该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。
 优势劣势的操作    
     进行查找操作时,首先在根节点进行二分查找,找到一个 key 所在的指针,然后递归地在指针所指向的节点进行查
找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的 data。
    找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的 data。
 插入删除操作会破坏平衡树的平衡性,因此在插入删除操作之后,需要对树进行一个分裂、合并、旋转等操作来维护平衡性。  
     优势     
     更少查询次数  
     利用磁盘预读特性  
     B+Tree(加强版多路平衡树,多岔树),没有B-Tree;不用平衡二叉树数据量大的话,树越高,所以尽量让树变得低,查找次数越低,磁盘IO 越少。B树比平衡二叉树减少了一次磁盘IO,  
     图示           
     B+树的数据结构  
     注意 这是mysql   B+树检索过程(后面查找过程分析)    
     查找过程  
     大多数 MySQL 存储引擎的默认索引类型    
     InnoDB 的 B+Tree 索引分为主索引和辅助索引。主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被 称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。  
     辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到 主索引中进行查找。  
     2. 哈希索引    
     哈希索引能以 O(1) 时间进行查找,但是失去了有序性:
无法用于排序与分组(重点);
只支持精确查找,无法用于部分查找和范围查找。
InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之 上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。
    无法用于排序与分组(重点);
只支持精确查找,无法用于部分查找和范围查找。
InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之 上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。
 3. 全文索引    
     MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。 查找条件使用 MATCH AGAINST,而不是普通的 WHERE。  
     全文索引使用倒排索引实现,它记录着关键词到其所在文档的映射。
InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。
    InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。
 4. 空间数据索引    
     MyISAM 存储引擎支持空间数据索引(R-Tree),可以用于地理数据存储。空间数据索引会从所有维度来索引数据, 可以有效地使用任意维度来进行组合查询。
必须使用 GIS 相关的函数来维护数据。
    必须使用 GIS 相关的函数来维护数据。
 按物理存储结构分    
     聚族索引    
     数据和索引存储在同一文件中,以主键索引存储数据  
     表中的行的物理顺序和健值的逻辑(索引)顺序相同,一个表只包含一个聚集索引  
     非聚族索引    
     数据和索引分开,单独存放在不同的文件中,索引文件不存储数据,而是存储数据的地址。  
     数据库表中记录的物理顺序和索引顺序可以不相同,一个表可以包含多个非聚集索引  
     按字段列分    
     单列索引    
     主键索引  
     唯一索引  
     普通索引  
     组合索引  
     索引优化    
     1.最左前缀匹配  
     2.覆盖索引  
     3.索引顺序    
     让选择性最强的索引列放在前面。
索引的选择性是指:不重复的索引值和记录总数的比值。最大值为 1,此时每个记录都有唯一的索引与其对应。选择性越高,每个记录的区分度越高,查询效率也越高。
  
    索引的选择性是指:不重复的索引值和记录总数的比值。最大值为 1,此时每个记录都有唯一的索引与其对应。选择性越高,每个记录的区分度越高,查询效率也越高。
 注意事项    
     字符串 不要忘了“” ,  
     like % 不要写最前  
     where 后索引列 不能计算  
     where对null判断
where不等于
    where不等于
 SQL执行计划    
     explain 分析  
     重构查询方式    
     1.切分大查询  
     2.切分大连接查询  
     索引是mysql高效获取数据的排好序的数据结构。  
     为什么选择B+树作为索引结构
  
     切分    
     水平切分    
     水平切分又称为 Sharding,它是将同一个表中的记录拆分到多个结构相同的表中。 当一个表的数据不断增多时,Sharding 是必然的选择,它可以将数据分布到集群的不同节点上,从而缓存单个数据库的压力。  
     垂直切分    
     垂直切分是将一张表按列切分成多个表,通常是按照列的关系密集程度进行切分,也可以利用垂直切分将经常被使用
的列和不经常被使用的列切分到不同的表中。
在数据库的层面使用垂直切分将按数据库中表的密集程度部署到不同的库中,例如将原来的电商数据库垂直切分成商
品数据库、用户数据库等。
    的列和不经常被使用的列切分到不同的表中。
在数据库的层面使用垂直切分将按数据库中表的密集程度部署到不同的库中,例如将原来的电商数据库垂直切分成商
品数据库、用户数据库等。
 Sharding 策略    
     哈希取模:hash(key) % N;
  
      映射表:使用单独的一个数据库来存储映射关系。  
     范围:可以是 ID 范围也可以是时间范围;  
     Sharding 存在的问题    
     1. 事务问题 使用分布式事务来解决,比如 XA 接口。
  
     2. 连接 可以将原来的连接分解成多个单表查询,然后在用户程序中进行连接。   
     3. ID 唯一性
使用全局唯一 ID(GUID)
为每个分片指定一个 ID 范围
分布式 ID 生成器 (如 Twitter 的 Snowflake 算法)
    使用全局唯一 ID(GUID)
为每个分片指定一个 ID 范围
分布式 ID 生成器 (如 Twitter 的 Snowflake 算法)
 复制    
     主从复制    
     主要涉及三个线程:binlog 线程、I/O 线程和 SQL 线程。
binlog 线程 :负责将主服务器上的数据更改写入二进制日志(Binary log)中。
I/O 线程 :负责从主服务器上读取二进制日志,并写入从服务器的中继日志(Relay log)。
SQL 线程 :负责读取中继日志,解析出主服务器已经执行的数据更改并在从服务器中重放(Replay)。
    binlog 线程 :负责将主服务器上的数据更改写入二进制日志(Binary log)中。
I/O 线程 :负责从主服务器上读取二进制日志,并写入从服务器的中继日志(Relay log)。
SQL 线程 :负责读取中继日志,解析出主服务器已经执行的数据更改并在从服务器中重放(Replay)。
 子主题  
     读写分离           
     主服务器处理写操作以及实时性要求比较高的读操作,而从服务器处理读操作。
读写分离能提高性能的原因在于:
主从服务器负责各自的读和写,极大程度缓解了锁的争用; 从服务器可以使用 MyISAM,提升查询性能以及节约系统开销; 增加冗余,提高可用性。
读写分离常用代理方式来实现,代理服务器接收应用层传来的读写请求,然后决定转发到哪个服务器。
    读写分离能提高性能的原因在于:
主从服务器负责各自的读和写,极大程度缓解了锁的争用; 从服务器可以使用 MyISAM,提升查询性能以及节约系统开销; 增加冗余,提高可用性。
读写分离常用代理方式来实现,代理服务器接收应用层传来的读写请求,然后决定转发到哪个服务器。
 SQL基础    
     DDL:数据定义语言    
     添加一行:alter table apple add red varchar[50];
修改表名: rename table apple To banana
修改列名:alter table apple change red green int ;
修改一个表的字段类型:alter table apple modify red varchar(50);
查看表的字段信息:desc apple;
删除一列:alter table apple drop red;
    修改表名: rename table apple To banana
修改列名:alter table apple change red green int ;
修改一个表的字段类型:alter table apple modify red varchar(50);
查看表的字段信息:desc apple;
删除一列:alter table apple drop red;
 DML:数据操作语言
    
     查看表:show tables;
查询表中的所有数据:select * from Apple ;
插入操作:insert into apple(red,green) value(nice,bad);
更新操作:update apple set red=5; 限定条件:update apple set red=10 where green=5;
删除操作:delete from apple ;(删除表中的数据,表结构还在) truncate table apple;(把表直接drop掉,然后再创建一个同样的表)
  
    查询表中的所有数据:select * from Apple ;
插入操作:insert into apple(red,green) value(nice,bad);
更新操作:update apple set red=5; 限定条件:update apple set red=10 where green=5;
删除操作:delete from apple ;(删除表中的数据,表结构还在) truncate table apple;(把表直接drop掉,然后再创建一个同样的表)
 DQL:数据查询语言   
     权限    
     grant all privileges on 数据库名.表明(所有:*.*) To 用户名 identify by '密码'(with grant option——给与其给别人权限的权限);
  
     子查询    
     外连接  
     自连接  
     视图    
     创建视图:create view name as();
修改视图:create or replace view name as ();
删除视图:drop view name ;
algorithm:替代式:merge 具化式:temptable (更安全)
with check option 更新数据时进行检测
create algorithm view name as (conditon) with check option;
视图不可更新部分:不是来自于基表
    修改视图:create or replace view name as ();
删除视图:drop view name ;
algorithm:替代式:merge 具化式:temptable (更安全)
with check option 更新数据时进行检测
create algorithm view name as (conditon) with check option;
视图不可更新部分:不是来自于基表
 SQL执行顺序    
     语法顺序:select -> distinct -> from -> join on  -> where -> group by -> having -> union-> order by   
     执行顺序: from->where ->group by ->having->select ->distinct ->union ->order by  
     数据类型    
     Java, JDBC and MySQL类型对应关系
  
     面试    
     如何实现 MySQL 的读写分离?  
     MySQL 主从复制原理的是啥?           
     MySQL 主从同步延时问题(精华)  
     Mysql的逻辑结构
  
     MVCC,redolog,undolog,binlog
    
     undoLog  
     redoLog  
     MVCC多版本并发控制  
     binlog  
     binlog和redolog的区别  
     InnoDB的行锁模式
  
     扩展    
     SQL优化    
     负向查询不能使用索引  
     前导模糊查询不能使用索引  
     字段的默认值不要为 null  
     在字段上进行计算不能命中索引  
     最左前缀问题  
     如果明确知道只有一条记录返回  
     不要让数据库帮我们做强制类型转换  
     如果需要进行 join 的字段两表的字段类型要相同
不然也不会命中索引。
    不然也不会命中索引。
 数据区分不明显的不建议创建索引  
     Mongodb    
     mongo.dml    
     database操作    
     use mydb    
     切换数据库  
     创建数据库  
     数据库为空,则在show时不显示  
     所有修改数据库操作基于mydb  
     show dbs    
     查看所有数据库  
     db    
     查看当前use的数据库  
     db.dropDatabase()    
     删除数据库  
     collection操作    
     use mydb    
     所有操作基于数据库mydb执行  
     db.collection.drop()    
     删除集合  
     document操作    
     use mydb    
     所有操作基于数据mydb执行  
     数据插入    
     db.mycol.insert({"key" : "value"})  
     db.mycol.insert(myvar)    
     myvar=({"key" : "val"})  
     数据查找    
     db.col.find()    
     查看collection下所有document  
     逻辑条件    
     等于    
     {<key>:<value>}  
     小于	    
     {<key>:{$lt:<value>}}  
     小于或等于    
     {<key>:{$lte:<value>}}  
     大于    
     {<key>:{$gt:<value>}}  
     大于或等于    
     {<key>:{$gte:<value>}}  
     不等于    
     {<key>:{$ne:<value>}}  
     大于并小于    
     {<key> : { $gt : <value>, $lt : <value>}  
     and    
     {"key1" : "value1", "key2" : "value2"}  
     key1 = value2 and key2 = value2  
     or         
    { "key" : "value", 
    $or : [
        {"key1" : "vaule1"}, {"key2" : "value2"}
    ] 
}
   key = value and ( key1 = value1 or key2 = value2)  
     类型条件    
     类型映射    
     Double : 1  
     String : 2  
     Object : 3  
     Array : 4  
     Binary data : 5  
     Undefined : 6    
     已废弃  
     Object id : 7  
     Boolean : 8  
     Date : 9  
     Null : 10  
     Regular Expression : 11  
     JavaScript : 13  
     Symbol : 14  
     JavaScript (with scope) : 15  
     32-bit integer : 16  
     Timestamp : 17  
     64-bit integer : 18  
     Min key : 255    
     使用-1  
     Max key : 127  
     db.col.find({<key> : { $type : 2}} )  
     查询数量限制    
     limit    
     limit(number)  
     指定查询返回记录数  
     skip    
     skip(number)  
     指定从记录数中跳过前number条记录  
     查询排序    
     sort({<key> : 1})    
      1- 升序排序  
     -1 - 降序排序  
     db.col.find().pretty()  
     数据更新              
    db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
     <query>    
     查询条件  
     <update>    
     更新字段及结果  
     upsert    
     可选,若不存在,true-插入;false-不插入  
     multi    
     可选,true-只更新查找到的第一条记录;false-更新所有查找到的记录  
     writeConcern    
     可选,抛出异常的级别  
    db.collection.save(
   <document>,
   {
     writeConcern: <document>
   }
)
     document完整文档数据,需要指明id进行更新  
     writeConcern    
     可选,抛出异常的级别  
     数据删除         
    db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)
     <query>    
     可选,查询条件  
     justOne    
     可选,默认为false,true-只删除一条;false-删除所有记录  
     writeConcern    
     可选,抛出异常的级别  
     聚合操作         
    MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。
管道操作是可以重复的。
   操作    
     $project    
     修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。  
     $match    
     用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。  
     $limit    
     用来限制MongoDB聚合管道返回的文档数  
     $skip    
     在聚合管道中跳过指定数量的文档,并返回余下的文档  
     $unwind    
     将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值  
     $group    
     将集合中的文档分组,可用于统计结果  
     操作    
     $sum    
     aggregate([{$group : {_id : "$<group_by_key>", <output_key> : {$sum : num}}}])  
     select sum(group_by_key) * num as output_key from col group by group_by_key  
     $avg    
     aggregate([{$group : {_id : "$<group_by_key>", <output_key> : {$avg : "$<avg_key>"}}}])  
     select group_by_key, avg(avg_key) as output_key from col group by group_by_key  
     $min    
     aggregate([{$group : {_id : "$<group_by_key>", <output_key> : {$min : "$<min_key>"}}}])  
     select group_by_key, min(min_key) as output_key from col group by group_by_key  
     $max    
     db.mycol.aggregate({$group : {_id : "$<group_by_key>", <output_key> : { $max : "$age"}}})  
     select group_by_key, min(min_key) as output_key from col group by group_by_key  
     $push    
     aggregate([{$group : {_id : "$title_var", age : { $push : "$push_key"}}}])  
     将聚合输出的avg_key转化为数组  
     $addToSet    
     aggregate([{$group : {_id : "$<group_by_key>", <output_key> : { $addToSet  : "$age"}}}])  
     在结果文档中插入值到一个数组中,但不创建副本。  
     $first    
     aggregate([{$group : { _id : "$<group_by_key>", <output_key> : {$first : "$name"}}}])  
     根据资源文档的排序获取第一个文档数据。  
     $last    
     aggregate([{$group : { _id : "$<group_by_key>", <output_key> : {$last: "$name"}}}])  
     根据资源文档的排序获取最后一个文档数据  
     $sort    
     将输入文档排序后输出  
     $geoNear    
     输出接近某一地理位置的有序文档  
     index    
     创建索引    
     db.ensureIndex({<key1> : 1, <key2> : -1}, options...)    
     排序    
     1-升序  
     2-降序  
     background    
     boolean, 执行期间阻塞其他操作    
     true-在后台创建索引,执行期间不阻塞其他操作  
     false-默认,执行期间阻塞其他操作  
     unique    
     bool, 唯一索引    
     true-唯一索引  
     false-默认,非唯一索引  
     name    
     string-索引的名称。若未指定,通过过连接索引的字段名和排序顺序生成一个索引名称  
     dropDups    
     bool,创建唯一索引时删除重复记录    
     true-删除,创建唯一索引  
     false-默认,创建非唯一索引  
     sparse    
     bool,对文档中不存在字段数据不启用索引    
     true-在索引字段中不会查询出不包含对应字段的文档  
     false-默认  
     expireAfterSeconds    
     int,设置生存时间(TTL, Time To Live)。数据在存储n秒后,自动被数据库删除  
     v    
     索引的版本号,默认的索引版本取决于mongod创建索引时运行的版本。  
     weights    
     索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。  
     default_language    
     对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语。  
     language_override    
     对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language。  
     范围    
     集合中索引不能超过64个  
     索引名的长度不能超过125个字符  
     一个复合索引最多可以有31个字段  
     不能使用索引    
     正则表达式及非操作符  
     算术运算符  
     $where 子句  
     ObjectId    
     格式    
     时间戳    
     1~4字节  
     机器标示码    
     5~7字节  
     进程ID    
     8~9字节  
     随机数    
     10~12字节  
     DBRef    
     格式    
     db    
     数据库名称  
     ref    
     集合名称  
     id    
     引用id  
     redis    
     数据结构    
     字典(散列表)  
     跳跃表是有序集合的底层实现之一。  
     redis基础知识    
     String类型操作 [key|value(string/int/float)]    
     set    
     设置置顶key的值    
     set key value  
     get    
     获取指定key的值    
     get key  
     incr    
     将key中储存的数字值增一    
     incr key  
     decr key    
     将key中储存的数字值减一    
     decr key  
     incrby    
     key 所储存的值增加给定的减量值(decrement)     
     incrby key decrement  
     decrby    
     key 所储存的值减去给定的减量值(decrement)     
     decrby key decrement  
     append    
     如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。    
     append key value  
     setnx    
     只有在 key 不存在时设置 key 的值
    
     setnx key value  
     mget    
     获取所有(一个或多个)给定 key 的值。    
     mget key [key...]  
     mset    
     同时设置一个或多个 key-value 对    
     mget key value [key value ...]  
     getset    
     将给定 key 的值设为 value ,并返回 key 的旧值(old value)。    
     getset key value  
     setex    
     将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。    
     setex key seconds value  
     strlen     
     返回 key 所储存的字符串值的长度    
     strlen key   
     del    
     删除键    
     del key  
     操作场景    
     单值缓存  
     对象缓存    
     set user:1  json数据格式    
     使用更简单  
     mset user:1:name zhangsan user:1:age 22    
     这种方式更好,当对象需要某个值的  
     分布式锁    
     setnx  
     计数器    
     微信文章阅读数量,当打开文章的incr article:readcount:1001 实现加一  
     获取直接用get article:readcount:1001(文章id)  
     spring session的实现使用该数据结构  
     分布式系统全局序列号  
     Hash类型操作
key-> key1 value(string/int/float)
key2 value(string/int/float)
key3 value(string/int/float)
key4 value(string/int/float)
    key-> key1 value(string/int/float)
key2 value(string/int/float)
key3 value(string/int/float)
key4 value(string/int/float)
 hset    
     将哈希表 key 中的字段 field 的值设为 value    
     srem key field value  
     hmset    
     同时将多个 field-value (域-值)对设置到哈希表 key 中    
     hmset key field1 value1 [field2 value2]  
     hsetnx    
     只有在字段 field 不存在时,设置哈希表字段的值    
     hsetnx key field value  
     hget    
     获取存储在哈希表中指定字段的值    
     hget key field  
     hmget    
     获取所有给定字段的值    
     hget key field1 [field2]  
     hgetall    
     获取在哈希表中指定 key 的所有字段和值    
     hgetall key  
     hvals    
     获取哈希表中所有值    
     hvals key  
     hlen    
     获取哈希表中字段的数量    
     hlen key  
     hkeys     
     获取所有哈希表中的字段    
     hkeys key  
     hdel    
     删除一个或多个哈希表字段    
     hdel key field1 [field2]   
     hexitst     
     查看哈希表 key 中,指定的字段是否存在    
     hexitst key field  
     操作场景    
     对象缓存    
     hmset person (用户id):age 20 (用户id):sex man  
     购物车           
     优点缺点  
     List类型操作
[key => value1 | 自
value2 | 左
value3 | 而
value4 | 右
]
    [key => value1 | 自
value2 | 左
value3 | 而
value4 | 右
]
 push    
     lpush    
     将一个或多个值插入到列表头部    
     lpush key value1 [value2....]  
     rpush    
     将一个或多个值插入到列表尾部    
     rpush key value1 [value2....]  
     pop    
     lpop    
     移出并获取列表的第一个元素    
     lpop key  
     rpop    
     移出并获取列表的最后一个元素    
     rpop key  
     brpop  
     lrange    
     获取列表指定范围内的元素(可用来简单分页)    
     lrange key start stop   
     llen    
     获取列表长度    
     llen key  
     lindex    
     通过索引获取列表中的元素    
     lindex key index  
     lrem    
     移除列表元素    
     lrem key count value    
     count > 0    
     从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT  
     count < 0    
     从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值  
     count = 0    
      移除表中所有与 VALUE 相等的值  
     lset key index value    
     通过索引设置列表元素的值
    
     lset key index value  
     场景应用    
     常用数据结构,栈,队列,阻塞队列  
     微博微信公众号消息流    
     小用户量  
     Set类型操作
key->[ value1
value2
value3
value4
]
    key->[ value1
value2
value3
value4
]
 sadd    
     向集合添加一个或多个成员(存在则返回0)    
     sdd key member1 [member2]   
     scard    
     获取集合的成员数    
     scard key  
     sinter    
     返回给定所有集合的交集    
     sinter key1 [key2]  
     sdiff 差集,sunion 并集  
     sismember    
     判断 member 元素是否是集合 key 的成员    
     sismember key member  
     smembers    
     返回集合中的所有成员    
     smembers key  
     srandmember    
     返回集合中一个或多个随机数    
     srandmember key [count]  
     srem    
     移除集合中一个或多个成员    
     srem key member1 [member2]  
     使用场景    
     微信小程序抽奖    
     key 活动id  
     微信微博点赞           
     微信微博关注模型           
     使用  
     Sorc Set类型操作
key-> score(10.1) value(string/int/float) rank:1
score(9.1) value(string/int/float) rank:0
score(11.2) value(string/int/float) rank:2
    key-> score(10.1) value(string/int/float) rank:1
score(9.1) value(string/int/float) rank:0
score(11.2) value(string/int/float) rank:2
 zadd    
     向有序集合添加一个或多个成员,或者更新已存在成员的分数    
     zadd key score1 member1 [score2 member2....]  
     zcard    
     获取有序集合的成员数    
     zcard key  
     zcount     
     计算在有序集合中指定区间分数的成员数    
     zcount key min max  
     zincrby    
     有序集合中对指定成员的分数加上增量 increment    
     zincrby key increment member  
     zrange    
     通过索引区间返回有序集合成指定区间内的成员    
     zrange key start stop [withscores]  
     zrank     
     返回有序集合中指定成员的索引    
     zrank key member  
     zrem    
     移除有序集合中的一个或多个成员    
     zrem key member1 [member2....]  
     zrevrange    
     返回有序集中指定区间内的成员,通过索引,分数从高到底    
     zrevrange key start stop [withscores]  
     zscore    
     返回有序集中,成员的分数值    
     zscore key member  
     sorted set 是排序的 set,去重但可以排序,写进去的时候给一个分数,自动根据分数排序。  
     Redis的应用场景    
     缓存    
     会话缓存(Session Cache)  
     全页缓存(FPC)  
     队列  
     数据存储  
     排行榜/计数器  
     发布/订阅  
     JedisPool资源池优化
  
     特性    
     键的过期时间    
     Redis 可以为每个键设置过期时间,当键过期时,会自动删除该键。 对于散列表这种容器,只能为整个键设置过期时间(整个散列表),而不能为键里面的单个元素设置过期时间。  
     数据淘汰策略    
     可以设置内存最大使用量,当内存使用量超出时,会施行数据淘汰策略。  
     发布订阅           
     持久化    
     RDB 持久化
    
     在redis.conf 有如下配置  
     原理    
     过程总结  
     用户执行SAVE或BGSAVE命令  
     注意  
     AOF 持久化    
     redis4.0优化  
     AOF 重写    
     流程  
     Redis中使用Lua脚本    
     原子性问题  
     效率问题
  
     Lua  
     使用  
     事务    
     官网  
     使用    
     当Redis连接处于MULTI请求的上下文中时,所有命令都将回复该字符串QUEUED(从Redis协议的角度来看,这是作为状态回复的发送)。当EXEC被调用时,queued命令被有计划地执行。  
     在 EXEC 之后发生的错误不是以一种特殊的方式处理的:即使某些命令在事务中失败,所有其他的命令也会被执行。
  
     Redis不支持回滚  
     事务阶段           
     乐观锁定使用check-and-set
    
     WATCH命令    
     使用WATCH来实现ZPOP
  
     注意  
     乐观锁  
     Redis事务命令
  
     pipeline    
     pipeline的思想
  
     pipelineVS脚本
           
     pipelineVS事务
           
     通过Jedis操作pipeline
  
     小总结  
     事件    
     Redis 服务器是一个事件驱动程序。  
     文件事件           
     时间事件  
     事件的调度与执行  
     概念    
     套接字  
     主从复制    
     配置  
     全量复制           
     注意  
     增量复制  
     无硬盘复制  
     哨兵机制    
     sentinel之间的相互感知  
     master的故障发现  
     配置  
     分片  
     Redis-Cluster    
     Redis的数据分区  
     HashTags  
     重定向客户端  
     分片迁移  
     Redis CAS乐观锁实现  
     使用场景    
     计数器    
     可以对 String 进行自增自减运算,从而实现计数器功能。
Redis 这种内存型数据库的读写性能非常高,很适合存储频繁读写的计数量。
    Redis 这种内存型数据库的读写性能非常高,很适合存储频繁读写的计数量。
 缓存    
     将热点数据放到内存中,设置内存的最大使用量以及淘汰策略来保证缓存的命中率。  
     查找表    
     例如 DNS 记录就很适合使用 Redis 进行存储。
查找表和缓存类似,也是利用了 Redis 快速的查找特性。但是查找表的内容不能失效,而缓存的内容可以失效,因为
缓存不作为可靠的数据来源。
    查找表和缓存类似,也是利用了 Redis 快速的查找特性。但是查找表的内容不能失效,而缓存的内容可以失效,因为
缓存不作为可靠的数据来源。
 消息队列    
     List 是一个双向链表,可以通过 lpush 和 rpop 写入和读取消息 不过最好使用 Kafka、RabbitMQ 等消息中间件。  
     会话缓存    
     可以使用 Redis 来统一存储多台应用服务器的会话信息。当应用服务器不再存储用户的会话信息,也就不再具有状态,一个用户可以请求任意一个应用服务器,从而更容易实现高可用性以及可伸缩性。  
     分布式锁    
     在分布式场景下,无法使用单机环境下的锁来对多个节点上的进程进行同步。
可以使用 Redis 自带的 SETNX 命令实现分布式锁,除此之外,还可以使用官方提供的 RedLock 分布式锁实现。
    可以使用 Redis 自带的 SETNX 命令实现分布式锁,除此之外,还可以使用官方提供的 RedLock 分布式锁实现。
 其它    
     Set 可以实现交集、并集等操作,从而实现共同好友等功能。 ZSet 可以实现有序性操作,从而实现排行榜等功能。  
     客户端使用    
     jedis  
     Redisson  
     redis实现分布式限流  
     解决方案    
     缓存雪崩
    
     简介:缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。  
     解决办法(中华石杉老师在他的视频中提到过,视频地址在最后一个问题中有提到):
事前:尽量保证整个 redis 集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策略。
事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉
事后:利用 redis 持久化机制保存的数据尽快恢复缓存
    事前:尽量保证整个 redis 集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策略。
事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉
事后:利用 redis 持久化机制保存的数据尽快恢复缓存
 缓存穿透    
     简介:一般是黑客故意去请求缓存中不存在的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。  
     解决办法: 有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法(我们采用的就是这种),如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
  
     如何解决 Redis 的并发竞争 Key 问题    
     所谓 Redis 的并发竞争 Key 的问题也就是多个系统同时对一个 key 进行操作,但是最后执行的顺序和我们期望的顺序不同,这样也就导致了结果的不同
  
     推荐一种方案:分布式锁(zookeeper 和 redis 都可以实现分布式锁)。(如果不存在 Redis 的并发竞争 Key 问题,不要使用分布式锁,这样会影响性能)  
     如何保证缓存与数据库双写时的数据一致性?
    
     不使用的方案  
     最终一致性的解决方案  
     怎么保证 redis 挂掉之后再重启数据可以进行恢复    
     redis 持久化机制  
     为什么要用 redis 而不用 map/guava 做缓存?
  
     为什么要用 redis/为什么要用缓存
    
     主要从“高性能”和“高并发”这两点来看待这个问题。  
     面试    
     redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?
    
     redis 和 memcached 有啥区别?  
     redis 的线程模型    
     图示           
     解释  
     文件事件处理器  
     为啥 redis 单线程模型也能效率这么高?  
     redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现?
    
     redis 过期策略  
     内存淘汰机制  
     手写一个 LRU 算法    
     思路2  
     比较Redis 与 Memcached  
     部分笔记           
     Redis 主从架构+原理    
     图示    
     子主题  
     redis replication 的核心机制  
     redis 主从复制的核心原理    
     图示+ 解释           
     主从复制的断点续传  
     无磁盘化复制  
     过期 key 处理  
     复制的完整流程    
     解释+图示           
     全量复制  
     增量复制  
     heartbeat  
     异步复制  
     redis 如何才能做到高可用
  
     Redis 哨兵集群实现高可用    
     哨兵的介绍  
     哨兵的核心知识  
     redis 哨兵主备切换的数据丢失问题    
     异步复制导致的数据丢失           
     脑裂导致的数据丢失           
     数据丢失问题的解决方案  
     sdown 和 odown 转换机制  
     哨兵集群的自动发现机制  
     slave 配置的自动纠正  
     slave->master 选举算  
     quorum 和 majority  
     configuration epoch  
     configuration 传播  
     redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的?
    
     redis 持久化的两种方式  
     RDB 优缺点  
     AOF 优缺点  
     RDB 和 AOF 到底该如何选择  
     Redis的持久化机制
  
     redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?    
     redis cluster 介绍    
     节点间的内部通信机制    
     集中式           
     gossip 协议    
     子主题  
     比较  
     redis cluster 的高可用与主备切换原理    
     判断节点宕机  
     从节点过滤  
     从节点选举  
     与哨兵比较  
     gossip 协议  
     ping 消息深入  
     分布式寻址算法    
     hash 算法  
     一致性 hash 算法  
     redis cluster 的 hash slot 算法           
     了解什么是 redis 的雪崩、穿透和击穿?redis 崩溃之后会怎么样?系统该如何应对这种情况?如何处理 redis 的穿透?    
     缓存雪崩           
     事中解决方案解析           
     缓存穿透           
     缓存击穿  
     如何保证缓存与数据库的双写一致性?    
     Cache Aside Pattern  
      最初级的缓存不一致问题及解决方案
  
     比较复杂的数据不一致问题分析    
     解决方案如下    
     高并发的场景下,该解决方案要注意的问题  
     redis 的并发竞争问题是什么?如何解决这个问题?了解 redis 事务的 CAS 方案吗?     
     解决    
     分布式锁           
     时间戳  
     Redis: 分布式锁的正确实现方式( Java 版 )
  
     生产环境中的 redis 是怎么部署的?    
     思路  
     为什么我们做分布式使用Redis?
  
    
 
 
 
 
  0 条评论
 下一页