Redis数据类型及其操作

Redis-3.2.x安装
http://www.cnblogs.com/leechenxiang/p/7094018.html

简介

  1. redis默认端口是6379,自定义端口使用:reids-server –port 6380
  2. 关闭redis。在关闭redis前考虑到可能正在将内存中的数据同步到磁盘,强行关闭redis有可能导致数据丢失,应使用SHUTDOWN 命令进行关闭:
    redis-cli SHUTDOWN
    SHUTDOWN命令的作用:断开所有客户端链接–>执行持久化–>完成退出
    使用“kill redis进程PID”效果跟SHUTDOWN一样。
  3. -h和-p自定义地址和端口号:redis-cli -h 127.0.0.1 -p 6379
  4. 查看redis连接是否正常用:ping ,结果会返回PONG
  5. 命令回复。

    • 状态回复:
127.0.0.1:6379> ping
PONG
  • 错误回复:
127.0.0.1:6379> ERRORCOMMEND
ERR unknown command 'ERRORCOMMEND'
  • 整数回复:Redis没有整数类型。
127.0.0.1:6379> SET foo 1
OK
127.0.0.1:6379> INCR foo
2
  • 字符串回复
127.0.0.1:6379> GET food
bread
  • 多行字符串回复:
127.0.0.1:6379> KEYS *
people
mylist
food
foo
fruit
user:1

KEYS命令是用于获取数据库中指定规则的键名。需要遍历Redis中所有键,当键较多时会影响性能,不建议在生产环境中使用。

配置

启用配置文件要在服务启动时将配置文件的路径作为启动参数传递给redis-server,如:

redis-server /etc/redis/redis.conf

通过启动参数传递同名的配置项会覆盖配置文件中相应的参数。

在Redies 运行时通过 CONFIG SET 命令在不重启Redis的情况下动态修改部分配置。并不是所有配置都能使用CONFIG SET修改,附录B(后面再附上)列出了哪些命令能够使用该命令修改。CONFIG SET也可以在Redis运行时查看当前配置的情况。

数据库

每个数据库都是从0开始的递增数字命名,Redis默认支持16个数据库。通过“SELECT 编号” 来切换数据库。不支持为每个数据库设置访问密码,所以一个客户端可以访问全部数据库,要么全都不能访问。最重要的一点是这些数据库之间并不是完全隔离的,比如FLUSHALL可以清空一个Redis实例中所有数据库中的数据。

使用

1、 获得符合规则的键名列表

KEYS pattern
符号 含义
? 匹配一个字符
* 匹配任意个(包括0个)字符
[] 匹配括号间的任意一个字符,可以用“-”表示一个范围,如a[b-d]可以匹配“ab”,“ac”,“ad”
\x 匹配字符x,用于转义符号。如要匹配”?”,就需要使用\?

2、 判断一个键是否存存在

EXISTS KEY

如果存在返回1,不存在返回0。如:

127.0.0.1:6379> exists food
1

3、删除键,可以删除一个或多个键

DEL key [key...]

如:

127.0.0.1:6379> del bar foo
2

返回删除成功的键的个数,没得删除返回0。

DEL 不支持通配符,但可以用Linux管道和xargs命令来删除符合规则的键。如要删除“user:”开头的键,可以执行
redis-cli keys "user:*" | xargs redis-cli DEL
另外由于DEL命令支持多个键作为参数,可以执行
redis-cli DEL 'redis-cli KEYS "user:*"'
来达到相同的效果,性能更好。

4、获得键的数据类型

TYPE key

返回值可能是string(字符串类型),hash(散列类型),list(列表类型),set(集合类型),zset(有序集合类型)。

127.0.0.1:6379> TYPE mylist
list

5、数据类型

字符串类型

Redis中最基本的数据类型,能存储任何形式的字符串,包括二进制数据。可以存储用户邮箱,JSON数据,甚至一张图片。一个字符串类型键运行存储最大容量为512M。

赋值与取值

SET key value
GET key

读取键值,当结果不在时返回空结果。

127.0.0.1:6379> get abc
--这是一个空行--

递增数字

INCR num

INCR命令让当前键值递增,返回递增后的值。没有的key,默认键值为0,创建并返回1,当键值不是整数是就报错。如:

