为什么要使用redis

因为mysql是存储在硬盘上的,硬盘的读取效率低,redis是处于内存上,mysql之间表的关系错综复杂,redis是关系简单的key-value数据库,表面看起来像是一个map

 

使用

因为是key-value,所以就是一个key对应一个值,string这里是一个字符串

基本命令

 

 由这张图就能看出

命令含义

set key string :     给一个key,设置一个string的值

get key :         得到key对应的值,如果没有设置为nil

mset key string ... :   设置多个key string

mget key .... :         得到多个key的值

strlen    :         计算长度是多少

append  :        在值后面追加

 

多指令操作和单指令操作场景

区别:设置或者得到都其实是一条指令,首先需要把指令发送到redis,redis计算,redis返回,总共消耗时间的有这三步

多指令:多指令的话因为同时发送,同时返回,这两步的时间就会减少很多,时间上优势,缺陷是如果同时发送的过多,这条指令的时间就会偏长,就会阻塞

单指令:时间上相对多指令长一些,但是好在一条一条返回能够慢慢的得到数据,不会出现完全得不到数据的情况

 

mysql分表场景

当存储数据量比较大的时候,会采用分表来加速查询,分表因为分成了多张表,外面一层能够定位到是哪张表,所以相当于是加了层索引

这个数据的主键就不能保证唯一了,因为他只是保证当前表唯一,不能保证和其他表不相同,这个时候就可以使用redis的命令,增加或者减少一个数值

 

 

 incr   :  增加数值

decr   :减数值

 

 

这三个信息是人们比较关注的点,高访问量

 

 

使用json存储的话读取会比较快,但是如果我只是改变其中单个的话就还是分开好了,因为redis是单线程的

 

 

 

 这样能够更好的保证key的唯一性

 

 

原理

因为redis是用c写的,所以string的内部结构也符合c

 

 

 名称为sdshdr的结构体,有free len buf三个成员

free : 还能够使用的空间

len :已使用的字符串长度

buf:一个char数组,用来保存字符串

 

为什么不是直接用数组而要用一层结构体包装的目的

1.常数取字符串长度,可以通过len直接拿到字符串长度

2.杜绝缓冲区溢出:如果添加字符串进char数组的话,避免溢出,可以先判断free大小,如果不够可以去扩容

3.减少内存重新分配的次数

  3.1.扩容策略:

    4.1  修改之后的长度<1MB :如果不够,会变成 (本来总空间+新加长度)*2+1(\0)的字节空间

    4.2  修改之后>=1MB  : 会增加1MB

  3.2.释放策略:如果进行缩短字符串,不会自动去释放掉多出的空间,而是提供API让用户自己去选择时间去释放

4.二进制安全:使用len来判断结束,并不是用\0,目的是因为Ascil码的缘故,其实遇到0就是真正的结束了,所以存储二进制数据的时候就会出现问题,所以使用len来判断

5.兼容C字符串:加上\0的目的就是兼容C的字符串函数,这样能够方便使用

    

 

目录

NoSql数据库redis之string篇