一、前提:Redis(jedis测试)
Redis缓存数据库,基于内存的Key-Value数据库。
二、几种主要的设计模式
以下jedis为已连接到Redis或Redis集群的client对象。
Key的设计注意事项:
1,不要太长,如果太长的话不仅占用空间大,而且查找时间长 2,不要太短,字符+符号+字符,即用字符分割是个不错的方案,增加可读性 3,要从始至终使用一种模式,例如 "object-type:id" is a good idea 4,key的最大值为512M |
1.条件查询
保存为JSON,
示例:
例如我们需要保存user中名字为Jack的信息,我们需要把key设置为user:Jack:info,用冒号隔开不仅增加了可读性,而且使读取更为高效。
java代码:
String json="{ \"item\": \"pencil\", \"qty\": 500, \"type\": \"no.2\" }"; jedis.set("user:Jack:info",json ); String personstr =jedis.get("user:Jack:info"); Map<String,Object> map=JSONObject.fromObject(personstr); map.get("item"); |
2.List的用法
可以用于查询mysql DB返回List<Map>的场景,存放到List
Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用 Redis的list结构来实现,比较好理解,这里不再重复。
命令说明:
lpush lpop rpush rpop
列表左侧放入,左侧弹出,右侧放入,右侧弹出
java代码:
for(int i=1;i<=50;i++){ jedis.rpush("car:mylist",i+""); } jedis.rpop("rpop"); |
3.Set的用法
Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的,用于存放结果集为Map的场景
例如:
命令说明:
jedis.sadd("name", "dh1","dh2","dh3","dh4"); //随机弹出一个元素 System.out.println(jedis.spop("name")); //查看key为name的集合中的所有元素 System.out.println(jedis.smembers("name")); |
4.模糊查询
命令说明:
在确定匹配结果集很大的情况下请勿使用次命令。(在redis中大量执行keys的模糊搜索操作的时候,会立马导致cpu 100%,并会导致终止服务,貌似是正则表达式匹配,而只要稍加注意,即可避免)
keys 查找符合匹配模式的key值。
java代码示例:
//查找key符合name* 的key值 Set<String> names=jedis.keys("name*"); |
查看某个key是否存在
//查看key为name的键值是否存在 |
5.分页查询
需要使用Sorted sets来实现,Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。
命令:
zadd zrem zcard zrange
举例:
//添加时的顺序按照score进行排序
jedis.zadd("name", 11,"dh11");
jedis.zadd("name", 12,"dh12");
jedis.zadd("name", 13,"dh13");
//按照score正序取第1到第3个元素
System.out.println(jedis.zrange("name", 1, 3));
6.经纬度
命令:
GEOADD
将给定的空间元素(纬度、经度、名字)添加到指定的键里面。
时间复杂度:
每添加一个元素的复杂度为 O(log(N)) , 其中 N 为键里面包含的位置元素数量。
返回值:
新添加到键里面的空间元素数量, 不包括那些已经存在但是被更新的元素。
GEOPOS
从键里面返回所有给定位置元素的位置(经度和纬度)。
返回值:
GEOPOS 命令返回一个数组, 数组中的每个项都由两个元素组成: 第一个元素为给定位置元素的经度 , 而第二个元素则为给定位置元素的纬度。当给定的位置元素不存在时, 对应的数组项为空值。
Geodist
计算两个给定位置之间的距离,需要指定返回的单位(m,km,mi,ft之一)(米,千米,英里,英尺)
返回值:
计算出的距离会以双精度浮点数的形式被返回。 如果给定的位置元素不存在, 那么命令返回空值。
GEORADIUS
以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
范围可以使用以下其中一个单位:
m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
在给定以下可选项时, 命令会返回额外的信息:
WITHDIST : 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
WITHCOORD : 将位置元素的经度和维度也一并返回。
WITHHASH : 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。
命令默认返回未排序的位置元素。 通过以下两个参数, 用户可以指定被返回位置元素的排序方式:
ASC : 根据中心的位置, 按照从近到远的方式返回位置元素。
DESC : 根据中心的位置, 按照从远到近的方式返回位置元素。
在默认情况下, GEORADIUS 命令会返回所有匹配的位置元素。 虽然用户可以使用 COUNT <count> 选项去获取前 N 个匹配元素, 但是因为命令在内部可能会需要对所有被匹配的元素进行处理, 所以在对一个非常大的区域进行搜索时, 即使只使用 COUNT 选项去获取少量元素, 命令的执行速度也可能会非常慢。 但是从另一方面来说, 使用 COUNT 选项去减少需要返回的元素数量, 对于减少带宽来说仍然是非常有用的。
返回值:
GEORADIUS 命令返回一个数组, 具体来说:
在没有给定任何 WITH 选项的情况下, 命令只会返回一个像 ["New York","Milan","Paris"] 这样的线性(linear)列表。
在指定了 WITHCOORD 、 WITHDIST 、 WITHHASH 等选项的情况下, 命令返回一个二层嵌套数组, 内层的每个子数组就表示一个元素。在返回嵌套数组时, 子数组的第一个元素总是位置元素的名字。 至于额外的信息, 则会作为子数组的后续元素, 按照以下顺序被返回:以浮点数格式返回的中心与位置元素之间的距离, 单位与用户指定范围时的单位一致。 geohash 整数。由两个元素组成的坐标,分别为经度和纬度。 (http://redisdoc.com/geo/index.html)