zoukankan      html  css  js  c++  java
  • Redis我想入门——数据类型

    每一个数据库都有自己的数据类型。同样子redis为我们提供了五种类型的数据——字符串、哈希、列表、集合、有序集合。我们知道关系型数据的数据存放型式是一张二维表。用行和列来表示数据之间的关系。redis是一个nosql数据库当然不可能在用什么二维表的形式来表示了。他所有的数据都是以key=value的形式来存放的。每一种数据类型都有数据结构和内部编码的概念。数据结构你们可以理解他们的存放时的结构。而内部编码就是数据结构的具体实现。但是一种数据结构可以对应多种内部编码的实现。接下来笔者就要去看看每一种数据类型相关的操作命令和数据结构,内部编码。

    1.字符串类型的数据

    字符串类型,笔者认为比较简单的类型。

    数据结果:一串值

    内部编码:一共有三种:int  embstr  raw

    例子:

    127.0.0.1:6379> set k1 1002
    OK
    127.0.0.1:6379> set k2 "i am aomi"
    OK
    127.0.0.1:6379> set k3 "i am aomi i am aomi i am aomi i am aomi i am aomi i am aomi i am aomi i am aomi i am aomi i am aomi i am aomi "
    OK
    127.0.0.1:6379> object encoding k3
    "raw"
    127.0.0.1:6379> object encoding k2
    "embstr"
    127.0.0.1:6379> object encoding k1
    "int"
    127.0.0.1:6379> keys *
    1) "k3"
    2) "k1"
    3) "k2"
    127.0.0.1:6379> get k2
    "i am aomi"

    笔者向redis时面存放了三个值。他这三个值对应的键为:k1、k2、k3。

    •  set:用于增加字串符的值。

    语法:

    SET key value [EX seconds] [PX milliseconds] [NX|XX]

      key:键名

      value:键对应的值

      EX:表示有效的时间。0表示永存,大于0表示在几秒内有效。

      PX:表示有效时间。只是单位是毫秒。

      NX:表示不存在的时候才可以增加成功。

      XX:表示只有存在的时候才可以增加成功。

    • object encoing:用于查看当前键的内部编码。

    语法:

    OBJECT subcommand [arguments [arguments]]

      subcommand:这个有三个值 refcount(用于查看对象引用次数)、encoding(查看内部编码)、idletime(存在的时间)。

    • keys:用于查看当前数据库有多少键。

    语法:

    KEYS pattern

      pattern:*表示全部。*aaa表示查找以aaa结尾的。[a,b]123表示查看以a或是b,并且后面是123。相信不用笔者都说明了。

    •  get:用于获取指定键的值。

    语法:

    GET key

      key:键的名称

    学下语法之后,我们可以从上面看到字串符有三种内部编码了吧。如果你输入是一个数字的话,一般都是int。如果输入不是一个数字的话,是embstr。如果输入的字符串长度大于512的话。就会变成raw

    笔者来一个设置有效时间的数据吧。

    127.0.0.1:6379> set k5 v5 ex 10
    OK
    127.0.0.1:6379> ttl k5
    (integer) 4
    127.0.0.1:6379> ttl k5
    (integer) -2

    上面ttl用于查看当前键是的有效时间。

    上面的都是一个一个增加有没有一次增加多个呢?当然是有的。

    127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
    OK
    127.0.0.1:6379> mget k1 k2 k3
    1) "v1"
    2) "v2"
    3) "v3"
    127.0.0.1:6379> 

    事实上学习redis的命令是一件很简单的事情。笔者是一边看命令手册一边写命令的。所以大家也可以这样子。自己写过一遍基本上都不会忘记。如果有不懂的话,查看一下手册就可以了。至于手册网络上很多。建义可以去官网看看。

    2.哈希类型的数据

    这个数据类型算是这五种类型中最为复杂的。存放形式不用说key=value。只是这个value里面就不一样子。是一个field=value形式的数据值。

    数据结构:key: value(field=value)。不知道笔者这样子表示你们看得懂多。

    内部编码:一共有俩种。一种是ziplist,二种是hashtable。

    列子:

    127.0.0.1:6379> hset user:1 name aomi
    (integer) 1
    127.0.0.1:6379> hset user:1 age 32
    (integer) 1
    127.0.0.1:6379> hset user:1 sex 1
    (integer) 1
    127.0.0.1:6379> hset user:2 name nono
    (integer) 1
    127.0.0.1:6379> hset user:2 age 24
    (integer) 1
    127.0.0.1:6379> hset user:2 sex 1
    (integer) 1
    127.0.0.1:6379> hset user:2 desc "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    (integer) 1
    127.0.0.1:6379> hget user:1 name
    "aomi"
    127.0.0.1:6379> hkeys user:1
    1) "name"
    2) "age"
    3) "sex"
    127.0.0.1:6379> hvals user:1
    1) "aomi"
    2) "32"
    3) "1"
    127.0.0.1:6379> hgetall user:1
    1) "name"
    2) "aomi"
    3) "age"
    4) "32"
    5) "sex"
    6) "1"
    127.0.0.1:6379> object encoding user:1
    "ziplist"
    127.0.0.1:6379> object encoding user:2
    "hashtable"
    127.0.0.1:6379> 

    笔者先向redis数据库增加俩个数据。分别为:user:1 和user:2。同时写了三个获得哈希信息的命令。分别为:hget 、hkeys、hvals、hgetall。接着显示出这个俩数据的内部编码。

    • hset:用于增加哈希

    语法:

    HSET key field value

    从语法我就可以看出数据结构大概是一个什么样子。这个JAVA的类有一个像。key为类名,field为成员,value:为成员的值。事实上你可以看到笔者上面的例子就有一点像存放User类的实例一样子。

      key:键名称

      field:成员名

      value:成员的值

    •  hget:用于获得一个成员的值。

    语法:

    HGET key field
    • hkeys:用于获得当前键下的所有成员

    语法:

    HKEYS key
    • hvals:用于获得当前键下的所有值

    语法:

    HVALS key 
    • hgetall:用于获得当前键下的所有成员和对应的所有值。

    语法:

    HGETALL key

    上面例子我们可以看到俩种内部编码。user:2的desc却很长。一定大于64个字节。什么意思。如果成员值的长度大于64个字节的话,内部编码都会转为hashtable。当然还有如果你的成员个数大于512的话,内部编码也会转为hashtable有话。

    笔者想知如果user:2的desc成员删除。内部编号会不会为ziplist。同时大家看一下什么删除。

    127.0.0.1:6379> hdel user:2 desc
    (integer) 1
    127.0.0.1:6379> object encoding user:2
    "hashtable"
    127.0.0.1:6379> hkeys user:2
    1) "name"
    2) "sex"
    3) "age"
    127.0.0.1:6379> hdel user:2
    (error) ERR wrong number of arguments for 'hdel' command

    最后一步出错了。笔者就想试一下删除整个键。你们看到出错了。要删除的话。还要用下的。

    127.0.0.1:6379> del user:2
    (integer) 1
    127.0.0.1:6379> exists user:2
    (integer) 0

    这里有一个观念。hdel删除的是对应哈希里面的成员的。而要删除key是属于数据层的。

    3.列表类型的数据

    redis的列表有一点奇怪。在笔者第一接触的时候。被搞得有一点晕。你们可以这样子理解。现在有一个列表。他只有俩个地方可以进入。一个是左边的头,一个是右边的头。出去也只这俩个头。

    数据结果:一个列表

    内部编码:有三种:一种是ziplist,一个是linkedlist。最后一种是quicklist。

    127.0.0.1:6379> lpush list1 a b c d e f
    (integer) 6
    127.0.0.1:6379> lrange list1 0 -1
    1) "f"
    2) "e"
    3) "d"
    4) "c"
    5) "b"
    6) "a"
    127.0.0.1:6379> 
    • lpush:将一个或多个值 从左边插入

    语法:

    LPUSH key value [value ...]

    lpush就是从左边口进入。所以就 a进完 ,b在进,b进完了c进。以此类推。这个时候我们要以看到列表如下

     左边进入--> f-e-d-c-b-a
    • lrange:获得指定区间内的元素。

    语法:

    LRANGE key start stop

    start表示从哪里开始,stop表示从哪里结果,如果stop=-1表示最后一个,-2的话表示倒数第二个,-3的话表示倒数第三个,依此类推。

    现在我们就可以明白为什么上面是f-e-d-c-b-a。我们在来看看从右边插入会是什么样子。

    127.0.0.1:6379> rpush list2 1 2 3 4 5 6 7
    (integer) 7
    127.0.0.1:6379> lrange list2 0 -1
    1) "1"
    2) "2"
    3) "3"
    4) "4"
    5) "5"
    6) "6"
    7) "7"
    127.0.0.1:6379> 

    如果我们从右边的口进入的话,那么在列表里就是如下

    1-2-3-4-5-6-7 <--右边进入

    所以lrange显示就是1,2,3,4,5,6,7。

    列表的内部是有序的并且可以重复。笔者插入一个相同信的看看

    127.0.0.1:6379> lpush list3 a a b c d
    (integer) 5
    127.0.0.1:6379> lrange list3 0 -1
    1) "d"
    2) "c"
    3) "b"
    4) "a"
    5) "a"

    上面都是入,没有出。现在笔者要做一出的操作。如下

    127.0.0.1:6379> lrange list1 0 -1
    1) "f"
    2) "e"
    3) "d"
    4) "c"
    5) "b"
    6) "a"
    127.0.0.1:6379> lpop list1 
    "f"
    127.0.0.1:6379> lrange list1 0 -1
    1) "e"
    2) "d"
    3) "c"
    4) "b"
    5) "a"
    127.0.0.1:6379> 

    我们发现用lpop的命令之后。相对应的值也会被取出。如上面的“f”就是被取出来了。笔者最后看一下列表只有:e-d-c-b-a了。原来应该是f-e-d-c-b-a。说明lpop是左边出的。同样子rpop是从右边出的。

    127.0.0.1:6379> rpop list1
    "a"
    127.0.0.1:6379> lrange list1 0 -1
    1) "e"
    2) "d"
    3) "c"
    4) "b"
    127.0.0.1:6379> 

    接下让我们看一下他的内部编码。

    127.0.0.1:6379> lpush list4 a "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" 
    (integer) 4
    127.0.0.1:6379> object encoding list4
    "quicklist"
    127.0.0.1:6379> lrange list4 0 -1
    1) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
    2) "a"
    3) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    4) "a"
    127.0.0.1:6379> 

    笔者用了很长的值,内部编码还是quicklist。quicklist是3.2版本之后出现的。他接结ziplist和linkedlist俩都优点而生的。相关的你们可以去查看官网。

    redis提供列表的功能事实上是可以当队列和栈来用的。先进先出。那么你就要用到lpush和rpop 或是rpush 和lpop。从左边进,从右边出。后进先出就是栈了。那么就lpush和lpop或是rpush和rpop了。

    4.集合类型的数据

    他是一个无序的,同时他不能有重复。

    数据结果:你可以理解为一个箱子。东西随便放。但不能重复。

    内部编码:他有俩种:一是intset,一种hashtable.

    例子

    127.0.0.1:6379> sadd set1 a a b c d e f 
    (integer) 6
    127.0.0.1:6379> smembers set1
    1) "a"
    2) "d"
    3) "c"
    4) "f"
    5) "b"
    6) "e"
    127.0.0.1:6379> object encoding set1
    "hashtable"
    127.0.0.1:6379> sadd set2 a b "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    (integer) 3
    127.0.0.1:6379> object encoding set2
    "hashtable"
    127.0.0.1:6379> object encoding set1
    "hashtable"
    127.0.0.1:6379> sadd set3 1 2 3 4 5 6 7 8 9
    (integer) 9
    127.0.0.1:6379> smembers set3
    1) "1"
    2) "2"
    3) "3"
    4) "4"
    5) "5"
    6) "6"
    7) "7"
    8) "8"
    9) "9"
    127.0.0.1:6379> object encoding set3
    "intset"
    127.0.0.1:6379> 

    笔者增加了三个集合类型的数据。set1一般没有什么特别的。set2里面有一个值长度很长。set3都是整数。

    • sadd:用于增加一个集合。

    语法:

    SADD key member [member ...]

    笔者就不说明了。member就是相对应的成员值。

    •  smembers用于显示里面的成员

    语法:

    SMEMBERS key

    笔者分别显示出三个的内部编码。发现只有当集合里面全部是整数的时候,内部编码是intset。其他都是hashtable。

    5.有序集合类型的数据

    你们可以这样子里面集合类型是无序的。为了让他有序,把集合类型的数据结构里面加入值来表示他的顺序。

    数据结构:同样子的箱子。只是在放入这个箱子的东西。必须贴上相关的数字标签。

    内部编码:有俩种:一种是ziplist,一种是skiplist。

    127.0.0.1:6379> zadd stu 80 math 60 english 70 chinese
    (integer) 3
    127.0.0.1:6379> zcard stu
    (integer) 3
    127.0.0.1:6379> zrange stu 0 -1
    1) "english"
    2) "chinese"
    3) "math"
    127.0.0.1:6379> zrange stu 0 -1 withscores
    1) "english"
    2) "60"
    3) "chinese"
    4) "70"
    5) "math"
    6) "80"
    127.0.0.1:6379> zadd stu2 80 "aoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
    (integer) 1
    127.0.0.1:6379> object encoding stu
    "ziplist"
    127.0.0.1:6379> object encoding stu2
    "skiplist"
    127.0.0.1:6379> 

    有没有感觉就是一个报表。比如学习的成绩之类的数据体现。80分 数学。60分 语文。那么前面是不是一定要是一个数字呢?笔者做了一下实验。

    127.0.0.1:6379> zadd stu3 "GODD" "AOMI" 80 EN
    (error) ERR value is not a valid float 

    看到了果然要一个数字。同时我们可以到他的俩种内部编码。

  • 相关阅读:
    python学习之【第十一篇】:Python中的文件操作
    vue2-preview引用时报错解决办法
    原生JS封装_new函数,实现new关键字的功能
    vue+element UI + axios封装文件上传及进度条组件
    Python面试题汇总
    在vue中如何使用axios
    tp5 修改默认的分页url
    jq判断是PC还是手机端的方法
    php 通过curl header传值
    windows 安装memchched和memcache教程
  • 原文地址:https://www.cnblogs.com/hayasi/p/10671440.html
Copyright © 2011-2022 走看看