redis的sort排序
Redis排序命令是sort,完整的命令格式如下:
SORT key [BY pattern] [LIMIT start count] [GET pattern] [ASC|DESC] [ALPHA] [STORE dstkey]
返回或保存给定列表、集合、有序集合key中经过排序的元素。排序默认以数字作为对象,值被解释为双精度浮点数,然后进行比较。
说明 | |
1.一般sort用法 | |
> lpush list1 hello 1 world 2 nihao 3 color bit 2B (integer) 8 > lrange list1 0 -1 |
向链表list1中添加实验数据 |
> sort list1 1) "bit" 2) "color" 3) "nihao" 4) "world" 5) "hello" 6) "1" 7) "2B" 8) "2" 9) "3" |
最简单的情况 a.排序对象:没指定(默认:数字); b.排序方式:没有指定(默认:asc升序); 1.字母开头元素先(字母全当0,内部不排序); |
> sort list1 desc 1) "3" 2) "2B" 3) "2" 4) "1" 5) "bit" 6) "color" 7) "nihao" 8) "world" 9) "hello" |
a.排序对象:没指定(默认:数字); b.排序方式:指定了desc降序; 1.数字开头元素先(内部降序) |
2.使用alpha修饰符对字符串进行排序 | |
> sort list1 alpha 1) "1" 2) "2" 3) "2B" 4) "3" 5) "bit" 6) "color" 7) "hello" 8) "nihao" 9) "world" |
a.指定按alpha(字符)对象; b.没有指定方式(默认:asc升序); 1.数字开头元素先(数字全当a),内部按升序 |
> sort list1 desc alpha 1) "world" 2) "nihao" 3) "hello" 4) "color" 5) "bit" 6) "3" 7) "2B" 8) "2" 9) "1" |
a.排序对象:指定按alpha(字符)对象; b.排序方式:指定了desc降序 1.字母开头元素先,按降序 |
3.使用limit修饰符限制返回结果 | |
排序之后返回元素的数量可以通过limit修饰符进行限制,修饰符接受offset和count两个参数。 offset:指定要跳过的元素数量,即起始位置(偏移量;0 1 2 3 ...)。 count:指定跳过offset个指定的元素之后,要返回多少个对象。 |
|
> sort list1 desc alpha limit 2 3 1) "hello" 2) "color" 3) "bit" |
使用limit 2 3限制,在全部查询结果中从第2个偏移,取3个元素。 用法同MySQL中的limit |
4.案例实战篇:假设现在有用户数据如下: | |
#添加admin用户 > lpush listuid 1 (integer) 1 > mset user_name_1 admin user_level_1 9999 OK #添加jack用户 #添加peter用户 #添加mary用户 |
添加实验数据 |
4.1by 选项[BY pattern] | |
除了可以按集合元素自身值排序外,还可以使用外部 key 的数据作为权重,代替默认的直接对比键值的方式来进行排序。 即:将集合元素内容按照给定pattern组合成新的key,并按照新key中对应的内容进行排序。 |
|
> sort listuid by user_level_* asc 1) "2" #jack用户级别10↑,对应键名user_level_2,返回2 2) "3" #peter用户级别25↑,对应键名user_level_3,返回3 3) "4" #mary用户级别70↑,对应键名user_level_4,返回4 4) "1" #admin用户级别9999↑,对应键名user_level_1,返回1 |
通过使用by选项,可以让listuid按其他键的元素来排序。
目的:将用户按用户级别asc升序进行排序,返回排过序的用户uid 解释:user_level_*是一个占位符,*代表listuid中的元素值,它先逐个取出listuid中的值,然后再用这个值来查找相应user_level_{listuid}元素值,并按要求排序,完成后再将user_level_{listuid}中的{listuid}这部分返回输出。 过程:比如在对listuid链表进行排序时,程序就会先取出listuid的值1、2、3、4,然后再对应的取出user_level_1、user_level_2、user_level_3和 user_level_4的值进行排序,排序完成后将user_level_{listuid}中的{listuid}返回输出。 |
> sort listuid by user_name_* alpha asc 1) "1" #admin↑用户对应键名user_name_1,返回1 2) "2" #jack↑用户对应键名user_name_2,返回2 3) "4" #mary↑用户对应键名user_name_4,返回4 4) "3" #peter↑用户对应键名user_name_3,返回3 |
目的:按用户名值asc降序进行排序,查询出数据库中对应的uid。 |
4.2get 选项[GET pattern] | |
我们也可以通过get选项去获取指定pattern作为新key对应的值。 | |
> sort listuid get user_level_* desc 1) "70" #listuid=4,对应用户级别键名user_level_4值为70 2) "25" #listuid=3,对应用户级别键名user_level_3值为25 3) "10" #listuid=2,对应用户级别键名user_level_2值为10 4) "9999" #listuid=1,对应用户级别键名user_level_1值为9999 |
紧接上面实验 目的:将用户按uid进行desc降序排序,返回排过序的对应用户级别值。 过程:程序对listuid进行排序,逐个取出排过序的uid元素值4、3、2、1,然后再对应的返回user_level_4、user_level_3、user_level_2和 user_level_1的值。 |
> sort listuid get # get user_name_* get user_level_* desc 1) "4" 2) "mary" 3) "70" 4) "3" 5) "peter" 6) "25" 7) "2" 8) "jack" 9) "10" 10) "1" 11) "admin" 12) "9999" |
1.可以同时使用多个get,达到一次性获取多个“字段”(外部键)值目的。 2.get有一个额外的参数规则,那就是可以用#特殊符号引用原始集合也就是listuid。 本例使用get #再获取用户uid“字段” |
4.3sort by选项 get选项综合使用 | |
> sort listuid by user_level_* get # get user_name_* get user_level_* desc 1) "1" 2) "admin" 3) "9999" 4) "4" 5) "mary" 6) "70" 7) "3" 8) "peter" 9) "25" 10) "2" 11) "jack" 12) "10" |
sort、by和get综合使用案例 |
> sort listuid by not-exists-key get # get user_name_* get user_level_* 1) "4" 2) "mary" 3) "70" 4) "3" 5) "peter" 6) "25" 7) "2" 8) "jack" 9) "10" 10) "1" 11) "admin" 12) "9999" |
也可以使用 by not-exists-key 不进行任何排序(节省CPU资源),而关联的获取多个外部键。 |
4.4将哈希表作为get或by的参数 | |
除了可以将字符串键之外, 哈希表也可以作为 get 或 by 选项的参数来使用。 我们可以不将用户的名字和级别保存在 user_name_{uid} 和 user_level_{uid} 两个字符串键中, 而是用一个带有 name 域和 level 域的哈希表 user_info_{uid} 来保存用户的名字和级别信息。 |
|
> hmset user_info_1 name admin level 9999 OK > hmset user_info_2 name jack level 10 OK > hmset user_info_3 name peter level 25 OK > hmset user_info_4 name mary level 70 OK |
添加hash类型实验数据 |
> sort listuid by user_info_*->level asc 1) "2" #jack用户级别10↑,对应哈希键名user_info_2,返回2 2) "3" #peter用户级别25↑,对应哈希键名user_info_3,返回3 3) "4" #mary用户级别70↑,对应哈希键名user_info_4,返回4 4) "1" #admin用户级别9999↑,对应哈希键名user_info_1,返回1 |
by 和 get 选项都可以用 key->field 的格式来获取哈希表中的域的值, 其中 key 表示哈希表键, 而 field 则表示哈希表的域。
目的:将用户按用户级别asc升序排序,然后返回排过序的用户uid |
> sort listuid get # get user_info_*->name get user_info_*->level desc 1) "4" 2) "mary" 3) "70" 4) "3" 5) "peter" 6) "25" 7) "2" 8) "jack" 9) "10" 10) "1" 11) "admin" 12) "9999" |
目的:将用户按uid进行desc降序排序,返回用户详细信息 |
5.保存排序结果 | |
如果对集合经常按照固定的模式去排序,那么把排序结果缓存起来会减少CPU开销。使用store选项可以将排序内容保存到指定key中。保存的类型是list。如果被指定的 key 已存在,那么原有的值将被排序结果覆盖。 | |
> lpush myStore c b a (integer) 3 > lrange myStore 0 -1 1) "a" 2) "b" 3) "c" |
假设我有一个链表类型键,准备存储排序结果 |
> sort listuid by user_info_*->level asc store myStore (integer) 4 |
排序并存储 返回成功存储的元素个数 |
> lrange myStore 0 -1 1) "2" 2) "3" 3) "4" 4) "1" |
查看结果,原值被覆盖,新值存储了 |
如果我们有多个redis server的话,不同的key可能存在于不同的server上。比如name12 name13 name23 name23,很有可能分别在四个不同的server上存贮着。这种情况会对排序性能造成很大的影响。redis作者在他的blog上提到了这个问题的解 决办法,就是通过key tag将需要排序的key都放到同一个server上 。由于具体决定哪个key存在哪个服务器上一般都是在client端hash的办法来做的。我们可以通过只对key的部分进行hash.举个例子假如我们 的client如果发现key中包含[]。那么只对key中[]包含的内容进行hash。我们将四个name相关的key,都这样命名[name]12 [name]13 [name]23 [name]23,于是client 程序就会把他们都放到同一server上。不知道jredis实现了没。
还有一个问题也比较严重。如果要sort的集合非常大的话排序就会消耗很长时间。由于redis单线程的,所以长时间的排序操作会阻塞其他client的 请求。解决办法是通过主从复制机制将数据复制到多个slave上。然后我们只在slave上做排序操作。并进可能的对排序结果缓存。另外就是一个方案是就 是采用sorted set对需要按某个顺序访问的集合建立索引。
redis的sort排序的更多相关文章
- 【转载】Redis sort 排序命令详解
转载地址:http://www.jb51.net/article/69131.htm 本文介绍redis排序命令 redis支持对list,set,sorted set元素的排序 sort 排序命令格 ...
- redis的sort命令
1.简单描述 sort命令可以对list.set和sorted set的元素进行排序,然后显示排序的结果,不影响这些类型里面存储的数据的排序.就是说sort可以对list的元素排序,但是执行lrang ...
- 2.sort 排序命令讲解
sort命令 sort:文本排序,仅仅是对显示文件的排序,而不影响源文件的顺序,是根据ASSII码 的字符升序来排列的. -n:安装数值大小从小到大排列 ,默认是升序. ...
- 反向输出及sort排序
建立条件:#include "algorithm"引用这个头文件 1.reverse 的用法,反向排序,由自己输入5个数: 1 2 3 4 5 for (int i = 0; i ...
- JAVA Collections工具类sort()排序方法
主要分析内容: 一.Collections工具类两种sort()方法 二.示例 一.Collections工具类两种sort()方法 格式一: public static <T extends ...
- javascript:算法之数组sort排序
数组sort排序 sort比较次数,sort用法,sort常用 描述 方法sort()将在原数组上对数组元素进行排序,即排序时不创建新的数组副本.如果调用方法sort()时没有使用参数,将按字母顺序( ...
- sort排序
/*问题 L: 使用sort排序题目描述标准库的sort函数给我们提供了一个很方便的排序的方法,光听别人说方便不顶事,得自己亲自实践一下才能体会到它的方便之处. 输入每组包含多组数据,每组数据第一行包 ...
- [转] C++的STL库,vector sort排序时间复杂度 及常见容器比较
http://www.169it.com/article/3215620760.html http://www.cnblogs.com/sharpfeng/archive/2012/09/18/269 ...
- List<T>.Sort() 排序的用法
List<T> 可以通过 .Sort()进行排序,但是当 T 对象为自定义类型时(比如自定义模型),就需要 IComparable接口重写其中的方法来实现,实现代码如下: class Pr ...
随机推荐
- VS2008 "无法找到资源编译器dll 请确保路径正确"
系统环境:windows 8.1 企业版 x64 (装有 .NET 2.0 / 3.5 / 4.0 / 4.5) 安装前确认系统已安装 .NET 2.0 / 3.5 .在安装时,最好是默认安装,并且 ...
- svn 配置仓库
1.新建一个空文件夹,然后点击--在此创建版本库. 2.修改conf 下的 svnserve.conf : anon-access = read auth-access = write passwor ...
- 用原生JS实现的一个导航下拉菜单,下拉菜单的宽度与浏览器视口的宽度一样(js+html+css)
这个导航下拉菜单需要实现的功能是:下拉菜单的宽度与浏览器视口的宽度一样宽:一级导航只有两项,当鼠标移到一级导航上的导航项时,相应的二级导航出现.在本案例中通过改变二级导航的高度来实现二级导航的显示和消 ...
- java计算工龄
计算工龄原则:若是2000-10-12作为开始工作时间,则到下一年的2001-10-13算为一年.有个bug,不满一年的工龄是错误的. import java.util.Date;import jav ...
- selenium 列表循环定位方法。
话不多说,直接上代码. 就是循环第一层,然后拼接,然后继续循环,继续屏接,任你多少层都不是问题. def c_select(self, values, text): """ ...
- php命名空间学习笔记。
为什么要用命名空间? 在PHP中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题: 用户编写的代码 与 PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲 ...
- 针对某一网站的UI进行分析
本周课上教学通过对PM(项目经理)的学习,我了解到PM 对项目所有功能的把握, 特别是有关的UI内容.最差的UI, 体现了团队的组织架构:其次, 体现了产品的内部结构:最好, 体现了用户的自然需求. ...
- Ubuntu16.04下 protobuf3.4.0 的安装与卸载
感谢原文作者:https://blog.csdn.net/xiexievv/article/details/47396725 一. 安装 下载protobuf protobuf下载地址:https:/ ...
- 软工实践-Alpha 冲刺 (6/10)
队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 已经解决登录注册等基本功能的界面. 完成了主界面的基本布局 ...
- Java中static关键字的作用和用法详细介绍
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static修饰的成员变量和成员方法独立于该类的任何 ...