• Redis中的数据结构


    一、Redis概述


    如今,互联网项目越来越青睐 Redis。

    Redis 是一种基于内存的数据库。因为是面向内存,所以其读写性能要远优秀于面向磁盘的数据库。这也是在高并发场景下,Redis 发挥其作用的主要原因。


    Redis

    二、5种数据类型

    Redis 是一种键值(key-value)数据库。这是理解其数据结构的关键。因为任何存放在 Redis 数据库中的数据都是以这种形式存在的。

    在 Redis 中,Key 是一个简单的 String。Key 的长度没有限制,但是减小 Key 的长度可以有效的节约内存,也更有利于 Key 检索的效率。

    而在 Redis 中,Value 则有 5 种数据类型。除了基本类型 String 外,还有 List、Hash、Set、Zset 四种数据类型。

    1、String

    字符串是 Redis 中最基本的数据类型,也是 Redis 中默认的数据类型。
    下面是 String 种常用的命令。

    127.0.0.1> set key1 value1 //向Redis中新增一个键值对
    OK
    127.0.0.1> get key1 //获得该键指向的字符串的值
    "value1"
    127.0.0.1> strlen key1 //获得该键指向的字符串的长度
    (integer) 6
    127.0.0.1> getset key1 newvalue //将该键指向字符串设为新值,返回旧值
    "value1"
    127.0.0.1> get key1 //测试上面的命令是否成功
    "newvalue"
    127.0.0.1> getrange key1 3 7 //获取该键指向字符串的子串,范围为0~len
    "value"
    127.0.0.1> append key1 more //向该键指向字符串后添加新串,返回总长度
    (integer) 12
    127.0.0.1> get key1  //测试上面命令是否成功
    "newvaluemore"

    Redis 还提供对整数和浮点数的简单运算,命令如下。

    127.0.0.1> set key1 10 //向Redis中新增键值对
    OK
    127.0.0.1> incr key1 //对该键所指向的值,做加1运算
    (integer) 11
    127.0.0.1> incrby key1 10 //对该键所指向的值,加上指定的整数
    (integer) 21
    127.0.0.1> decr key1 //对该键所指向的值,做减1运算
    (integer) 20
    127.0.0.1> decrby key1 10 //对该键所指向的值,减去指定的整数
    (integer) 10

    这里要注意的是如果 value 值为浮点数,以上四个命令都会失败。想要操作浮点数,可以使用下面的命令。

    127.0.0.1> set key1 1.1
    OK
    127.0.0.1> incrbyfloat key1 1.1 //这个命令对浮点数和整数都适用
    "2.2"

    可以看到,Redis 中自带的运算功能是比较弱的。不过 Redis 中提供 Lua 语言的支持,这是 Redis 扩展功能中最强大的一个地方。

    2、List

    Redis中的 List 是一个双向链表结构,也是一个有序的线性结构。所以它的优缺点也是十分明显的,优点就是:

    • 插入和删除很方便

    而其缺点:

    • 查找性能很弱

    由于是双向链表,所以 List 结构的命令分为左操作和右操作两种,示例如下。

    127.0.0.1> lpush left_key node_1 node_2 node_3 //链表逆序加入节点
    (integer) 3
    127.0.0.1> lrange left_key 0 2 //查看链表中下标从0到2的节点值
    1) "node_3"
    2) "node_2"
    3) "node_1"
    127.0.0.1> rpush right_key node_1 node_2 node_3 //链表顺序加入节点
    (integer) 3
    127.0.0.1> lrange right_key 0 2 //查看链表中下标从0到2的节点值
    1) "node_1"
    2) "node_2"
    3) "node_3"
    127.0.0.1> lindex left_key 2 //读取指定链表中下标为2的节点,以左操作
    "node_1"
    127.0.0.1> llen left_key //返回指定链表的长度,以左操作
    (integer) 3
    127.0.0.1> lpop left_key //删除链表最左边的节点并返回
    "node_3"
    127.0.0.1> rpop left_key //删除链表最右边的节点并返回
    "node_1"
    127.0.0.1> lrange left_key 0 0 //测试上面两条命令是否生效
    1) "node_2"
    127.0.0.1> lpushx left_key node_1 //如果存在该链表,则在最左边
    (integer) 2                       //添加一个节点,否则添加失败
    127.0.0.1> rpushx left_key node_3 //如果存在该链表,则在最右边
    (integer) 3                       //添加一个节点,否则添加失败
    127.0.0.1> lrange left_key 0 2 //测试上面两条命令是否生效
    1) "node_1"
    2) "node_2"
    3) "node_3"
    127.0.0.1> lset left_key 0 newNode_1 //修改执行下标的节点值
    OK
    127.0.0.1> lrange left_key 0 2 //测试上面一条命令是否生效
    1) "newNode_1"
    2) "node_2"
    3) "node_3"
    127.0.0.1> ltrim left_key 1 1 //修剪链表,保留指定下标区间的节点
    OK
    127.0.0.1> lrange left_key 0 0 //测试上面一条命令是否生效
    1) "node_2"

    需要注意的是,对链表的操作都是进程不安全的,有可能存在多个客户端同时操作链表的情况。为了保证链表操作的安全性,Redis 提供了阻塞命令,执行阻塞命令,会给链表加锁,可是这些命令在实际开发中使用的不多,这里不做过多介绍。

    3、Set

    set 翻译成中文就是集合。这里的集合同数学中的集合有着相同的性质:无序、不可重复。

    同 list 一样,集合中每一个元素也都是 String 数据类型。

    127.0.0.1:6379> sadd set1 val1 val2 val3 val4 val5 //给键为set1的
    (integer) 5                                        //集合添加成员    
    127.0.0.1:6379> sadd set2 val4 val5 val6 val7 val8 //同上
    (integer) 5
    127.0.0.1:6379> smembers set1 //返回该键指向集合的所有成员
    1) "val4"                     //从取出的成员能明显看出来集合是无序的
    2) "val1"
    3) "val3"
    4) "val2"
    5) "val5"
    127.0.0.1:6379> sdiff set1 set2 //求两个集合的差
    1) "val1"
    2) "val3"
    3) "val2"
    127.0.0.1:6379> sinter set1 set2 //求两个集合的交
    1) "val4"
    2) "val5"
    127.0.0.1:6379> sunion set1 set2 //求两个集合的并
    1) "val4"
    2) "val8"
    3) "val7"
    4) "val3"
    5) "val5"
    6) "val1"
    7) "val6"
    8) "val2"
    127.0.0.1:6379> sismember set1 val1 //判断val1是否为指定集合的成员
    (integer) 1
    127.0.0.1:6379> smove set1 set2 val1 //把val1从set1移到set2中
    (integer) 1
    127.0.0.1:6379> smembers set2 //测试上一条命令是否生效
    1) "val4"
    2) "val5"
    3) "val7"
    4) "val8"
    5) "val1"
    6) "val6"
    127.0.0.1:6379> spop set1 //随机弹出一个集合成员
    "val2"
    127.0.0.1:6379> spop set1 //同上
    "val4"
    127.0.0.1:6379> spop set1 //同上
    "val3"
    127.0.0.1:6379> smembers set1 //测试上面三条命令是否生效
    1) "val5"

    4、Zset

    zset 称为有序集合。有序集合和集合相似,唯一不同的是有序集合中每一个元素还带有一个分数,可以根据这个分数来对集合成员进行排序。

    下面介绍有序集合的一些常用命令。

    127.0.0.1> zadd set 1 A 2 B 3 C 4 D 5 E //向有序集合中添加成员
    (integer) 5
    127.0.0.1> zcount set 2 4 //返回指定分数区间内的成员个数
    (integer) 3
    127.0.0.1> zincrby set 1 E //为指定成员增加指定分数值
    "6"
    127.0.0.1> zrange set 0 4 //返回指定下标区间内成员,分数从小到大排序
    1) "A"
    2) "B"
    3) "C"
    4) "D"
    5) "E"
    127.0.0.1> zrank set B //返回指定成员的排名,排名从0开始
    (integer) 1
    127.0.0.1> zadd set 2.5 X //添加一个分数为浮点数的成员
    (integer) 1
    127.0.0.1> zrange set 0 5 //测试上面一条命令是否生效
    1) "A"
    2) "B"
    3) "X"
    4) "C"
    5) "D"
    6) "E"

    5、Hash

    Redis 中的 Hash 就如同 Java 中的 map 一样。这种数据类型对于某些场景非常有用:比如需要在 Redis 中存储大量的 User 信息,每个 User 包括多个属性字段。这种情况使用 Hash 结构来存储就相当方便,实例如下。

    127.0.0.1> hmset user_1 id 001 age 23 sex male //设置多个键值对
    OK
    127.0.0.1> hgetall user_1 //获取所有的键值对
    1) "id"
    2) "001"
    3) "age"
    4) "23"
    5) "sex"
    6) "male"
    127.0.0.1> hexists user_1 id //是否存在id字段/键
    (integer) 1
    127.0.0.1> hincrby user_1 age 3 //age字段/键上加3
    (integer) 26
    127.0.0.1> hkeys user_1 //获得所有的键
    1) "id"
    2) "age"
    3) "sex"
    127.0.0.1> hvals user_1 //获得所有的值
    1) "001"
    2) "26"
    3) "male"
    127.0.0.1> hlen user_1 //返回该hash中键值对的数量
    (integer) 3
    127.0.0.1> hset user_1 name mary //向该hash中新增一个键值对
    (integer) 1
    127.0.0.1> hgetall user_1 //测试上面的命令是否生效
    1) "id"
    2) "001"
    3) "age"
    4) "26"
    5) "sex"
    6) "male"
    7) "name"
    8) "mary"

    可以看出,此时键为 user_1,而值为一个 hash 结构,该 hash 结构中又存放了多个键值对。也就是说 Redis 需要通过 user_1 这个键来索引到对应的 hash 结构,再通过 hash 结构的键找到对应的值。

  • 相关阅读:
    USTC 软硕讯飞班参考资源
    nginx 负载均衡
    Meidawiki 配置
    10 款实用的jquery插件
    Mongodb 定时释放内存
    互联网产品精神解读
    简单的缓冲区溢出实验
    fatal error C1902: 程序数据库管理器不匹配;请检查安装解决
    C#的override、new、vitutal一例
    SQL Server 2008导入、导出数据库
  • 原文地址:https://www.cnblogs.com/KKSJS/p/9622824.html
Copyright © 2020-2023  润新知