Redis数据类型和操作

本例为redis单实例模式

基本数据类型

String --最常用的数据类型

  • String 除了保存字符串之外,可保存很多特殊类型,序列化之后可存图片、对象、数值

Hash --key value

  • Map类型

List --链表

  • 以链表形式存储String

Set --集合

  • 以集合形式存储String

ZSet --有序集合

  • 以score大小顺序排列

所有操作命令说明可通过 redis-cli 查看,如使用help @string 命令可以查看所有String相关操作命令。使用 help set 查看set命令用法和说明

字符串基本操作

  • set get
  > set key1 value1
  OK
  > get key1
  "value1"
  • setnx key存在时不进行设置。返回0
> setnx key1 valuenx
(integer)0
> setnx key2 value2
(integer)1
  • setex 存值时设置过期时间
> setex key3 60 value3  //60秒后过期
(integer)1
> ttl key3 //查看剩余时间
(integer)40
> get key3 //60秒后再查看
(nil) //空
  • setnx 可作为分布式锁使用。对指定的key,线程获取锁时进行setnx 如果能设置成功,即获得锁。操作结束删除。如果未结束。其他线程setnx将失败。
  • setrange替换字符串
  > set email maven163@163.com
  > setrange email 8 $ //把第八位替换成$ 符号(从0开始)
  > get email
  "maven163$163.com"
  • mset or msetnx 多值存入
> FLUSHALL //删除所有key
OK
> mset key1 value1 key2 value2 key3 value3
OK
> keys *
1) "key1"
2) "key2"
3) "key3"
  • mget 多值获取
> mget key1 key2 key3
1) "value1"
2) "value2"
3) "value3"
  • getset 获取旧值存入新值
> getset key1 newvalue
"value1"
> get key1
"newvalue"
  • incr、decr 数字类型自增自减 +1 -1
> set key1 100  //注意,如果是其他非数字类型,自增将报错
OK
> incr key1
"101"
> decr key1
"100"
  • incrby、decrby 自定义的数字增减 。小数增加 incrbyfloat 但是减小数没有decrbyfloat 只能incrbyfloat key -1.5 用负数
> incrby key1 2
"102"
> decrby key1 3
"99"
  • append 追加字符串 append key1 world
  • strlen 获取字符串长度 strlen key1

Hash类型操作

redis最常用的类型,一个hash id下对应多个key value,更节省内存容量。适合存储对象。

  • hset
 > hset key1 name zhangsan
(integer)1
> hset key1 age 18
(integer)1

这样就加入了一个{"name":"zhangsan","age":1}的对象。他们对应的key为“key1”

  • hget
> hget key1 name
"zhangsan"
> hget key1 age
"18"
  • hmset、hmget 多参数值传入和获取
> hmset key1 sex nan addr hangzhou
OK
> hmget key1 name sex age addr
1) "zhangsan"
2) "nan"
3) "18"
4) "hangzhou"
  • hsetnx key下已存在的参数不进行更新
> hsetnx key1 name lisi
(integer)0 //返回0.表示没有数据被改变
> hget key1 name 
"zhangsan" //再次取出name,还是zhangsan
  • hincrby 加(减)法操作
    hincrbyfloat 浮点型操作
> hincrby key1 age 2 //加2
(integer)20
> hincrby key1 age -2 //减2
(integer)18
  • hexists 是否存在
> hexists key1 name
(integer)1
> hexists key1 weight
(integer)0
  • hlen 对象中的键值数量
> hlen key1
(integer)4
  • hdel 删除指定的field
    hkeys 显示对象中的所有field的key
> hkeys key1 //删除前的所有field
1) "name"
2) "age"
3) "sex"
4) "addr"
> hdel key1 addr //删除
(integer)1
> hkeys key1  //删除后的field
1) "name"
2) "age"
3) "sex"
  • hvals 显示对象中所有field的value
> hvals key1
1) "zhangsan"
2) "20.5"
3) "nan"
  • hgetall 获取所有field的key value
> hgetall key1
1) "name"
2) "zhangsan"
3) "age"
4) "20.5"
5) "sex"
6) "nan"

List类型操作

