redis使用基础(二) ——Redis数据类型

redis使用基础(二)

——Redis数据类型

(转载请附上本文链接——linhxx) 

一、概述

Redis是一种Key-Value类型的数据库,属于非关系型数据库,NoSQL的一种。Redis共有5种数据类型:字符串(string)、散列(hash)、列表(list)、集合(set)、有序集合(zset)。

1、通配符

Redis支持部分通配符,包括?、*、[]、\x,和正则表达式一致,?表示匹配0或1个,*匹配任意个,[]匹配框内的任意一个内容,\x转义,例如\?表示匹配?。

2、获取键 KEYS

当要获取键值时,可以用KEYS * 获取所有的键,也可以用KEYS a*获取所有a开头的键。该方法会遍历所有的键,影响性能,不建议使用。

3、判断键是否存在 EXISTS

如 EXISTS test ,判断test键是否存在,存在返回整数1,不存在返回0。

4、删除键 DEL

DEL test,如果test存在,则删除,返回1;如果不存在,则返回0。

该命令不支持通配符,因此要删除多个键时,可以在linux命令行下,通过管道符的方式获取与删除,例如 redis-cli KEYS “user*” | xargs redis-cli DEL。其中xargs是将管道符前面的命令的执行结果作为参数传给xargs后面的命令。也可以使用redis-cli DEL “user*”的方式删除。

5、获取键的数据类型 TYPE

TYPE test 可以获取test键的数据类型,返回值即上述五种数据类型中的一种。

6、原子性

redis的所有命令都是原子性的,例如自增命令incr,当并发调用incr对某个key的value设置自增,只会增加一次。其他命令也是如此。

7、存储方式

redis存储元素都是用hash的方式存储,将每个键用hash进行计算后,存储在hash(key)的位置,每个位置即为一个bucket。当hash(key1)和hash(key2)相同时,会采用链表的方式,将key1和key2都存储在同一个bucket的结果中,bucket根路径指向key1,key1再指向key2。

二、字符串类型(String)

字符串是redis的最基本数据类型,其他的数据类型可以看作是各种方式把字符串集合在一起的类型。字符串的一个键允许存储512MB的值,因此可以存放绝大多数的内容。

1、使用方式

赋值:SET key value,给key赋值为value。获取:GET key。当get不存在的键,会返回(nil)。

用PHP连接redis,并接收命令行的参数,使用set和get操作redis,如下:

<?php

$redis = new Redis();

$redis->pconnect(‘127.0.0.1‘, 6379);

$name = $argv[1];

$redis->set(‘test:1:name‘, $name);

echo $redis->get(‘test:1:name‘);

echo PHP_EOL;

2、递增数字

INCR key,当key对于的value是数字时自增1,否则会报error。当key没有设定value时,默认是0,所以执行INCR会变成1。

redis中的操作都是都是原子操作,因此当有多个客户端并发对某个键使用INCR时,最后的结果也仅加1次,不会出现多次加的情况。

3、实现文章访问量统计

给每篇文章设置一个名字,名字为article:id:page.view,表示文章的id中某个页面的访问量。

1)id可以选用文章在数据库(如mysql)中的id。如果文章不用数据库存储,而用redis,则也可以自制自增的id。自增id的设置方法为,新建一个字段为articles:count,初始值为1,每有一篇文章要计算时,就把这个值INCR,返回的结果就是文章的id。

2)当要用redis存储文章标题、内容等信息时,需要将文章的各类内容存储在数组中,通过PHP序列化后进行存储,取出则同样是反序列化后使用。

4、字符串相关其他命令

1)增加指定整数:INCRBY、自减一:DECR、减少指定整数:DECRBY、增加浮点数:INCRBYFLOAT。

2)尾部追加内容:APPEND、获取串长度:STRLEN。

3)同时获取/设置多个值:MGET key1 key2…. ,MSET key1 value1 key2 value2…

4)位操作:SETBIT i val、GETBIT,获取或者操作变量的第i位,由于是二进制操作,因此值只有0或1。此方法用于获取或设置数量较小的内容时,效率极高,如性别、状态等,只有几个数字的可能的情况,用此方法比较好。

三、散列类型(Hash)

散列存储了字段和字段值的映射,即每个key对应的值仍是field =>value的形式,每个key可以对应多个field =>value形式的内容,最多支持232-1。但是字段值只能是string,不能是其他类型,即不支持嵌套。

redis的每种类型都只支持字符串,不支持类型的嵌套。

1、设置与获取

1)单次单个:HGET key field、HSET key field value

2)单次多个:HMGET key field1 field2… 、HMSET key field1 value1 field2 value2…

