为什么要使用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篇