Redis入门

Redis_入门

Redis(REmote DIctionary Server)是C语言开发的开源的高性能键值对(key-value)数据库。

​ NoSQL(NoSQL = Not Only SQL ),指非关系型的数据库。是对不同于传统的关系型数据库的数据库管理系统的统称。

类型部分代表特点
列存储Hbase、Cassandra、Hypertable顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。
文档存储MongoDB、CouchDB文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。
key-value存储Tokyo Cabinet / TyrantBerkeley DB、MemcacheDB、Redis可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能)
图存储Neo4J、FlockDB图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。
对象存储db4o、Versant通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。
xml数据库Berkeley DB XML、BaseX高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath。
  • 数据间没有必然的关联关系
  • 内部采用单线程机制进行工作
  • 高性能
  • 多数据类型支持
    • 字符串类型 String
    • 列表类型 list
    • 散列类型 hash
    • 集合类型 set
    • 有序集合类型 sorted_set
  • 持久化支持。可进行数据恢复

数据类型

​ redis自身是一个Map,其中所有的数据均采用key:value的形式存储。

在这里插入图片描述

数据类型指存储的数据的类型,也就是value部分的类型,key部分的类型永远是字符串。

string

存储的数据:单个数据,最简单常用的数据存储类型。

存储数据的格式:一个存储空间保存一个数据。

存储内容:通常使用字符串,如果字符串的内容是数字,可以作为数字操作。

在这里插入图片描述

基本操作
  • 添加/修改数据:set key value
  • 获取数据:get key
  • 删除数据:del key
  • 添加/修改多个数据:mset key1 value1 key2 value2 …
  • 获取多个数据:mget key1 key2…
  • 获取数据字符串个数(字符串长度):strlen key
  • 追加信息道原始信息的后部(原始key不存在,则为新增):append key value
扩展操作
  • incr key:将 key 中储存的数字值增一。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
  • INCRBY key increment:将 key 所储存的值加上增量 increment 。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。
  • INCRBYFLOAT key increment:为 key 中所储存的值加上浮点数增量 increment。
  • DECR key:将 key中储存的数字值减一。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。
  • DECRBY key increment:将 key 所储存的值减去减量 increment 。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECRBY 命令。

​ string在Redis内部存储默认是一个字符串,当遇到增减类的操作会转换成数字进行计算。

​ Redis所有的操作都是原子性的,采用单线程处理所有业务,因此无需考虑并发的影响

时效性设置
  • SETEX key seconds value:设置 key=value ,并将 key 的生存时间设为 seconds (以秒为单位)。如果 key 已经存在, SETEX 命令将覆写旧值。
  • PSETEX key milliseconds value:和上一条指令一致,设置的有效时长为毫秒。

hash

​ 对象类数据的存储如果频繁的更新会显得较为笨重。

在这里插入图片描述

存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息。

存储结构:一个存储空间保存多个键值对。

hash:底层使用哈希表结构实现数据存储

基本操作
  • 添加/修改数据:hset key field value
  • 获取数据:hget key field
  • 获取全部数据:hgetall key
  • 删除数据:del key field1 [field2]…
  • 添加/修改多个数据:hmset key field1 value1 field2 value2…
  • 获取多个数据:hmget key field1 field2…
  • 获取字段的数量:hlen key
  • 指定字段是否存在:hexists key field
  • 获取所有的键:hkeys key
  • 获取所有的值:hvals key
  • **field 的值加上增量 increment **:HINCRBY/HINCRBYFLOAT key field increment

​ hash类型下的value只能存储字符串,不能存储其他类型。

​ hgetall操作可以获取全部属性,如果内部的field过多,会导致效率很低,可能成为数据访问瓶颈。

Redis购物车存储设计

在这里插入图片描述

  • 用户id作为key,每位用户创建一个hash存储购物车里面的商品编号(fidle)和商品数量(value)

  • 添加商品:追加信的field和value

  • 浏览:遍历hash

  • 更改数量:设置value或者自增自减

  • 移出商品:删除队医你个的field

  • 清空:删除对应的key

    如果只是这样设计,在每次查看购物车,都需要用商品编号查询数据库获取商品信息

