Redis学习笔记1-Redis数据类型
Redis数据类型
typedef struct redisObject {
unsigned [type] ;
unsigned [encoding] ;
unsigned [lru] REDIS_LRU_BITS;
int refcount;
void *ptr;
} robj;
- type:数据类型,就是我们熟悉的string、hash、list等。
- encoding:内部编码,其实就是本文要介绍的数据结构。指的是当前这个value底层是用的什么数据结构。因为同一个数据类型底层也有多种数据结构的实现,所以这里需要指定数据结构。
- REDIS_LRU_BITS:当前对象可以保留的时长。这个我们在后面讲键的过期策略的时候讲。
- refcount:对象引用计数,用于GC。
- ptr:指针,指向以encoding的方式实现这个对象的实际地址。
Redis支持5种数据类型,它们描述如下:


Strings - 字符串
- 在Redis内部,字符串对象的编码可以是int、(动态字符串)raw或者embstr。
- Redis会根据存储的数据及用户的操作指令自动选择合适的结构:
- int:存放整数类型;
- SDS:存放浮点、字符串、字节类型;
- 如果修改后len长度将小于1M,这时分配给free的大小和len一样,例如修改过后为10字节, 那么给free也是10字节,buf实际长度变成了10 + 10 + 1 = 21byte
- 如果修改后len长度将大于等于1M,这时分配给free的长度为1M,例如修改过后为30M,那么给free是1M.buf实际长度变成了30M + 1M + 1byte