127.0.0.1:6379> INCR list
1
127.0.0.1:6379> INCR list
2
127.0.0.1:6379> INCR food
ERR value is not an integer or out of range

键的命名技巧

推荐用“对象类型:对象ID:对象属性”来命名一个键。比如:user:1:friends来存储ID=1的用户的朋友列表。对于多个单词用”.“分隔
为了可读性考虑,键的命名一定要有意义,如u:1:f的可读性明显不如user:1:friends。

自增长ID

对于每一类对象使用对象类型(复数形式):count来存储当前类型对象的数量。每增加一个对象使用一次INCR命令,其返回值既是加入该对象后的当前类型的对象总数,也是新增对象的ID.

命令拾遗

  1. 增加指定整数:INCRBY key increment
  2. 减少指定整数:
    DECR key
    DECRBY key increment
  3. 增加指定浮点数:INCRFLOAT key increment
  4. 向尾部追加值:APPEND key value。如果键不存在则将该键设置为value,相当于SET key value。返回值是追加后字符串的总长度。
  5. 获取字符串长度:STRLEN key
  6. 同时获得/设置多个键值
    MGET key [key…]
    MSET key value [key value …]
  7. 位操作:
GETBIT key offset
SETBIT key offset value
BITCOUNT key [start] [end]
BITOP operation destkey key [key...]

如果获取二进制位的索引超过键值二进制位长度,则默认位置为0.
SETBIT设置指定二进制位的值,返回的是该位的旧值。
利用位操作命令可以非常方便存储布尔值。

散列类型

散列类型(hash)的键值是字典结构,存储了字段和字段值的映射,字段值只能是字符串,不支持其他数据类型,即,散列类型不能嵌套其他数据类型。一个散列类型可以包含至多 2321 个字段。

散列类型适合存储对象:使用对象类别和ID构成键名,使用字段表示对象的属性,而字段值则存储属性值。如ID=2的汽车对象,用color,name,price三个字段分别表示颜色、名称、价格,存储结构图如下:
Redis数据类型及其操作_第1张图片

常用命令

HSET key field value  //设置单条记录
HGET key field
HMSET key field value [field value...] //批量设置
HMGET key field [field...]
HGETALL key

命令从字面上很好理解。例如:

127.0.0.1:6379> HMSET phone brand gionee version M6 price 2699
OK
127.0.0.1:6379> HMGET phone brand
gionee
127.0.0.1:6379> HGETALL phone
brand
gionee
version
M6
price
2699

HSET 不区分插入和更新操作,当执行的是插入操作时会返回1,当执行的是更新操作时会返回0。当键本身不存在时HSET会自动创建。

判断字段是否存在HEXISTS key field
存在返回1,不在返回0。

当字段不存在时赋值:HSETNX key field value

增加数字:HINCRBY key field increment

删除字段:HDEL key field [field...]

值获取字段名、字段值:

HKEYS key   //只获取字段名
HVALS key   //只获取字段值

//如:
127.0.0.1:6379> hkeys phone
brand
version
price
127.0.0.1:6379> hvals phone
gionee
M6
2699

列表类型

可以存储一个有序的字符串列表,常用操作是向列表两端添加元素,或者获取列表的某一个片段。列表类型内部使用双向链表实现,时间复杂度是O(1),获取越接近两端的元素就越快。容量是 2321

向列表两端增加元素:

LPUSH key value [value...]
RPUSH key value [value...]

LPUSH 是向列表左边增加元素,返回值是新增元素后列表的长度。

127.0.0.1:6379> LPUSH phonesList 小米 gionee 华为 vivo oppo
5

存储结果的顺序(从左到右)如下:
oppo vivo 华为 gionee 小米

向列表右边添加元素:

127.0.0.1:6379> RPUSH phoneList apple
1

列表变为:
oppo vivo 华为 gionee 小米 apple

从列表两端弹出元素:

LPOP key  //左边弹出
RPOP key  //右边弹出

LPOP的作用:左边的元素被移除,返回被移除的元素。

127.0.0.1:6379> RPOP phonesList
apple