3)获取某个key的全部:HGETALL,返回的是field1、value1、field2、value2…,不是很直观,但是很多语言都已经将结果封装。

在PHP中,$redis->hgetall(key)会返回key对应的field=>value的一个二维数组。

但是,当字段数量非常多时,由于redis是单线程的,hgetall要遍历某个key所有的field和value,因此会发生阻塞,甚至可能是服务器宕机。

因此,可以将key和field另外进行存储。

2、判断

1)field是否存在:HEXISTS key field

2)field不存在时赋值:HSETNX key field value,由于具有原子性,当多个hsetnx命令同时发出时,只会执行第一个命令,后面的命令由于已经有值了所以不会再次设置。

3)增加数字:HINCRBY key field increment

4)删除field:HDEL key field1 field2…

3、存储文章数据

当使用序列化将文章的标题、内容等存储,反序列化取出时,存在的问题由于反序列化以及修改的操作不是在redis执行,不是原子性,因此并发情况下有可能发生问题。另外,反序列化则如果只修改标题也需要取出全部内容,浪费资源。

使用散列可以很好解决此问题,存储的方法是关键字设置为article:id,然后里面的field分别是title、content等,要修改也可以用HSET进行修改。

4、其他命令

1)部分获取:只获取field——HKEYS key,只获取value——HVALS key,获取field的数量:HLEN key

四、列表类型(List)

列表类型可以存储一个有序的字符串列表,其存储方式是双向链表的数据结构,即可以从两头增加、删除内容。因此,redis列表的操作方式和数据结构的链表非常像,大部分情况下是用push、pop进行操作。

列表的优势很明显,两头的数据增加、删除很快,但是缺点也比较明显,就是当需要获取中间的第i个元素的时候,则需要从头(或尾)逐个进行遍历。但是,遍历的过程中如果还有并发的增加元素,则可以直接从另一头增加,不需要将列表锁起来,这也是其优势。

列表类型的元素在如新鲜事(即通常只会查看前n条记录,且n较小)等场景速度非常快。因为即使原始数据非常多,但是列表可以从另一头取数据,且当有新内容时也是直接加入到尾部,因此非常的便利且高效。

1、设置、获取数据

1)设置:LPUSH key value1 value2…、RPUSH key value value2…分别是从表的左、右两头塞入新的数据。

2)弹出:LPOP key、RPOP key分别是从左右两头弹出第一个数据。

3)获取元素个数:LLEN key,不存在返回0,redis的获取类似数据库的count,但是非常高效,时间复杂度是O(1),即读取现成值,不用遍历。

4)获取列表片段:LRANGE key start stop,从key左边第start个获取到第stop个元素,获取的过程不会删除元素,和pop命令不一样。另外,key或stop的值为负数,则表示从右边计算。如-1,-10表示从右边第一个到第十个。

5)删除列表指定值:LREM key count value,将key的值为value的元素删除count个,count为正数从左数,负数从右数,0则删除全部。

2、实例

1)新鲜事存取

设定key为usernews:userid,每当有新鲜事时,则用lpush usernews:userid value的方式将值从左边插入,拉取最近10条新鲜事则采用lrange usernews:userid 1 10的方式。

2)文章id存取

当要获取最新10个文章时,如果用前面说的自增count的方式获取最大的10个id,存在的问题是如果中间有删除的文章,则id不是连续的,此时的获取如果还要加上判断,效率很低。

而将id存在列表内,当删除文章时使用lrem相应的把列表的值删除,获取最新10个文章则使用lrange的方式,更为高效。

3、其他命令

1)数组方式使用列表:LINDEX key index 获取列表key的第index个元素,LSET key index value相应的赋值,index是负数时从右边开始计算。

2)批量删除:LTRIM key start end,将索引小于start和大于end的值全部删除,仅保留start至end的元素。删除之后列表的索引会变化,此时在最左边的元素下标将变成0,以此类推。

3)向列表中间插入元素:LINSERT key BEFORE|AFTER index value,会在key的下标为index的元素的前面|后面插入值。

4)原子性的将列表从一个元素移到另一个元素:RPOPLPUSH key1 key2,把key1的最右边的元素移除,插入到key2的最左边。当redis用作消息队列系统时,如果需要经过多个队列,则此操作很重要,可以将监控到的队列进行转移,完成一个转移到下一个队列。

五、集合类型(Set)

集合是一组没有顺序的元素,其中每个值都不相同,一个集合最多可以存储232-1个字符串。集合和列表很相似,但是区别在于集合是无序的、每个元素值唯一的,列表是有序的、元素值不唯一的。

1、设置与获取

1)增加/删除元素:SADD key member1 member2…,SREM key member1 member2…,返回的是成功的个数,sadd的member如果有重复的则重复的那一个不会插入,srem如果删除不存在的member也不会去删除。

