6人参与 • 2026-03-18 • Redis
(1) redis中,key都是字符串,value可以是各种类型。存放键值对,使用set keyname keyvalue;redis不区分大小写,也不需要
注意单双引号的问题,写不写都可以。
(2) set keyname value [ex seconds | px milliseconds] [nx|xx],ex指定超时时间以秒为单位,px以毫秒为单位;nx表示有设置keyname则不插入,xx表示只在keyname存在时修改value
(3) mset keyname value [keyname value] 设置多组键值对
(4) setnx setex psetex即设置时就加上选项,setnx表示只在不存在时设置,setex表示设置过期时间,秒为单位,psetex也是设置过期时间,但是以毫秒为单位
(1) redis中,获取键值对使用get,通过get keyname的方式获取
(2) mget,获取多组键值对
?表示任意一个字符,如key可由ke?检索出来*表示任意多个字符,使用其实和linux检索文件名时使用一样[abcdefg]表示从中括号中的选项中匹配任意一个[^e]表示不匹配e[a-c]表示范围匹配但是实际开发中,几乎不会使用(禁止)*的方式,因为会检索整个redis中的所有key,而redis又是单线程的,
所以可能会导致该线程阻塞在检索的过程中,导致大量请求从redis的缓存数据中取不出结果,都去向数据库发出请求,
导致数据库压力过大挂掉
查看一个键值对(多个)是否存在,使用exists keyname1 keyname2 ...
关于同时支持多个keyname的问题:redis是客户端、服务器形式的应用,所以对于服务器的请求操作都要通过网络进行,这意味着经由网络传输、各个层级之间协议的封装与解包,都是较大的时间消耗,所以redis支持一次请求携带多个key值去操作,以节省传输的时间(网络的速度一般网卡和硬盘速度对比还是网络慢很多的
使用del删除键值对,del keyname1 keyname2
expire keyname secondspexpire keyname microsecondsttl(time to live) + keyname,查看剩余存活时间,如果没有设置过期时间,那么就返回-1;如果查无此key,首先搭建一个环形队列,其中每个节点都指向一个链表的头节点,从头节点往后的每个节点都代表过期时间处在
某个范围的事件,让检测线程每个一段事件往后走一个检查该格中是否有需要处理的事件(结合周期和环形队列
循环的概念,不难得出一个链表中可能有多种时间),但是这种方式对于时间粒度和环形队列的长度的设计
都有很高的要求
使用type + keyname查看key对应的value的类型
很多类型,redis承诺对外是某种类型,但是具体实现的时候可能采用了其他的方式
(1) raw,就是字符串的形式存储
(2) int,如果字符串中存储的是数字的话,就直接作为数字存储
(3) embstr,对于短字符串做出优化的存储方式,也负责存储小数,这也意味着性能的损失,因为整数通过int的方式存储直接就可以
比较,但是通过embstr的话就要转化为数字之后再进行比较
(1) hashtable,以redis自己的方式做的哈希表
(2) ziplist,压缩表,当value的类型是哈希表但是其中的元素又很少时,就可以采用ziplist来遍历(因为元素少所以时间差异不大)压缩表通过内部的优化,将数据按照更紧凑的方式进行表示,当数据增多时,会导致效率下降
(1) 以前的版本采用的是linkedlist + ziplist实现,redis3.2以后,采取quicklist的实现方式,类似于std::deque
(1) hashtable (2) intset整数集合,当集合中数据较少而且只存储整数的时候,就是用这种结构
(1) skiplist,跳表,类似于链表,但是每个节点有多个指针域,使之能够实现logn的查询效率
(2) ziplist,元素个数比较少或者元素大小比较小
object encoding keyname,查看某个value具体的存储方式
(1) incr,表示给相应value + 1,只有实际类型是int的才可以
(2) incrby,表示给相应value + n,n必须是整数,可以是负数
(3) 如果key不存在,就从零开始处理
(1) 除了进行的是减操作以外,其他的都是和incr与incrby一样的
可以进行小数和整数的操作,如果需要减操作,使用负数即可
(1) 对字符串进行追加操作,并返回追加之后的长度
(2) 对于redis来说,不会对我们的数据进行字符集上的处理,因此输入中文的话默认打出的就是原编码,所以可以在启动客户端
的时候加上–raw指令,让客户端尝试解读返回的二进制数据并展示,就能够完成中文的显示了
(1) getrange keyname start end,表示获取[start, end]的内容,以字节为单位,这意味着可能会出现中文被解析成乱码的情况
,因为无论是utf8还是gbk都是多字节编码一个中文字符
(2) 当end是负数时,表示倒数第几个字符,例如-1表示倒数第一个字符
(3) 根据两个端点的情况,redis会自动截取内容(数字同理),但是如果最后出现start > end时,会导致解析不出内容
(1) setrange key start value,设置从start开始的内容为value,具体设置到哪里取决于value的长度
(2) 如果设置的key不存在,那么就根据start的值,用空格填充前面的内容;如果start超过了当前内容的长度,也是同理往后
添加用空格补全长度
(1) 获取字符串类型的value的长度,单位是字节,对于中文也是具体字节而不是字符的个数
redis中的hash,使用field-value表示键值的结构,其中,value的类型只允许是字符串
(1) hset keyname fieldname value,表示keyname用来查找这个哈希表,fieldname是哈希表的键值。
(2) hget keyname fieldname,获取keyname的哈希表的fieldname所对应的值
(3) hexists keyname fieldname,判断keyname对应的哈希表是否具有fieldname的键值
(4) hdel keyname fieldname,删除keyname对应的哈希表的fieldname键值
hkeys key,获取key对应的哈希表中的所有field;hvals key,获取key对应的哈希表中的所有value值。尽量不要使用这些操作,
和keys*有异曲同工之妙
hlen keyname,用来查询哈希表的大小hsetnx,不存在则插入,存在则失败hincrby,哈希表中某个value + n,只适合处理数字类型的valuehincrbyfloat,哈希表中某个值增加,可以是小数push_front pop_front push_back pop_back
lrem key count value,表示将key列表中的count个value(有多少删多少)删除并返回lrange key start stop,表示将key列表中[start, stop]的下标的内容返回(显示查询出结果的时候,前面带的数字不是下标,是结果集的序号),当下标超出的时候会取余调整lindex key index,表示获得key列表中下标为index的元素lpop keyname [count],从左端删除,后面的count在低版本的不支持rpop keyname [count],从右端删除linsert keyname [before|after] pivot value, pivot是从左到右寻找的一个值(如果没有找到就插入失败)
lrem keyname count element,count > 0时,从左到右移除count个元素;count == 0,移除列表中所有element相等的元素;count < 0时,从右向左移除count个元素
ltrim,ltrim keyname start stop 截取[start, stop]的区间之后,剩下部分丢弃lset,lset keyname index element 将index下标设置为element,其中index超过范围时,会报错blpop keyname timeout,0表示一直阻塞等待,以秒为单位等待set与列表相比,是无序的,意思是顺序不重要,同时set中不允许有相同元素,但是列表可以
sadd key elements往set中添加元素smembers key,获取set中的所有元素sismember key member,判断一个value是否是key’s set中的元素scard keyname,获取集合中的元素个数spop keyname,从set中随机获取一个元素并且从set中删除srandmember keyname,从set中随机获取一个元素,但是并不会删除set中的返回元素srem keyname element,删除指定set中的指定元素smove source destination element,将source set中的element移动给element,如果移动destination中已经存在的元素也能移动成功,但是发生替换sinter setname1 setname2 ...,求出两者的交集sinterstore destination setname1 setname2 ...,求出两者的交集,放到destination集合中分别取求并集和差集,使用方式与求交集相同
zset也是有序的,但是zset的有序是真正的有顺序的,通过在插入时基于score的结构实现。score和member一一对应,类似std::pair
zadd key [nx|xx] [gt|lt] [ch] [incr] score member [score member ...]
zrange key start end [withscore],展示zset中的全部元素,withscores表示展示相应元素分数zrevrange key start end [withscore],表示逆序展示(start, range)的memberzrangebyscore key start end [withscore],表示根据score从低到高排序展示member,前面两个start、end表示的是下标zcount key start end,用来统计某个score区间中member的个数,如果要表示一个数字是开区间的一端的话就在前面加上(,例如(2, 5)表示为(2 (5zcard key,统计member个数
zpopmax key [count]表示连续取count个最大member,时间复杂度o(logn * m);bzpopmax key \[key...\] timeout,阻塞的取最大member,超时时间为timeout(0为一直阻塞),可以等待多个key,当任意一个有返回时,阻塞结束,因此时间复杂度是o(logn);两者使用和zpopmax、bapopmax相同,区别是操作的是zset中的最小值
zrank key member [withscore],查询member在有序列表中的下标,从前往后算,就和正常数组一样zrevrank key member withscore,查询member在有序数组中从后往前的下标,即最后一个元素下标为0zscore key member,查询member的分数,为了优化效率,redis牺牲空间,换取了该操作o(1)的时间复杂度zrem key member,删除member成员,时间复杂度o(logn);zremrangebyrank key start end,删除下标[start, end]的成员,时间复杂度o(logn + m),因为只需要找到一个七点就可以往后删除zremrangebyscore key min max,删除分数[min, max]的成员,支持使用’('去指定开区间zincrby key increment member,给member的分数增加increment,increment可以是小数,也可以是负数,表示减小分数zinterstore destination keynum key \[key...\] weights \[weight...\] \[aggregate sum | min | max\]
o(n*k) + o(m*log(m)),其中n为最小集合的元素个数,k为求交集的元素个数,m为最后交集中zunionstore destination keynum key \[key...\] weights \[weight\] \[aggregate sum | min | max\]
o(n) + o(m*log(m)),n是元素总个数,m是并集中元素的个数bitfield,位域,可以理解成是一个字节数组,和c语言中的位段类似,能够为几个比特位赋予特殊的含义并进行读取、存储、计算等操作,相对于hash string,目的仍然是省空间keys *的方式去查找整个redis中的键,渐进式遍历采取一次查找一小部分的方式来查找到需要的内容。这样每一次花费的时间都较少,能够避免redis服务器被阻塞scan cursor [match match] [count count] [type type],表示从cursor光标开始,寻找count个元素。这里的cursor并不是下表的意思,而是redis服务器在每次渐进式遍历结束后返回的下次渐进式遍历的开始位置,输入0表示从头开始遍,返回的新位置是0表示此次遍历结束;match表示通配符匹配,使用规则和keys的一样;type表示检索出的结果的类型select index,表示切换0~15号数据库;使用dbsize来查看当前数据库中key的个数;使用flushdb [async|sync]来选择同步或者异步清空数据库;使用flushall来清空所有数据库的所有内容+ok\r\n
simple string,以 + 开头
-err\r\n
error,以 - 开头
:1000\r\n
整形,以:开头
$5\r\nhello\r\n
bulkstring,以$开头,相比simple string可以传输二进制数据
*2\r\n$5\r\nhelloworld$5\r\nhello\r\n
array,以*开头
声明redis连接对象
#include <sw/redis++/redis.h>
sw::redis::redis redis("tcp://127.0.0.1:6379");声明ip和redis服务器端口号
使用ping方法检查连通性
std::string ret = redis.ping(); std::cout << ret << std::endl;
get、set方法
sw::redis::redis redis("tcp://127.0.0.1:6379");
using namespace std::chrono_literals;
redis.set("key1", "val1", 0s, sw::redis::updatetype::no_exist); //0s表示不设置过期时间,没有提供只传递更新策略的set函数
auto ret = redis.get("key1");
if(ret) std::cout << ret.value() << std::endl;set方法基本使用通过传入sw::redis::stringview的key、val即可设置简单键值对,stringview使用类似于std::string,但是他是只读的而且效率更高;返回值的类型是sw::redis::optionalstring,其中optional表示无效值,没有采用std::string的原因是一方面如果直接采用对象的话,那么无法很好的表示nil,另一方面如果返回对象指针,还要设计内存指向空间是否有效的问题。sw::redis::optionstring在结果有效时,可以通过value()接口获取返回内容,同时失败的情况也可通过他隐式转换为bool来得知
set还有第三、四个参数,分别用来表示过期时间和更新策略。过期时间使用std::chrono::milliseconds,更新策略分为sw::redis::updatetype::exist、sw::redis::updatetype::not_exist sw::redis::updatetype::always,分对应setnx setxx 和直接set
exists和del
sw::redis::redis redis("tcp://127.0.0.1:6379");
auto ret = redis.exists("key1");
ret = redis.del({"key1", "key2"});exists判断一个key是否存在,存在返回1,失败返回0del删除key,返回删除key的数目keys
sw::redis::redis redis("tcp://127.0.0.1:6379");
vector<string> ret; auto it = std::back_inserter(ret);
redis.keys("*", it);keys用来获取所有的key,通过第一个参数的匹配规则来检索,方法和前面命令行中介绍的五种一样;同时为了解耦合,第二个参数要求传入输出型数据结构的尾插迭代器
expire和ttl
sw::redis::redis redis("tcp://127.0.0.1:6379");
using namespace std::chrono_literals;
bool ret = redis.expire("key", 10s); std::this_thread::sleep_for(5s);
long long len = redis.ttl("key");expire用来设置过期时间,通过std::chrono给定ttl用来判断剩余生存时间,以秒为单位。已经过期的key,返回值为-1;不存在的key,返回值为-2type
sw::redis::redis redis("tcp://127.0.0.1:6379");
redis.set("key", "val");
std::string ret = redis.type("key");mget mset
sw::redis::redis redis("tcp://127.0.0.1:6379");
redis.mset({std::make_pair("key1", "val1"), std::make_pair("key2", "val2")});
std::vector<std::string> keys;
redis.mset(keys.begin(), keys.end());
std::vector<sw::redis::optionalstring> vals; auto bit = std::back_inserter(vals);
redis.mget({"key1", "key2"}, bit);
std::vector<std::string> vals2 = {"key1", "key2"};
redis.mget(vals2.begin(), vals2.end(), bit);mget方法支持通过初始化列表出入多个pair来表示要插入的多个键值对,或者可以采用迭代器的方式使用string数组的起止迭代器传参mset方法支持通过初始化列表或者sw::redis::optionalstring数组来传入多个key,也需要在最后传入一个尾插迭代器来带出结果getrange setrange
sw::redis::redis redis("tcp://127.0.0.1:6379");
std::string ret = redis.getrange("key", 5, 10);
long long val = redis.setrange("key", 5, "ins_val");getrange返回[start, end]范围中的内容,返回的时普通的std::stringsetrange将从offset开始的内容,设置为给定的字符串,并返回完成更改后新的字符串的长度incr decr
sw::redis::redis redis("tcp://127.0.0.1:6379");
long long ret1 = redis.incr("key");
long long ret2 = redis.decr("key");incr和decr返回更改过后的值,两者都是以一为单位;相比get方法,后者返回的是sw::redis::optionalstring,如果想要当作数字使用的话还要转换sw::redis::redis server("tcp://127.0.0.1:6379");
server.lpush("list1", "1");
server.lpush("list1", {"1", "2", "3"});
std::vector<std::string> vals = "1", "2", "3";
server.lpush("list1", vals.begin(), vals.end());
std::vector<std::string> rets;
auto bit = std::back_inserter(rets);
server.lrange("list1", bit);
auto ret1 = server.rpop("list1"); auto ret2 = server.lpop();lpush和rpush都是通过先指定列表名称,再指定元素的方式使用的。指定元素有三种方式:1. 直接给予,这样可以给一个;2. 通过初始化列表给予多个值;3. 现在外部容器构造完成,然后给予起止迭代器lrange,需要给予一个尾插迭代器,来带出遍历结果rpop和lpop,两个都是通过直接给予列表名称,然后返回sw::redis::optionalstring的方式获取两端元素sw::redis::redis server("tcp://127.0.0.1:6379");
auto ret = server.blpop("list1", std::chrono::seconds(1));
if(ret)
{
std::cout << ret.value().first << ret.value().second << std::endl;
}optionalstring+pair的方式返回,因为可以等待多个队列,所以既返回列表名,也返回删除元素;也可以设置超时时间,超过仍未获取元素就直接返回sw::redis::redis server("tcp://127.0.0.1:6379");
long long server.llen("list");llen用来获取列表长度sw::redis::redis server("tcp://127.0.0.1:6379");
server.sadd("set", "1");
set<string> mems; auto in = std::inserter(mems, mems.end());
server.smembers("set", in);sadd前面提到的三种方式都可以,smembers也是通过迭代器的方式将遍历结果带出sw::redis::redis server("tcp://127.0.0.1:6379");
bool exists = server.ismember("set", "1");
auto ret = spop("set"); if(ret) std::cout << ret.value() << std::endl;
long long num = scard("set");sismember,用来判断某个成员是否属于某个集合spop,用来随机返回集合中的一个元素scard,用来返回某个集合中的元素个数sw::redis::redis server("tcp://127.0.0.1:6379");
long long ret = server.hset("hash1", "1", "zhangsan");
ret = server.hset("hash1", {std::make_pair("2", "lisi"), std::make_pair("3", "wangwu")});
auto val = server.hget("hash1", "1"); if(val) std::cout << val.value() << std::endl;hset用来向哈希表中添加元素,依然可以通过直接给予、初始化列表、迭代器三种方式给予field-valuehget用获取哈希表中field-value中的valuesw::redis::redis server("tcp://127.0.0.1:6379");
bool exists = server.hexists("hash1", "1");
long long ret = server.hdel("hash1", {"1", "2"});
ret = server.hlen("hash1");hexists用来判断某个field是否存在hdel用来删除多个field,并返回删除的个数hel,返回一个哈希表中field的个数std::vector<std::string> keys;
auto it = std::back_inserter(keys);
server.hkeys("hash1", it);
std::vector<std::string> vals;
it = std::back_inserter(vals);
server.hvals("hash1", it);
server.hmget("hash1", {"3", "4", "5"}, it);hmset hmget用来获取、设置多个元素,hkeys hvals用来获取一个哈希表中所有的field valueserver.zadd("zset1", "zhangsan", 1);
server.zadd("zset1", {std::make_pair("lisi", 2), std::make_pair("wangwu", 3)});
std::vector<std::pair<std::string, std::string>> pairs = {
std::make_pair("zhouliu", "4"),
std::make_pair("tianqi", "5")
};
server.zadd("zset1", pairs.begin(), pairs.end());
std::vector<std::string> withnoscore;
auto it = std::back_inserter(withnoscore);
std::vector<std::pair<std::string, double>> withscore; //通过模板类型来指定是否需要带出分数
auto it2 = std::back_inserter(withscore);
server.zrange("zset1", 0, -1, it2);zadd,往有序列表中加入成员和分数,依然支持前面的三种方法zrange,遍历获取有序列表中的元素,通过不同的输出容器来间接指定是否需要获取分数long long ret = server.zcard("zset1");
auto score = server.zscore("zset1", "tianqi");
auto rank = server.zrank("zset1", "zhangsan");
server.zrem("zset1", "lisi");zcard,获取有序集合中成员的个数zscore,根据成员获取分数zrank,根据成员获取排名(在整个有序列表中的数组下标)zrem,删除某个有序列表中的成员到此这篇关于详解redis终端操作和redis-plus-plus接口使用教程的文章就介绍到这了,更多相关redis终端和redis-plus-plus接口内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论