如果把列表当成栈,可以搭配LPUSH和LPOP或RPUSH和RPOP
如果把列表当做队列可以搭配LPUSH和RPOP或RPUSH和LPOP

获取列表长度:LLEN key
获取列表片段:LRANGE key start stop;Redis列表初始索引值为0。

127.0.0.1:6379> LRANGE phonesList 0 3
oppo
vivo
华为
gionee

LRANGE支持负索引,表示从右边开始计数。“-1”表示右边第一个元素,以此类推。

127.0.0.1:6379> LRANGE phonesList -3 -1
华为
gionee
小米

所以 LRANGE key 0 -1 可以获取全部元素。还有如下特殊情况:

如果start索引比stop索引靠后,返回空列表;
如果stop大于实际索引范围,则返回至列表最右边的元素。

删除列表中指定的值:

LREM key count value

LREM 删除前count个值为value的元素,返回值是实际删除元素的个数。

当count>0时,从左边开始删除前count个值为value的元素;
当count<0时,从右边开始删除前 |count| 个值为value的元素。
当count=0时,删除所有值为value的元素。

127.0.0.1:6379> LREM phonesList 3 华为
1

获得指定索引的元素值:

LINDEX key index       //通过索引取值
LSET key index value   //通过索引赋值

//如
127.0.0.1:6379> LINDEX phonesList 2
gionee
127.0.0.1:6379> LSET phonesList 1 Apple
OK

只保留列表指定片段(类似java的trim()方法):

LTRIM key start stop

向列表中插入元素:

LINSERT BEFORE|AFTER pivot value

从左到右查找pivot,再根据BEFORE|AFTER决定在pivot 左边|右边 插入元素。

将元素从一个列表转到另一个列表:

RPOPLPUSH source destination

先执行RPOP再执行LPUSH。从source列表的右边弹出一个元素加入destination的左边,并返回这个元素值。

集合类型

集合也何以容纳 2321 个字符串。与列表有相似之处,对比如下:

item 集合类型 列表类型
存储内容 至多 2321 个字符串 至多 2321 个字符串
有序性
唯一性

集合的常用操作是插入和删除元素,判断元素是否存在。

增加删除元素:

SADD key member [member...]
SREM key member [member...]

SADD 向集合中添加一个或多个元素,如果键不存在会自动创建。如果集合中已经存在要添加的元素,则这个元素会被忽略。返回值是成功添加的元素的数量。

127.0.0.1:6379> SADD tag 美女 性感 可爱 小香风 大长腿 S型 大胸
7
127.0.0.1:6379> SADD tag 可爱 大长腿 小蛮腰 
1
127.0.0.1:6379> SREM tag 小香风 美女
2

判断元素是否存在:

SISMEMBER key member

时间复杂度O(1),存在返回1,不存在返回0。

集合间的运算:

SDIFF key [key...]
SINTER key [key...]
SUNION key [key...]

SDIFF 对多个集合进行差集运算。
SINTER 对多个集合进行交集运算。
SUNION 对多个集合进行并集运算。
详细的集合定律和运算规则,参考高中教材《人教版高中数学A版必修1》的第一章。

获得集合中元素个数:SCARD key

进行集合运算并将结果保存:

SDIFFSTORE destination key [key...]
SINTERSTORE destination key [key...]
SUNIONSTORE destinatio key [key...]

SDIFFSTORE进行差集运算并将结果保存在destination,用于多步集合运算的场景;
SINTERSTORE进行交集运算并将结果保存在destination;
SUNIONSTORE进行并集运算并将结果保存在destination。

随机获取集合元素:

SRANDMEMBER key [count]

count参数可选,表示随机获取集合元素的个数,
count>0时,随机选取count个不重复的元素;
count<0时,随机选取 |count| 个元素,这些元素有可能重复。

127.0.0.1:6379> SRANDMEMBER tag 3
小蛮腰
性感
S型
127.0.0.1:6379> SRANDMEMBER tag -3
大胸
性感
性感

从集合中弹出一个元素:SPOP key
返回元素值并在集合中删除该元素。

有序集合类型

时间复杂度 O(logN) 。是Redis中最高级的数据类型。

添加元素:

ZADD key score member [score member ...]