​ 再独立的新建一个hash用于存储商品信息,所有用户公用一个。用户新增商品用HSETNX key field value来更新用于存储商品信息的hash(将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在)。

list

存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分

存储结构:一个储存空间保存多个数据,且通过数据可以体现进入数据

List类型:保存多个数据,底层使用双向链表存储结构实现

在这里插入图片描述

基本操作
  • 添加/修改数据(左进和右进):lpush/rpush key value1 [value2]…

  • 获取数据

    lrange key start stop	//获取key中的数据,下标从start到stop
    lrange key index	//获取key中的下标是index的数据
    llen key	//key的list的长度
    

    在这里插入图片描述

    ​ 左进左出,那么查看得到的顺序和存入的顺序是相反的。

    ​ 同理,右进左出,查看得到的顺序和存入的顺序是一致的。

  • 获取并移除数据:lpop/rpop key

  • 规定时间内获取并移除数据:blpop/brpop key1 [key2]… timeout

    ​ 是 LPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP 命令阻塞,直到等待超时或发现可弹出元素为止。

    ​ 当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。

  • 删除指定的元素:lrem key count value

    根据参数 count 的值,移除列表中与参数 value 相等的元素。

    count 的值可以是以下几种:

    • count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
    • count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
    • count = 0 : 移除表中所有与 value 相等的值。

set

存储需求:存储大量数据,在查询方面提供更好的性能

存储结构:能够存储大量的数据,高效的内部存储机制,便于查询

set类型:与hash存储结构完全相同,仅存储键,不存储值(nil),并且值是不允许重复的。

在这里插入图片描述

基本操作
  • 添加数据:sadd key member1 [member2]…

  • 获取全部数据:smembers key

  • 删除数据:srem key member1 [member2]…

  • 获取集合数据总数:scard key

  • 集合中是否有指定数据:sismember key member

  • 随机操作数据

    随机获取集合中指定数量的数据:srandmember key [count]

    随意获取集合中的某个数据并移出集合:spop key

  • 交、并、差操作

    求两个集合的交、并、差集

    sinter key1 [key2]

    sunion key1 [key2]

    sdiff key1 [key2]

    求两个集合的交、并、差集,并将结果存到destination集合中

    sinterstore destination key1 [key2]

    sunionstore destination key1 [key2]

    sdiffstore destination key1 [key2]

  • 移动集合中的数据(将member从source移动到destination中):smove source destination member

  • set中的数据不能重复,如果添加的数据在set中已经存在,只保留一份
  • set虽然和hash的存储结构相同,但是无法启用hash中存储值的空间

sorted_set

存储需求:数据排序有利于数据的有效展示,需要提供一种可以根据自身特征进行排序的方式

存储结构:可以保存可排序的数据

sorted_set类型:在set的存储结构基础上添加可排序字段

在这里插入图片描述

基本操作
  • 添加数据:zadd key score1 member1 [score2 member2]

  • 获取全部数据

    zrange key start stop [Withscores] //升序查询,从start到stop

    zrevrange key start stop [Withscores] //降序查询,从start到stop

  • 删除数据:zrem key member [member]

  • 按条件查询

    zrangebyscore key min max [Withscores] [limit] //升序查询,score值再min到max之间的数据

    zrevrangebyscore key min max [Withscores] //升序查询,score值再min到max之间的数据

  • 条件删除数据

    zremrangebyrank key start stop //删除start到stop的数据(start、stop代表下标,不是score)

    zremrangebyscore key min max //删除score在min到max之间的数据

  • 获取集合数据总量:zcard key

  • 从min到max的数据总量:zcount key min max

  • 集合的交集:zinterstore destination numkeys key [key …]

  • 集合的并集:zunionstore destination numkeys key [key …]

    ​ 交集和并集的操作还可以进一步操作,比如求和,最大值等等。

    在这里插入图片描述

  • 获取对应数据的索引(排名):zrank/zrevrank key member

  • score值的获取:zscore key member

  • score值的修改:zincrby key increment member

sorted_set 底层基于set结构,所以数据不能重复。

score保存的数据可以是双精度的double值,可能会丢失精度。

通用指令

key通用指令