存储有序的字符串链表 ,可以往两端添加删除元素,故既可以当堆栈使用,也可以当队列使用。堆栈(先进后出):lpush+lpop rpush+rpop ;队列(先进先出)lpush+rpop rpush+lpop
由于Redis的list的数据类型特点及内存库高效率的特性,可被当成消息队列(MQ)使用。

  • lpush 从头部加入元素,先进后出。如果组合使用rpop 也可实现先进先出,所以是相对的。
> lpush list1 hello
(integer) 1
> lpush list1 world
(integer) 2
> lrange list1 0 -1 //表示从头取到尾。发现是先进后出的
1) "world"
2) "hello"
> lpop list1
"world"  //先取到了后加入的"world"
>lpop list1
"hello"

其他r和l的组合都是如上测试法。

  • lrange 从左至右查看list。没有rrange方法
> rpush list1 hello
(integer) 1
> rpush list1 world
(integer) 2
> lrange list1 0 -1 //查看list1中所有元素
1) "hello"
2) "world"
> lrange list1 -2 -1 //list中元素下标 是以-3 -2 -1 依次排列的
1) "hello"
2) "world"
  • linsert 插入操作,可指定元素之前(before)或之后(after)插入
> linsert list1 before world my //在world之前加入my
(integer) 3
> lrange list1 0 -1
1) "hello"
2) "my"
3) "world"
  • lset 替换指定下标元素
  • lrm 删除元素。并返回删除的个数
>lrm list1 0 a //删除所有a元素
>lrm list1 2 a //删除至多两个a元素
>lrm list1 -2 a //从尾部至多两个a元素
  • ltrim 截取队列
> ltrim list1 0 1 //保留第一个和第二个。
  • lpop rpop 从头部、尾部删除数据,并返回被删除的数据
  • rpoplpush 删除和加入操作可合为一个,把pop出来的元素加入到新队列中。是一个原子化的操作,比单独使用更安全。使用场景:1.同一队列可实现头尾互换,全部换一遍相当于一次遍历。比如存储的是一列ip地址,想进行一个是否都可用的判断。2.从一个队列pop出来后push到另一个队列中,pop出来的元素可能相关事务失败了,这时可去另外一个队列中找回原来那个元素进行追溯。
> lrange list1 0 -1
1) "a"
2) "my"
> rpoplpush list1 list1 // 可以指定不同队列
"my"
> lrange list1 0 -1 //rpoplpush操作之后。头尾进行了互换
1) "my"
2) "a"
  • lindex 返回index位置上的元素
> lindex list1 0
"my"
  • llen 返回元素个数
> llen list1
(integer) 2

Set类型操作

String类型的无序的集合 和list区别:list有序,set无序,list可重复,set不可重复,redis的set通过hashtable实现。使用场景:统计,如存储访问者ip就可统计访问量(scard)。交集(sinter)查看共同好友、共同关注者。

  • sadd 添加元素
> sadd set1 aaa bbb ccc //可往set1中连续添加元素
(integer) 3
> sadd set2 aaa bbb bbb //出现重复的元素,会忽略掉已存在的
(integer) 2
  • smembers 查看set中的元素
> SMEMBERS set2
1) "bbb"
2) "aaa"
  • srem 删除元素
> srem set1 aaa
(integer) 1
  • spop 随机删除并返回删除的元素
  • sinter、sunion 取集合的交集 、并集
> sinter set1 set2
1) "bbb"
> sunion set1 set2
1) "ccc"
2) "aaa"
3) "bbb"
  • sdiff 差集
> SMEMBERS set1
1) "ccc"
2) "bbb"
> SMEMBERS set2
1) "bbb"
2) "aaa"
> sdiff set1 set2 //sdiff是以前一个(set1)为基准,减去后面一个(set2)中存在的元素。
1) "ccc"
> sdiff set2 set1
1) "aaa"
  • sdiffstore、sinterstore、sunionstore 将返回结果存储到新的集合中
> sdiffstore setdiff set1 set2
(integer) 1
> SMEMBERS setdiff 
1) "ccc"            //sdiffstore之后的内容
> sinterstore setinter set1 set2
(integer) 1
> SMEMBERS setinter
1) "bbb"          //sinterstore之后的内容
> sunionstore setunion set1 set2
(integer) 3
> SMEMBERS setunion
1) "ccc"
2) "aaa"
3) "bbb"        //sunionstore之后的内容
  • smove 从一个set中移除元素添加到另外一个set中,实质是srem 和 sadd的原子化操作
