每个数据库都有本身的数据类型。一样子redis为咱们提供了五种类型的数据——字符串、哈希、列表、集合、有序集合。咱们知道关系型数据的数据存放型式是一张二维表。用行和列来表示数据之间的关系。redis是一个nosql数据库固然不可能在用什么二维表的形式来表示了。他全部的数据都是以key=value的形式来存放的。每一种数据类型都有数据结构和内部编码的概念。数据结构大家能够理解他们的存放时的结构。而内部编码就是数据结构的具体实现。可是一种数据结构能够对应多种内部编码的实现。接下来笔者就要去看看每一种数据类型相关的操做命令和数据结构,内部编码。redis
字符串类型,笔者认为比较简单的类型。sql
数据结果:一串值数据库
内部编码:一共有三种: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时面存放了三个值。他这三个值对应的键为:k一、k二、k3。nosql
语法:学习
SET key value [EX seconds] [PX milliseconds] [NX|XX]
key:键名ui
value:键对应的值编码
EX:表示有效的时间。0表示永存,大于0表示在几秒内有效。code
PX:表示有效时间。只是单位是毫秒。
NX:表示不存在的时候才能够增长成功。
XX:表示只有存在的时候才能够增长成功。
语法:
OBJECT subcommand [arguments [arguments]]
subcommand:这个有三个值 refcount(用于查看对象引用次数)、encoding(查看内部编码)、idletime(存在的时间)。
语法:
KEYS pattern
pattern:*表示所有。*aaa表示查找以aaa结尾的。[a,b]123表示查看以a或是b,而且后面是123。相信不用笔者都说明了。
语法:
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的命令是一件很简单的事情。笔者是一边看命令手册一边写命令的。因此你们也能够这样子。本身写过一遍基本上都不会忘记。若是有不懂的话,查看一下手册就能够了。至于手册网络上不少。建义能够去官网看看。
这个数据类型算是这五种类型中最为复杂的。存放形式不用说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 key field value
从语法我就能够看出数据结构大概是一个什么样子。这个JAVA的类有一个像。key为类名,field为成员,value:为成员的值。事实上你能够看到笔者上面的例子就有一点像存放User类的实例同样子。
key:键名称
field:成员名
value:成员的值
语法:
HGET key field
语法:
HKEYS key
语法:
HVALS key
语法:
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是属于数据层的。
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 key value [value ...]
lpush就是从左边口进入。因此就 a进完 ,b在进,b进完了c进。以此类推。这个时候咱们要以看到列表以下
左边进入--> f-e-d-c-b-a
语法:
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了。
他是一个无序的,同时他不能有重复。
数据结果:你能够理解为一个箱子。东西随便放。但不能重复。
内部编码:他有俩种:一是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 key member [member ...]
笔者就不说明了。member就是相对应的成员值。
语法:
SMEMBERS key
笔者分别显示出三个的内部编码。发现只有当集合里面所有是整数的时候,内部编码是intset。其余都是hashtable。
大家能够这样子里面集合类型是无序的。为了让他有序,把集合类型的数据结构里面加入值来表示他的顺序。
数据结构:一样子的箱子。只是在放入这个箱子的东西。必须贴上相关的数字标签。
内部编码:有俩种:一种是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
看到了果真要一个数字。同时咱们能够到他的俩种内部编码。