​ key是一个字符串,通过key获取redis中保存的数据。

基本操作
  • del key:删除指定key
  • exists key:key是否存在
  • type key:获取key的类型
  • keys pattern:查询key

pattern的匹配:

  • * 匹配任意数量的任意字符
  • ? 匹配一个任意字符
  • [] 匹配一个指定符号
时效性控制
设定key的有效期
  • expire key seconds
  • pexpire key milliseconds
  • expireat key timestamp
  • pexpireat key milliseconds-timestamp
获取key的有效时间
  • ttl key:-1表示永久,-2表示不存在,其他为有效时间长度。
  • pttl key
切换key的有效期有永久
  • persist key
其他操作
  • rename key newkey:为key改名(如果newkey已经存在,则会用key的值替换掉原来newkey的值,然后删掉key)
  • renamenx key newkey:为key改名(如果newkey已经存在,改名失败)
  • sort:对所有key排序(这对集合类型的key,比如list、set、sorted_set,不会修改集合里面的顺序,只是对获取的结果进行排序)

数据库的通用指令

​ redis为每个服务提供16鸽数据库,编号从0-15,每个数据库之间的数据相互独立。

  • select index:切换数据库
  • move key db:移动数据,移动key到db(db为0-15的index)
  • flushdb:删除当前db的数据
  • flushall:删除所有db的数据
  • dbsize:查看db中有多少个key

Jedis

​ Java连接redis服务:Jedis、SpringData Redis、Lettuce。

public void testJedis(){
    //1.连接redis
    Jedis jedis = new Jedis("127.0.0.1",6379);
    //2.操作redis
    //jedis.set("name","xijian");
    String name = jedis.get("name");
    System.out.printf(name);
    //3.关闭连接
    jedis.close();
}
HelloWord程序

​ 限定初级用户每10秒调用服务不超过10次。高级用户每10秒调用服务不超过30次。

Redis连接配置

redis.host=127.0.0.1
redis.port=6379
redis.maxTotal=30
redis.maxIdle=15

获取Redis连接

public class JedisUtils {
    private static JedisPool jedisPool = null;
    private static String host = null;
    private static int port;
    private static int maxTotal;
    private static int maxIdle;
    static {
        ResourceBundle resourceBundle = ResourceBundle.getBundle("redis");
        host = resourceBundle.getString("redis.host");
        port = Integer.parseInt(resourceBundle.getString("redis.port"));
        maxTotal = Integer.parseInt(resourceBundle.getString("redis.maxTotal"));
        maxIdle = Integer.parseInt(resourceBundle.getString("redis.maxIdle"));
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(maxTotal);
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPool = new JedisPool(jedisPoolConfig, host, port);
    }
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }
}

public class Service {
    private String id;
    private int count;
    public Service(String id, int count) {
        this.id = id;
        this.count = count;
    }
    //控制单元
    public void service() {
        //1.连接redis
//        Jedis jedis = new Jedis("127.0.0.1", 6379);
        Jedis jedis = JedisUtils.getJedis();
        //2.操作redis

        String value = jedis.get("compid:" + id);
        try {
            if (value == null) {//不存在
                //创建该值
                jedis.setex("compid:" + id, 10, Long.MAX_VALUE - this.count + "");
            } else {//存在
                //自增,执行业务
                long val = jedis.incr("compid:" + id);
                business(id, val - Long.MAX_VALUE + this.count);
            }
        } catch (JedisDataException e) {
            System.out.println("使用次数已经到达上限。");
            return;
        } finally {
            //3.关闭连接
            jedis.close();
        }
    }
    //业务操作
    public void business(String id, long val) {
        System.out.println("用户:" + id + "业务操作第" + val + "次");
    }
}


class Mythread extends Thread {
    Service service;
    public Mythread(String id, int count) {
        service = new Service(id, count);
    }
    @Override
    public void run() {
        while (true) {
            service.service();
            try {
                Thread.sleep(1000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Main {
    public static void main(String[] args) {
        Mythread mythread1 = new Mythread("初级用户", 10);
        Mythread mythread2 = new Mythread("高级用户", 30);
        mythread1.start();
        mythread2.start();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值