score是member的分数,可以是整数也可以是双精度浮点数,用于排序,返回值是插入元素的个数。

127.0.0.1:6379> ZADD hipline 39 杨幂 86 Angelababy 85 波多野结衣
3

ZADD 可以修改元素值,如:

127.0.0.1:6379> ZADD hipline 84 杨幂
0

获得元素的分数:

ZSCORE key member

//如
127.0.0.1:6379> ZSCORE hipline 波多野结衣
85

获得排在在某个范围内的元素列表:

ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]

ZRANGE会按照score从小到大的顺序返回索引从start到stop(含start和stop)之间的所有元素。start,stop是负数就从后向前查(-1表示最后一个元素)。时间复杂度为 O(logn+m) (n为有序集合的基数,m为返回元素个数)。

如果两个score相同,会按照字典顺序进行排列。

ZREVRANGE是按照元素的score从大到小的顺序得出结果。

获得指定分数范围的元素:

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

按照score从小到大的顺序返回score在min和max之间的元素。

127.0.0.1:6379> ZRANGEBYSCORE hipline 84 86
杨幂
波多野结衣
Angelababy

想要不包含端点值,可在score前面加“(”。如:

127.0.0.1:6379> ZRANGEBYSCORE hipline 84 (86
杨幂
波多野结衣

min和max支持无穷大。“-inf”表示负无穷,“+inf”表示正无穷。如:要查出列表中女明星臀围大于84,但不包含84的女明星:

127.0.0.1:6379> ZRANGEBYSCORE hipline (84 +inf
波多野结衣
Angelababy

LIMIT offset count 与MySQL中的用法相似。

增加某个元素的分数:

ZINCRBY key increment member

给杨幂丰臀:

127.0.0.1:6379> ZINCRBY hipline 2 杨幂
86
127.0.0.1:6379> ZINCRBY hipline 2 波多野结衣
87

获得集合中元素数量:ZCARD key

获得指定score范围内的元素个数:ZCOUNT key min max
min 和 max 跟ZRANGEBYSCORE中的一样。

删除一个或多个元素:ZREM key member [member...]

按照排名范围删除元素:

ZREMRANGEBYRANK key start stop

获得元素排名:

ZRANK key member
ZREVRANK key member  //倒过来获取,最大的排名是0

//如
127.0.0.1:6379> zrank hipline 杨幂
1

计算有序集合的交集:

ZINTERSTORE destination numkeys key [key...] [WEIGHTS weight [weight...]] [AGGREGATE SUM|MIN|MAX]

ZINTERSTORE计算多个有序集合的交集并将结果存在destination键,同样以有序集合存储。返回值为destination中的元素个数。

AGGREGATE为SUM,默认,destination中元素的score是参与计算的每个集合中该元素score的和。

AGGREGATE为MIN,destination中元素的score是每个参与计算的集合中该元素分数的最小值。

AGGREGATE为MAX,destination中元素的score是每个参与计算的集合中该元素分数的最大值。

通过 WEIGHTS 设置每个集合的权重,每个集合在参与计算时元素的score会被乘上该集合的权重。

并集命令:ZUNIONSTORE 用法与ZINTERSTORE类似。

Java代码演示

添加依赖:

        <dependency>
            <groupId>redis.clientsgroupId>
            <artifactId>jedisartifactId>
            <version>2.9.0version>
        dependency>

Java代码如下:

package com.lz.art.test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import redis.clients.jedis.Jedis;

/**
 * Function:连接本地的 Redis 服务和查看服务是否运行
 *          练习各种数据类型的简单操作
 * @author : gionee
 * Date: 2016年10月20日
 */
public class RedisJava {
    public static Jedis jedis = null;

    /**
     * 连接redis并返回redis对象
     * @return
     */
    static{
        //虚拟机ip:192.168.87.129
        jedis = new Jedis("192.168.87.129",6379);
        jedis.auth("123456");
        System.out.println("连接本地的  Redis 服务成功!");
        // 查看服务是否运行
        System.out.println("服务正在运行: " + jedis.ping());
    }

    /**
     * java操作redis之字符串操作
     */
    public static void strOpt(){
        jedis.set("phonebrand", "金立手机");  
        String phonebrand = jedis.get("phonebrand");
        System.out.println("从redis中获取数据:" + phonebrand);

        //向尾部追加值
        jedis.append("phonebrand", "M6升天了");
        System.out.println("从redis中获取数据:" + jedis.get("phonebrand"));

        //获取字符串长度
        System.out.println("phonebrand值的长度为:" + jedis.strlen("phonebrand"));

        //同时获得多个key的值
        jedis.set("star", "安卓啦宝宝");  
        List str = jedis.mget("phonebrand","star");
        System.out.println("输出得到的多值:" + str);

        //设置多个键-值
        jedis.mset("phone","苹果手机","car","宝马汽车");
        System.out.println("输出得到的多值:" + jedis.mget("phonebrand","star","phone","car"));
    }

    public static void hashOpt(){
        //保存对象的单个 "属性:值" 形式的值
        jedis.hset("star:1", "name", "Angelbaby");

        //保存多个对象的 "属性:值" 形式的值,用map封装
        Map starmap =new HashMap();
        starmap.put("stature", "163");
        starmap.put("bustgirth", "81");
        jedis.hmset("star:1",starmap);

        //获取单个属性的值
        String name = jedis.hget("star:1", "name");
        String bustgirth = jedis.hget("star:1", "bustgirth");
        System.out.println(name + " 的胸围是:" + bustgirth);

        //获取多个信息
        List infoList = jedis.hmget("star:1", "name","stature","bustgirth");
        System.out.println("姓名,身高,胸围 分别是:" + infoList);

        //获取全部信息
        Map infoMap = jedis.hgetAll("star:1");
        System.out.println("姓名,身高,胸围 分别是:" + infoMap);
    }

    /**
     * java操作redis之列表类型操作
     */
    public static void listOpt(){
        //向列表左端添加元素
        long n = jedis.lpush("girlList", "林志玲","苍老师","波多野老师","Angelababy");
        System.out.println("向girlList添加元素:" + n + " 个");
        //取列表元素
        System.out.println("girlList列表为:" + jedis.lrange("girlList", 0, -1));

        //从两端弹出元素
        System.out.println("从左边弹出元素:" + jedis.lpop("girlList"));
        System.out.println("从右边弹出元素:" + jedis.rpop("girlList"));
        System.out.println("弹出元素后结果为:" + jedis.lrange("girlList", 0, -1));

        //删除前n个元素中值为“苍老师”的元素,返回值是实际删除元素的个数
        System.out.println("成功删除元素个数:" + jedis.lrem("girlList", n, "波多野老师"));
        System.out.println("结果为:" + jedis.lrange("girlList", 0, -1));

        //通过索引取值
        System.out.println("获得元素:" + jedis.lindex("girlList", 0));
        //通过索引赋值
        System.out.println("赋值元素:" + jedis.lset("girlList", 0, "Angelababy"));
        System.out.println("结果为:" + jedis.lrange("girlList", 0, -1));

        //只保留指定范围内的元素
        System.out.println("保留指定范围内的元素:" + jedis.ltrim("girlList", 0, 1));
        System.out.println("结果为:" + jedis.lrange("girlList", 0, -1));

        //向列表中插入元素
        jedis.linsert("girlList", BinaryClient.LIST_POSITION.BEFORE, "杨幂", "苍老师");
        System.out.println("结果为:" + jedis.lrange("girlList", 0, -1));

        //元素转移列表
        jedis.rpoplpush("girlList", "girlList2");
        System.out.println("结果为:" + jedis.lrange("girlList2", 0, -1));
    }

    /**
     * 剩下的类型不做演示了,都差不多
     * @param args
     */

    public static void main(String[] args) {

        strOpt();
        hashOpt();

    }
}

Redis批量删除

DEL命令的参数不支持通配符,但我们可以结合Linux的管道和xargs命令自己实现删除素有符合规则的键。比如要删除以“user:”开头的键,可以执行:

redis-cli keys "user:*" | xargs redis-cli DEL

另外由于DEL命令支持多个键作为参数,还可以执行:

redis-cli DEL 'redis-cli KEYS "user:*"'

来达到同样的效果,而且性能更高。

你可能感兴趣的:(redis)