2)获取全部:SMEMBERS key、判断是否存在:SISMEMBER key member

3)集合间运算:SDIFF key1 key2…,SINTER key1 key2…,SUNION key1 key2…分别表示若干个集合的差集、交集和并集。返回集合运算的结果。

命令SDIFFSTORE resultkey key1 key2…可以将若干键的差集计算后存在resultkey里面,同理还有SINTERSTORE、SUNIONSTORE。

2、实例

1)要存储不能重名的字段,如用户名,当需要批量导入的时候,就可以使用此操作,因为重名的情况下sadd key会返回0,表示插入失败,则不允许进行导入。

2)博客系统给文章加标签,每个文章可以有多个标签,但是标签之间不能重复,则可以使用集合的方式。

3、其他命令

1)获取元素个数:SCARD key

2)获取集合随机一个元素:SRANDMEMBER key count,count默认是1,随机获取key集合中的count个元素,count为正数时获取的值互不相同,count为负数时获取的值可以相同。

由于redis存储key是采用hash的方式,因此这个随机的随机性不是那么好,当若干key的hash结果一样时,会存在同一个bucket里面,导致随机到的可能性降低。

3)弹出元素:SPOP key,由于集合无序,因此会随机弹出一个元素。

六、有序集合类型(Sorted Set)

此数据类型,在集合的基础上,为集合的每个元素关联一个分数,使得集合的结果可以进行排序。有序集合的每个元素仍要求不一样,但分数可以一样。

1、有序集合和列表的异同

1)相同之处

二者都有序,且都可以获取某一范围内的元素。

2)不同之处

a. 列表是双向链表,因此获取两边很快而获取中间很慢,很少用列表获取中间值;有序集合用的是散列表(hash)和跳跃表(skip list)实现,获取中间元素的速度比列表快,速度为O(logn)。

b. 列表不能简单的调整元素的位置,有序集合可以通过调整分数直接调整元素的位置。

c. 有序集合比较耗内存。

2、基本操作

1)增加元素:ZADD key score1 member1 score2 member2…,当对同一个member进行add时,会覆盖上一次的score。score支持浮点数,且+inf和-inf表示正负无穷大。

2)获取元素分数:ZGET key member

3)获取排序位置为某个范围的元素:ZRANGE key start stop [withscores],获取key的分数从start至stop的全部元素,从小到大排序,获取的结果是若干个member的有序集合;当加上withscores时,获取的是member1 score1 member2 score2这样的集合。

其时间复杂度是O(log n+m),n是有序集合元素个数,m是返回的元素个数。

当两个score一样,redis将member按照0<9<A<Z<a<z的方式进行排序,中文和其他符号按照编码方式进行排序。

ZREVRANGE将结果按照score从大到小排列。

4)获取score为某个范围的元素:ZRANGEBYSCORE key min max [withscores] [LIMIT offset count],此获取的是包含min和max的,如果希望不包含某边,例如不含最小值,则在min前面加上英文括号(,另外,+-inf也可以用上,表示只比较大于或者小于。

5)增加某个元素的分数:ZINCRBY key increment member,如果member不存在,会赋值为0后再进行增加的操作。

3、实例

1)此功能可以实现按点击量对文章进行排序、实现对学生成绩排序等。

2)对时间排序也可以使用有序集合,只要将时间都转成unix时间戳,然后用时间戳当作score即可。

4、其他操作

1)元素数量:ZCARD key、指定分数范围内元素数量:ZCOUNT key min max,其中min和max的特性与ZRANGEBYSCORE相同。

2)删除元素:ZREM key member1 member2… 、按排名范围删除:ZREMRANGEBYRANK key start stop、按分数范围删除:ZREMRANGEBYSCORE key min max

3)获取元素排名:从小到大——ZRANK key member,从大到小——ZREVRANK key member

4)有序集合交集:ZINTERSTORE resultkey numkeys key1 key2… [WEIGHTS weight1 weight2…] [AGGREGATE SUM|MIN|MAX]

此方法将多个key的交集存在resultkey中,返回resultkey元素个数。

返回集中,相同元素由于被合并,其分数要变化,变化的分数由AGGREGATE确定,默认是sum,即键分数是每个参与计算的键的分数和,min和max则是最小、最大值。

当设置了weight,则每个分数会被乘以相应的weight后进行比较。

5)ZUNIONSTORE,类似ZINTERSTORE,是求两个有序集合的并集。

——written by linhxx

更多最新文章,欢迎关注微信公众号“决胜机器学习”,或扫描右边二维码。

原文地址:https://www.cnblogs.com/linhxx/p/8412884.html