> smove set1 set2 ccc
(integer) 1
> SMEMBERS set1
1) "bbb"
> SMEMBERS set2
1) "ccc"
2) "bbb"
3) "aaa"
  • scard、smembers、sismember 查看元素个数、查看所有元素、是否存在某个元素
> scard set2
(integer) 3
> smembers set2
1) "ccc"
2) "bbb"
3) "aaa"
> sismember set2 aaa
(integer) 1
  • srandmember 随机取出一个元素,但不删除

ZSET 有序集合

使用hash表和skiplist实现。插入和查找更快。按指定的score大小来排序。可在需要分数名次排序的场景使用。比如考试名次、网站排名(为搜索提供排序)、时间戳当成score(有时间顺序的数据)、用户个性化兴趣标签

  • zadd 比set的插入多了一个分数。以这个分数的大小来排序
> zadd set1 1 aaa 2 bbb 3 ccc  //1分aaa 2分bbb 3分ccc
(integer) 3
> ZRANGE set1 0 -1 //查看所有元素
1) "aaa"
2) "bbb"
3) "ccc"
> ZRANGE set1 0 -1 withscores //查看所有元素,并带上分数
1) "aaa"
2) "1"
3) "bbb"
4) "2"
5) "ccc"
6) "3"
  • 对已存在元素zadd可修改顺序
> zadd set1 0 ccc  //ccc元素分数改为0
(integer) 0
> ZRANGE set1 0 -1
1) "ccc"   //ccc已排到最前
2) "aaa"
3) "bbb"
  • zadd set1 nx 20 ddd 不更新已存在的元素
  • zadd set1 xx 20 ddd 不更新不存在的元素
  • zadd set1 ch 30 aaa 返回有变化的元素个数 不加ch返回都是0
 > zadd set1 ch 30 aaa
(integer) 1
  • zadd set1 incr 5 aaa 对aaa加5分
> zadd set1 incr 5 aaa
"35"
  • zrem 删除元素
> zrem set1 aaa
(integer) 1
> ZRANGE set1 0 -1
1) "ccc"
2) "bbb"
  • zrangebyscore 指定分数区间查找元素
> zrangebyscore set1 0 100
1) "ccc"
2) "bbb"
> zrangebyscore set1 0 0
1) "ccc"
  • zrevrange set1 0 -1 withscores倒序查找元素
> zrange set1 0 -1 withscores //默认正序
1) "ccc"
2) "0"
3) "bbb"
4) "2"
> zrevrange set1 0 -1 withscores //倒序
1) "bbb"
2) "2"
3) "ccc"
4) "0"
  • zrank 显示一个元素的排名,非显示分数,而是从0开始的排名
> zrank set1 bbb
(integer) 1
> zrank set1 ccc
(integer) 0
  • zremrangebyrank 按排名顺序删除元素
> ZREMRANGEBYRANK set1 0 1 //删除前两位
(integer) 2
  • zremrangebyscore 按分数序号删除
> zadd set1 5 aaa 6 bbb 7 ccc //先加三个
(integer) 3
> zremrangebyscore set1 0 6 //删除分数0到6的
(integer) 2
> zrange set1 0 -1 
1) "ccc"        //只留下了ccc 分数 5和6的已经被删除
  • zcard 返回集合里所有元素个数
> zcard set1
(integer) 1
  • zcount set1 5 10 给定分数区间内的元素个数

优化技巧和配置

  • redis为了节省内存。在数量少的时候,Hash类型在redis内部会转化为ziplist。而不是hashmap。redis.conf下默认hash-max配置为 512。可配置为默认的两倍
hash-max-ziplist-entries 1024
hash-max-ziplist-value 128
  • 如需要存储一千万个以上用户数据时,一条hash key内存储多个用户可节省更多空间。
>hset 10000 001 userinfo
>hset 10000 002 userinfo

如上。一个hashkey里面可以存999个用户

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容