struct SDS<T> {
T capacity; // 数组容量
T len; // 数组长度
byte flags; // 特殊标识位,不理睬它
byte[] content; // 数组内容
}
- 快速获取字符串的长度
- C语言获取字符串的长度是通过遍历字符数组然后计数实现的,时间复杂度为O(n),对于SDS,由于len的存在,我们只需要读取len的值即可,时间复杂度为O(1)。
- 解决了c语言字符串拼接缓冲区溢出的问题
- 在c语言中。俩个字符串的拼接通过使用stract函数来完成,在拼接之前需要定义一个足够大的数组用来存在拼接好的字符串,如果没有分配足够长度的内存空间,那么拼接好的字符串放不进去。就会造成缓存区溢出,对于SDS,在进行拼接的时候,会首先查看free和len的情况,在拼接的时候通过len获取到字符串的长度,free获取到字符数组的剩余空间,可以做到精确的拼接操作
- 修改字符串减少内存分配次数
- 在c语言中。因为字符串的长度没有记录,所以每次在修改字符串的时候都需要重新开辟合适的内存,为什么要开辟呢??
- 因为如果不开辟新的内存大小,字符串增大会造成内存溢出,缩短会造成内存泄漏,
- 空间预分配:对字符串进行空间扩展的时候,扩展的内存比实际需要的多,这样可以减少连续执行字符串增长操作所需的内存重分配次数。
- 惰性空间释放:对字符串进行缩短操作时,程序不立即使用内存重新分配来回收缩短后多余的字节,而是使用 free 属性将这些字节的数量记录下来,等待后续使用。(当然SDS也提供了相应的API,当我们有需要时,也可以手动释放这些未使用的空间。)
- 二进制安全。
- c语言是二进制不安全的,因为c语言是以空字符来作为字符串结束的标记,像图片,音乐这些文件,内容中间可能包含空字符串,所以c语言只能存取一些文本文件,但是对于SDS而言,它是通过len的长度来记录字符串的长度的,所以SDS可以存取图片或者音乐等二进制文件。
redis 127.0.0.1:6379> SET name "hello"
OK
redis 127.0.0.1:6379> GET name
"hello"
列表 (Lists)
Redis 列表仅仅是按照插入顺序排序的字符串列表。可以添加一个元素到 Redis 列表的头部 (左边) 或者尾部 (右边)。
LPUSH 命令用于插入一个元素到列表的头部,RPUSH 命令用于插入一个元素到列表的尾部。当这两个命令操作在一个不存在的键时,将会创建一个新的列表。同样,如果一个操作会清空列表,那么该键将会从键空间 (key space) 移除。这些是非常方便的语义,因为列表命令如果使用不存在的键作为参数,就会表现得像命令运行在一个空列表上一样。
redis 127.0.0.1:6379> lpush listtest test1
(integer) 1
redis 127.0.0.1:6379> lpush listtest test2
(integer) 2
redis 127.0.0.1:6379> lpush listtest test3
(integer) 3
redis 127.0.0.1:6379> lrange listtest 0 -1 1 "test1"
2 "test2"
3 "test3"
集合 (Sets)
Redis 集合是没有顺序的字符串集合 (collection)。可以在 O(1) 的时间复杂度添加、删除和测试元素存在与否 (不管集合中有多少元素都是常量时间)。
Redis 集合具有你需要的不允许重复成员的性质。多次加入同一个元素到集合也只会有一个拷贝在其中。实际上,这意味着加入一个元素到集合中并不需要检查元素是否已存在。
Redis 集合非常有意思的是,支持很多服务器端的命令,可以在很短的时间内和已经存在的集合一起计算并集,交集和差集。
redis 127.0.0.1:6379> sadd setdemo set1
(integer) 1
redis 127.0.0.1:6379> sadd setdemo set2
(integer) 1
redis 127.0.0.1:6379> smembers setdemo 1) "set1"
2) "set2"
Hashes - 哈希值
Redis的哈希键值对的集合。 Redis的哈希值是字符串字段和字符串值之间的映射,所以它们被用来表示对象。
redis 127.0.0.1:6379> HMSET user:1 username testname password 123456
OK
redis 127.0.0.1:6379> HGETALL user:1 1) "testname"
2) "123456"
有序集合 (Sorted sets)
Redis 有序集合和 Redis 集合类似,是非重复字符串集合 (collection)。不同的是,每一个有序集合的成员都有一个关联的分数 (score),用于按照分数高低排序。尽管成员是唯一的,但是分数是可以重复的。
对有序集合我们可以通过很快速的方式添加,删除和更新元素 (在和元素数量的对数成正比的时间内)。由于元素是有序的而无需事后排序,你可以通过分数或者排名 (位置) 很快地来获取一个范围内的元素。访问有序集合的中间元素也是很快的,所以你可以使用有序集合作为一个无重复元素,快速访问你想要的一切的聪明列表:有序的元素,快速的存在性测试,快速的访问中间元素!
总之,有序集合可以在很好的性能下,做很多别的数据库无法模拟的事情。
redis 127.0.0.1:6379> zadd list 0 name1
(integer) 1
redis 127.0.0.1:6379> zadd list 0 name2
(integer) 1
redis 127.0.0.1:6379> ZRANGEBYSCORE list 0 1000 1) "name1"
2) "name2"
Redis学习笔记1-Redis数据类型的更多相关文章
- Redis学习笔记(1) Redis介绍及基础
1. Redis的特性 (1) 存储结构 Redis(Remote Dictionary Server,远程字典服务器)是以字典结构存储数据,并允许其他应用通过TCP协议读写字典中的内容.Redis支 ...
- redis学习笔记之redis简介
redis简介 Redis是一个开源的,高性能的,基于键值对的缓存与存储系统,通过设置各种键值数据类型来适应不同场景下的缓存与存储需求.同事redis的诸多高层级功能使其可以胜任消息队列,任务队列等不 ...
- StackExchange.Redis学习笔记(一) Redis的使用初探
Redis Redis将其数据库完全保存在内存中,仅使用磁盘进行持久化. 与其它键值数据存储相比,Redis有一组相对丰富的数据类型. Redis可以将数据复制到任意数量的从机中 Redis的安装 官 ...
- Redis学习笔记之Redis单机,伪集群,Sentinel主从复制的安装和配置
0x00 Redis简介 Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server). Redis的键值 ...
- Redis学习笔记(4) Redis事务、生存时间及排序
1. Redis事务 Redis中的事务(transaction)是一组命令的集合,一个事务中的命令要么都执行,要么都不执行.事务的原理是先将属于一个事务的命令发送给Redis,然后再让Redis依次 ...
- Redis学习笔记--五种数据类型的使用场景
String 1.String 常用命令: 除了get.set.incr.decr mget等操作外,Redis还提供了下面一些操作: 获取字符串长度 往字符串append内容 设置和获取字符串的某一 ...
- StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用
ConnectionMultiplexer ConnectionMultiplexer 是StackExchange.Redis的核心对象,用这个类的实例来进行Redis的一系列操作,对于一个整个应用 ...
- Redis 学习笔记-5种数据类型的基本操作
1.string类型 基本操作列表: GET 获取指定键对应的值 SET 设定键值 DEL 删除指定键对应的值(对所有数据类型都有效) > set hello world OK > get ...
- redis学习笔记(三)——redis的命令大全总结
总结了一些redis五种存储类型的常用命令以及一些通用操作命令,不是很全,是在学习的时候将学到的做了个汇总,使用的时候可以查一下. 笔记写在表格里面了,不好粘贴.......后面的直接截图了..... ...
- Redis学习笔记(2) Redis基础类型及命令之一
1. 基础命令 (1) 获取符合规则的键名列表 格式为:KEYS pattern 其中pattern表示支持通配符 # 建立一个名为bar的键 > SET bar OK # 获取Redis所有键 ...
随机推荐
- Struts2学习笔记 - HelloWorld总结
相信网上已经有很多关于struts2的HelloWorld可参考,我这里就不重复了,没个学struts2的人都会做过很多个HelloWorld,而我这里就总结一下一个简单的HelloWorld 我在一 ...
- XML学习笔记3——XSD简述
现在的语言,如果不有那么一点OO的影子,都不好意思称之为语言了.在XML的语义约束方面,DTD虽然简单,但是功能不够强大,完全是直白的描述,于是又有了替代DTD的XSD(XML Schema Defi ...
- SSH无密码登录
首先生成密钥对 ssh-keygen -t rsa cd ~/.ssh/ cat id_rsa.pub 复制你生成的公钥 登录到需要免登录的服务器 cd ~/.ssh 添加到 authorized_k ...
- 关于移动开发的一些想法和认识--Android和iOS
微信公众账号很久没更新了,发一点自己最近的想法和内容. 之前和朋友做了一个项目,现在在跟一些风投,大公司里面的几家在谈合作和投资的事宜,从这个过程中也了解到了一些信息. 关于移动平台的应用开发与游戏开 ...
- c++实现kd树
#ifndef _KD_TREE_H_ #define _KD_TREE_H_ #include <memory> #include <vector> #include < ...
- 浏览器端获取局域网IP地址,本机的MAC,以及机器名
原文链接:http://www.orlion.ga/59/ 只针对IE且客户端的IE允许AcitiveX运行 code: <html> <head> <title> ...
- CentOS yum安装Apache + PHP + Tomcat7 + MySQL
Linux平台上用得最多的web环境就是php.java和MySQL了,会搭建这个环境,就能把很多开源程序跑起来. 作为一个程序猿,虽然并不用精通运维的活,但基本的Linux环境搭建还是要掌握比较好, ...
- nodejs字符与字节之间的转换
new Buffer("Hello World").toString("base64"); /* yields SGVsbG8gV29ybGQNCg== */ ...
- 使用selenium+phantomJS实现网页爬取
有些网站反爬虫技术设计的非常好,很难采用WebClient等技术进行网页信息爬取,这时可以考虑采用selenium+phantomJS模拟浏览器(其实是真实的浏览器)的方式进行信息爬取.之前一直使用的 ...
- Javascript: 从prototype漫谈到继承(2)
本文同时也发表在我另一篇独立博客 <Javascript: 从prototype漫谈到继承(2)>(管理员请注意!这两个都是我自己的原创博客!不要踢出首页!不是转载!已经误会三次了!) 上 ...