时间: 2024-07-29 05:49:14

redis使用基础(二) ——Redis数据类型的相关文章

Redis学习基础二

回顾:上一基础中已了解 ( 什么是redis .redis 的三大特点.安装,和数据配置) 接下来浅尝Redis的数据类型,时间煮雨...... 一.Redis数据类型 redis支持五中数据类型(string字符串.hash哈希.list列表.set集合.zset有序集合) (一)String 字符串 1.string 是redis 中最基本的类型,可以理解成与memcached一模一样的类型,一个key对应一个value 2.string 类型是二进制安全的,意思是redis 的string

Redis系列(二)—— 数据类型及其使用

Redis数据类型及其使用 参考:http://www.cnblogs.com/jackluo/p/3173436.html Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 并结合实际,以简单博客(用户/关注)为模型,进行使用场景探讨. String(字符串) string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value. string类型是

Redis 详解 (二) redis的配置文件介绍

目录 1.开头说明 2.INCLUDES 3.MODULES 4.NETWORK 5.GENERAL 6.SNAPSHOTTING 7.REPLICATION 8.SECURITY 9.CLIENTS 10.MEMORY MANAGEMENT 11.APPEND ONLY MODE 12.LUA SCRIPTING 13.REDIS CLUSTER 上一篇博客我们介绍了如何安装Redis,在Redis的解压目录下有个很重要的配置文件 redis.conf (/opt/redis-4.0.9目录下

Redis学习系列二之.Net开发环境搭建及基础数据结构String字符串

一.简介 Redis有5种基本数据结构,分别是string.list(列表).hash(字典).set(集合).zset(有序集合),这是必须掌握的5种基本数据结构.注意Redis作为一个键值对缓存系统,其所有的数据结构,都以唯一的key(字符串)作为名称,然后通过key来获取对应的数据. 二..Net开发环境搭建 这个版本,暂时不考虑并发问题,后续的文章会说!第一步:安装StackExchange.Redis包,我用的是2.0.519版本的. 第二步:编写代码,采用扩展方法的链式编程模式+as

redis学习(二)——String数据类型

一.概述 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等.在Redis中字符串类型的Value最多可以容纳的数据长度是512M. 二.相关命令 1.赋值命令 命令原型:SET key value 时间复杂度:O(1) 命令描述:设定该Key持有指定的字符串Value,如果该Key已经存在,则覆盖其原有值. 返回值:总是返回"OK". 2.取值命令 命令原型:GET key

Redis资料汇总(二) 数据类型

1. keys redis本质上一个key-value db,所以我们首先来看看他的key.首先key也是字符串类型,但是key中不能包括边界字符 由于key不是binary safe的字符串,所以像"my key"和"mykey\n"这样包含空格和换行的key是不允许的 顺便说一下在redis内部并不限制使用binary字符,这是redis协议限制的."\r\n"在协议格式中会作为特殊字符. redis 1.2以后的协议中部分命令已经开始使用新

Redis学习笔记(三) Redis API与常用数据类型简介

一.Redis中常用数据类型 由上一篇博客可知,Redis目前提供五种数据类型:string(字符串).list(链表).Hash(哈希).set(集合)及zset(sorted set)  (有序集合).现在,我们一一来看看这五种数据类型的基本使用方法.在开始介绍之前,我们先使用刚刚引入的Redis API建立一个Redis客户端对象,有了这个客户端对象,我们才能和Redis服务端进行通信,且看下面的一行代码.我们需要事先指定好Redis服务端的IP地址和端口号,然后根据这两个信息建立一个Re

Redis学习基础一

今天开始系统的学习redis基础知识,以往只是看redis的手册,貌似总是记不住.这次尝试手记笔记,使得印象更加深刻,从零开始学习.看是很慢,其实很快哟. 一.什么是Redis 至于什么是redis, 官网上这样给出:redis 是Salvatore Sanfilippo 这个人写的 Key-value 存储系统.Redis是一个开源的使用 C语言编写的,并且准守 BSD协议 属于Key-value 数据库.也被称为数据结构服务器,因为 value 可以是 (字符串,哈希,列表,集合,有序集合)

redis使用基础(四) ——Redis排序与消息通知

redis使用基础(四) --Redis排序与消息通知 (转载请附上本文链接--linhxx) 一.排序 1.命令 SORT key [ALPHA] [DESC] [LIMIT start end],对列表.集合和有序集合进行排序,当加上alpha参数后,则可以按照字典顺序排序,加上desc则倒序排序,加上limit则支持分页. 2.关键参数 by参数:by key:*->val,可以指定排序的标准,可以自己传入一个list,也可以指定某个列进行排序. get参数:get key:*->val