技术标签: redis
| 命令 | 说明 | 时间复杂度 |
|---|---|---|
| keys[pattern] | 遍历所有key | O(N) |
| dbsize | 获取keys的大小 | O(1) |
| exists | 检查key是否存在 | O(1) |
| del key … | 删除指定key-value(可多个) | O(1) |
| expire key second(秒) | key在second秒后过期 | O(1) |
| ttl key | 查看key剩余的过期时间,该key有设置过期时间,返回剩余秒数,该key不存在返回-2该key存在并未设置过期时间返回-1 | O(1) |
| persist key | 去掉key的过期时间 | O(1) |
| type key | 返回key的value类型,若无类型返回none | O(1) |
注意:keys命令一般不在生产环境中使用,会造成性能上以及效率问题,毕竟redis它是一个单线程。
演示
127.0.0.1:7777> set hello word
OK
127.0.0.1:7777> set php good
OK
127.0.0.1:7777> set java best
OK
127.0.0.1:7777> keys *
1) "java"
2) "hello"
3) "php"
127.0.0.1:7777> keys p[h]?
1) "php"
127.0.0.1:7777> dbsize
(integer) 3
127.0.0.1:7777> exists php
(integer) 1
127.0.0.1:7777> del php java
(integer) 2
127.0.0.1:7777> keys *
1) "hello"
127.0.0.1:7777> expire hello 20
(integer) 1
127.0.0.1:7777> ttl hello
(integer) 16
127.0.0.1:7777> ttl hello
(integer) 12
127.0.0.1:7777> ttl hellos
(integer) -2
127.0.0.1:7777> persist hello
(integer) 1
127.0.0.1:7777> ttl hello
(integer) -1
127.0.0.1:7777> type hello
string
图示:
例如: hash数据结构中有hashtable和ziplist, 在hashtable达到一定的容量时,会自动转换成ziplist进行压缩。
redisObject
单线程在程序执行时,所在的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会一个一个的执行。
1.一次只能运行一条命令
2.拒绝长(慢)命令(以下命令,千万不要在正式环境中使用)
结构
| key | value |
|---|---|
| hello | world |
| counter | 1 |
| bits | 101111101110 |
value可以是字符串(JSON)、数字、二进制
API
| 命令 | 说明 | 时间复杂度 |
|---|---|---|
| get key | 获取key对应的value | O(1) |
| set key value | 设置key value(不管key是否存在) | O(1) |
| setnx key value | key不存在,才设置 | O(1) |
| set key value xx | key存在,才设置 | O(1) |
| del key… | 删除key-value(可以多个) | O(1) |
| incr key | key自增1,如果key不存在,自增后get(key) = 1 | O(1) |
| decr key | key自减1,如果key不存在,自减后get(key) = 1 | O(1) |
| incrby key k | key自增k,如果key不存在,自增后get(key) = k | O(1) |
| decrby key k | key自减k,如果key不存在,自减后get(key) = k | O(1) |
| mget key1 key2 key3 … | 批量获取key,原子操作 | O(n) |
| mset key1 val1 key2 val2 … | 批量设置key-value | O(1) |
| getset key newvalue | set key newvalues设置新的value并返回旧的value | O(1) |
| append key value | 将value追加到旧的value | O(1) |
| strlen key | 返回字符串长度(注意中文,utf-8的有三个字节) | O(1) |
| incrbyfloat key 3.5 | 在key对应的value增加3.5 | O(1) |
| getrange key start end | 获取字符串指定下标所有的值 | O(1) |
| setrange key index value | 获取指定下标所有对应的值 | O(1) |
演示
127.0.0.1:7777> set hello world
OK
127.0.0.1:7777> get hell
(nil)
127.0.0.1:7777> get hello
"world"
127.0.0.1:7777> del hello
(integer) 1
127.0.0.1:7777> get hello
(nil)
127.0.0.1:7777> get counter
(nil)
127.0.0.1:7777> incr counter
(integer) 1
127.0.0.1:7777> get counter
"1"
127.0.0.1:7777> incrby counter 99
(integer) 100
127.0.0.1:7777> get counter
"100"
127.0.0.1:7777> decr counter
(integer) 99
127.0.0.1:7777> get counter
"99"
127.0.0.1:7777> decrby counter 100
(integer) -1
127.0.0.1:7777> get counter
"-1"
127.0.0.1:7777> exists php
(integer) 0
127.0.0.1:7777> set php good
OK
127.0.0.1:7777> setnx php bad
(integer) 0
127.0.0.1:7777> set php best xx
OK
127.0.0.1:7777> get php
"best"
127.0.0.1:7777> exists java
(integer) 0
127.0.0.1:7777> setnx java best
(integer) 1
127.0.0.1:7777> set java easy xx
OK
127.0.0.1:7777> get java
"easy"
127.0.0.1:7777> set hello world
OK
127.0.0.1:7777> getset hello php
"world"
127.0.0.1:7777> get hello
"php"
127.0.0.1:7777> append hello ,php
(integer) 7
127.0.0.1:7777> get hello
"php,php"
127.0.0.1:7777> strlen hello
(integer) 7
127.0.0.1:7777> set hello 陈乔雄
OK
127.0.0.1:7777> strlen hello
(integer) 9
127.0.0.1:7777> set count 1
OK
127.0.0.1:7777> get count
"1"
127.0.0.1:7777>incrbyfloat count 2.5
"3.5"
127.0.0.1:7777>set name joemale
OK
127.0.0.1:7777>get name
"joemale"
127.0.0.1:7777>getrange name 0 3
"joem"
127.0.0.1:7777>setrange name 0 h
(integer) 7
127.0.0.1:7777>get name
"hoemale"
n次get操作和1次mget操作的区别
图示:
实战
incr userid:pageview -- 主要是redis是单线程,所有无竞争。
incr id
哈希键值结构
特点
API
| 命令 | 说明 | 时间复杂度 |
|---|---|---|
| hget key field | 获取hash key对应field的value | O(1) |
| hset key field value | 设置hash key对应field的value | O(1) |
| hexists key field | 判断hash key对应的field是否存在 | O(1) |
| hlen key | 获取hash key的field数量 | O(1) |
| hmget key field1 field2 … | 获取hash key对应一批的field | O(N) |
| hmset key field1 value1 field2 value2 … | 设置hash key对应一批的field value | O(N) |
| hgetall key | 获取hash key对应所有field value | O(N) |
| hvals key | 获取hash key对应所有field的value | O(N) |
| hkeys key | 获取hash key对应所有field | O(N) |
| hsetnx key field value | 设置hash key对应的field value(如果field已经存在则设置失败) | O(1) |
| hincrby key field count | 设置hash key对应field的value自增count(负数则自减) | O(1) |
| hincrbyfloat key field floatCount | 设置hash key对应field的value自增浮点数floatCount(负数则自减) | O(1) |
# 小心使用hgetall(牢记redis是单线程)
演示
127.0.0.1:7777> hset user1 age 26
(integer) 1
127.0.0.1:7777> hset user1 name chenqiaoxiong
(integer) 1
127.0.0.1:7777> hget all user1
(nil)
127.0.0.1:7777> hgetall user1
1) "age"
2) "26"
3) "name"
4) "wujunqi"
127.0.0.1:7777> hdel user1 age
(integer) 1
127.0.0.1:7777> hgetall user1
1) "name"
2) "wujunqi"
127.0.0.1:7777> hget user1 name
"wujunqi"
127.0.0.1:7777> hexists user1 name
(integer) 1
127.0.0.1:7777> hlen user1
(integer) 1
127.0.0.1:7777> hmset user2 name xiaoming age 26
OK
127.0.0.1:7777> hmget user2 name age
1) "xiaoming"
2) "26"
127.0.0.1:7777> hgetall user2
1) "name"
2) "xiaoming"
3) "age"
4) "26"
127.0.0.1:7777> hvals user2
1) "xiaoming"
2) "26"
127.0.0.1:7777> hkeys user2
1) "name"
2) "age"
127.0.0.1:7777> hincrby user age 2
(integer) 2
127.0.0.1:7777> hgetall user2
1) "name"
2) "xiaoming"
3) "age"
4) "26"
127.0.0.1:7777> hincrby user2 age 2
(integer) 28
127.0.0.1:7777> hgetall user2
1) "name"
2) "xiaoming"
3) "age"
4) "28"
127.0.0.1:7777> hincrbyfloat user2 age 2.0
"30"
127.0.0.1:7777> hincrbyfloat user2 age 2.5
"32.5"
127.0.0.1:7777> hgetall user2
1) "name"
2) "xiaoming"
3) "age"
4) "32.5"
列表结构
特点
API
| 命令 | 说明 | 时间复杂度 |
|---|---|---|
| rpush key value1 value2 … | 从列表右边插入(1-N个) | O(1-N) |
| lpush key value1 value2 … | 从列表左边插入(1-N个) | O(1-N) |
| linsert key before/after value newValue | 在list指定的值前/后插入newValue | O(N) |
| lpop key | 从列表左侧弹出一个item(相当于删除左侧的value) | O(1) |
| rpop key | 从列表右侧弹出一个item(相当于删除右侧的value) | O(1) |
| lrem key count value | 1、count>0则从左到右,删除最多count个value相等项 2、count<0则从右到左,删除最多count个value相等项 count=0则删除所有value相等项 |
O(N) |
| ltrim key start end | 按照索引范围修剪列表(类似于只保存start end范围的item,其余进行删除) | O(N) |
| lrange key start end | 获取列表指定索引范围所有item(包含end),下标:从右往左算是-1 -2,从左往右算是0 1 2 … | O(N) |
| lindex key index | 获取列表指定索引的item | O(1) |
| llen key | 获取列表长度 | O(1) |
| lset key index newValue | 设置列表指定索引值为newValue | O(N) |
| blpop key timeout | lpop阻塞版本,timeout是阻塞超时时间,timeout=0为永远阻塞 | O(1) |
| brpop key timeout | rpop阻塞版本,timeout是阻塞超时时间,timeout=0为永远阻塞 | O(1) |
blpop/brpop它是 RPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BRPOP 命令阻塞,直到等待超时或发现可弹出元素为止。
演示
127.0.0.1:7777> rpush list1 a b c d
(integer) 4
127.0.0.1:7777> lpush list1 e f g h i
(integer) 9
127.0.0.1:7777> lrange list1 0 -1
1) "i"
2) "h"
3) "g"
4) "f"
5) "e"
6) "a"
7) "b"
8) "c"
9) "d"
127.0.0.1:7777> linsert list1 before i wu
(integer) 10
127.0.0.1:7777> lrange list1 0 -1
1) "chen"
2) "i"
3) "h"
4) "g"
5) "f"
6) "e"
7) "a"
8) "b"
9) "c"
10) "d"
127.0.0.1:7777> linsert list1 after i qiao
(integer) 11
127.0.0.1:7777> lrange list1 0 -1
1) "chen"
2) "i"
3) "qiao"
4) "h"
5) "g"
6) "f"
7) "e"
8) "a"
9) "b"
10) "c"
11) "d"
127.0.0.1:7777> lpop list1
"chen"
127.0.0.1:7777> rpop list1
"d"
127.0.0.1:7777> lrange list1 0 -1
1) "i"
2) "qiao"
3) "h"
4) "g"
5) "f"
6) "e"
7) "a"
8) "b"
9) "c"
127.0.0.1:7777> lrem list1 1 i
(integer) 1
127.0.0.1:7777> lrange list1 0 -1
1) "qiao"
2) "h"
3) "g"
4) "f"
5) "e"
6) "a"
7) "b"
8) "c"
127.0.0.1:7777> rpush list1 c c c c c
(integer) 13
127.0.0.1:7777> ltrem list1 -3 c
(error) ERR unknown command 'ltrem'
127.0.0.1:7777> lrem list1 -3 c
(integer) 3
127.0.0.1:7777> lrange list1 0 -1
1) "qiao"
2) "h"
3) "g"
4) "f"
5) "e"
6) "a"
7) "b"
8) "c"
9) "c"
10) "c"
127.0.0.1:7777> lindex list 0
(nil)
127.0.0.1:7777> lindex list1 0
"qiao"
127.0.0.1:7777> llen list1
(integer) 10
127.0.0.1:7777> lset list 0 chen
(error) ERR no such key
127.0.0.1:7777> lset list1 0 chen
OK
127.0.0.1:7777> lrange list1 0 -1
1) "chen"
2) "h"
3) "g"
4) "f"
5) "e"
6) "a"
7) "b"
8) "c"
9) "c"
10) "c"
127.0.0.1:7777>lpush list2 A a1 a2 a3 a4
(integer)5
127.0.0.1:7777>blpop list2 100
1)"list2"
2)"a4"
127.0.0.1:7777>brpop list2 100
1)"list2"
2)"A"
127.0.0.1:7777>brpop list2 100
(nil)
(100.10s)
应用
1、lpush + lpop = Stack
2、lpush + rpop = Queue
3、lpush + ltrim = Capped Collection
4、lpush + brpop = Message Queue
实战
定义
Redis的set是String类型的无序集合,集合成员是唯一的,
这就意味集合中不能出现重复的数据,Redis中集合是通过
哈希码来实现的,所有添加,删除,查找的时间复杂度都是O(1).
特点
API
| 命令 | 说明 | 时间复杂度 |
|---|---|---|
| sadd key element | 向集合key添加element(如果element已经存在则添加失败) | O(1) |
| srem key element | 将集合key中的element移除掉 | O(1) |
| scard key | 计算集合大小 | O(1) |
| sismember key element | 判断element是否在集合中 | O(1) |
| srandmember key count | 从集合中随机挑出count元素 | O(1) |
| spop key | 从集合中随机弹出一个元素 | O(1) |
| smembers key | 获取集合所有元素 | O(1) |
| 命令 | 说明 | 时间复杂度 |
|---|---|---|
| sdiff key1 key2 | 差集 | O(1) |
| sinter key1 key2 | 交集 | O(1) |
| sunion key1 key2 | 并集 | O(1) |
| sdiff/sinter/sunion + store destkey key1 key2 | 将差集、交集、并集保存在destkey中 | O(1) |
sdiff/sinter/sunion + store destkey : 将给定(key1 key2)集合之间的差集/交集/并集存储在指定的集合(destkey)中。如果指定的集合 key 已存在,则会被覆盖。
注意
演示
127.0.0.1:7777> sadd set1 a b c d
(integer) 4
127.0.0.1:7777> srem set1 a
(integer) 1
127.0.0.1:7777> smembers set1
1) "d"
2) "c"
3) "b"
127.0.0.1:7777> scard set1
(integer) 3
127.0.0.1:7777> sismember set1 d
(integer) 1
127.0.0.1:7777> srandmember set1 2
1) "d"
2) "b"
127.0.0.1:7777> srandmember set1 2
1) "b"
2) "c"
127.0.0.1:7777> spop set1
"c"
127.0.0.1:7777> smembers set1
1) "d"
2) "b"
127.0.0.1:7777> srem set1 d
(integer) 1
127.0.0.1:7777> smembers set1
1) "b"
127.0.0.1:7777> sadd set1 1 2 3 4 5
(integer) 5
127.0.0.1:7777> sadd set2 a b c 12 8 9 1 2
(integer) 8
127.0.0.1:7777> sdiff set1 set2
1) "3"
2) "4"
3) "5"
127.0.0.1:7777> sinter set1 set2
1) "2"
2) "b"
3) "1"
127.0.0.1:7777> sunion set1 set2
1) "5"
2) "2"
3) "4"
4) "1"
5) "a"
6) "8"
7) "3"
8) "b"
9) "9"
10) "12"
11) "c"
127.0.0.1:7777>del set1 set2
(integer)2
127.0.0.1:7777>sadd set1 a b c d
(integer)4
127.0.0.1:7777>sadd set2 d e f g
(integer)4
127.0.0.1:7777>sdiff set1 set2
1) "a"
2) "b"
3) "c"
127.0.0.1:7777>sinter set1 set2
1) "d"
127.0.0.1:7777>sunion set1 set2
1) "d"
2) "c"
3) "b"
4) "g"
5) "a"
6) "e"
7) "f"
127.0.0.1:7777>keys *
1) "set1"
2) "set2"
127.0.0.1:7777>sunionstore destkey set1 set2
(integer) 7
127.0.0.1:7777>keys *
1) "set1"
2) "set2"
3) "destkey"
127.0.0.1:7777>smembers destkey
1) "d"
2) "c"
3) "b"
4) "g"
5) "a"
6) "e"
7) "f"
实战
应用
sadd = tagging
spop/srandmember = random item
sadd + sinter = social graph
定义
Redis有序集合和集合一样也是String类型元素的集合,且不允许重复的成员,不同的是每个元素
都会关联一个double类型分数,redis正是通过分数来为集合中的成员进行从小到大的排序,有序
集合的成员是唯一的,但分数(score)却可以重复
API
| 命令 | 说明 | 时间复杂度 |
|---|---|---|
| zadd key score element | 添加score和element | O(logN) |
| zrem key element(可以是多个) | 将集合中的element移除掉 | O(1) |
| zscore key element | 返回元素的分数 | O(1) |
| zincrby key increScore element | 增加或减少元素的分数(increScore) | O(1) |
| zcard key | 返回元素的总个数 | O(1) |
| zrank key element | 返回element元素的索引 | O(1) |
| zrange key start end [WITHSCORES] | 返回指定索引范围内的升序元素(分值) | O(logN + m) |
| zrangebyscore key minScore maxScore | 返回指定分数范围内的升序元素 | O(logN + m) |
| zcount key minScore maxScore | 返回有序集合内在指定分数范围的个数 | O(logN + m) |
| zremrangebyrank key state end | 删除指定排名内的升序元素 | O(logN + m) |
| zremrangebyscore key minScore maxScore | 删除指定分数内的升序元素 | O(logN + m) |
| zinterstore desination numbers(表示key的个数) key key1 … | 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合key中 | |
| zunionstore desination numbers key key1 … | 计算给定的一个或多个有序集的并集,并存储在新的key中 |
演示
127.0.0.1:7777>zadd myzset 1 v1
(integer) 1
127.0.0.1:7777>zadd myzset 10 v2 20 v3
(integer) 2
127.0.0.1:7777>zscore myzset v2
"10"
127.0.0.1:7777>zrem myzset v2
(integer) 1
127.0.0.1:7777>zincrby myzset 10 v3
"30"
127.0.0.1:7777>zcard myzset
(integer) 2
127.0.0.1:7777>zrank myzset v3
(integer) 1
127.0.0.1:7777>zrange myzset 0 -1
1) "v1"
2) "v2"
127.0.0.1:7777>zadd myzset 10 v2
(integer) 1
127.0.0.1:7777>zrangebyscore myzset 1 10
1) "v1"
2) "v2"
127.0.0.1:7777>zcount myzset 1 10
(integer) 2
127.0.0.1:7777>zremrangebyscore myzset 1 10
(integer) 2
127.0.0.1:7777>zremrangebyrank myzset 0 -1
(integer) 1
127.0.0.1:7777>zrange myzset 0 -1
(empty list or set)
127.0.0.1:7777>zadd myzset1 10 v1 20 v2 30 v3
(integer) 3
127.0.0.1:7777>zadd myzset2 5 v1 25 v2 35 v3 40 v4
(integer) 4
127.0.0.1:7777>zrange myzset1 0 -1 withscores
1) "v1"
2) "10"
3) "v2"
4) "20"
5) "v3"
6) "30"
127.0.0.1:7777>zrange myzset2 0 -1 withscores
1) "v1"
2) "5"
3) "v2"
4) "25"
5) "v3"
6) "35"
7) "v4"
8) "40"
127.0.0.1:7777>zinterstore myzset3 2 myzset1 myzset2
(integer) 3
127.0.0.1:7777>zrange myzset3 0 -1 withscores
1) "v1"
2) "15"
3) "v2"
4) "45"
5) "v3"
6) "65"
127.0.0.1:7777>zunionstore myzset4 2 myzset1 myzset2
(integer) 4
127.0.0.1:7777>zrange myzset4 0 -1 withscore
1) "v1"
2) "15"
3) "v4"
4) "40"
5) "v2"
6) "45"
7) "v3"
8) "65"
应用
来源:网络
Redis有五种基本数据类型,String(字符串),Hash(哈希),List(链表),Set(集合),ZSet(有序集合) 1、String是redis当中最常用的基本类型,常用命令: 1、set key value [EX seconds] [PX milliseconds] [NX|XX] &...
列表(类队列) 数据结构:有序、可重复 基本命令: 例子 阻塞式的列表弹出命令及列表之间移动元素的命令 blpop blpop keyname1 keyname2 timeout 解释: 非阻塞式:从左向右依次检查,如果发现列表不为空则弹出该列表的最左端的元素 阻塞式:从左向右依次检查,如果发现所有列表为空或者不存在,则等待时间timeout(s),期间如果其他客户端往列表中插入元素,该客户端则弹...
String类型 1. 内存存储模型 2. 常用操作命令 命令 说明 set 设置一个key/value get 根据key获得对应的value mset 一次设置多个key value mget 一次获得多个key的value getset 获得原始key的值,同时设置新值 strlen 获得对应key存储value的长度 append 为对应key的value追加内容 getrange 索引0...
文章目录 String hash list set sortedset String setex key 过期时间(单位秒) 值 例如上图 setex c 100 c 设置key为c的值为c , 过期时间为100s psetex key 过期时间(单位毫秒) 值 psetex d 10000 d 10000毫秒为10s ttl为查询还有多久时间过期, 单位为秒 获取字符串的范围getrange g...
每种类型的对象都至少使用了两种不同的编码: 其中REDIS_ENCODING_ENBSTR和REDIS_ENCODING_RAW都是用于保存字符串值,其中embstr编码是专门用于保存短字符串的一种优化编码方式,这种编码和raw编码一样,都使用redisObject结构和sdshdr结构结构来表示字符串对象,但raw编码会调用两次内存分配函数来分别创建redisObject结构和sdshdr结构,...
一、前言 Redis有五种基本数据结构:字符串、hash、set、zset、list。下面解释下载Redis 3.0.6版本中底层是怎样实现他们的。 二、动态字符串SDS SDS是“simple dynamic string”的缩写。Redis中所有场景出现的字符串,基本都是有SDS来实现的: 所有非数字的key, 如:set msg “hello”...
redis六种底层数据结构 Redis作为一个开源的用C编写的非关系型数据库,基于优秀的CRUD效率,常用于软件系统的缓存,其本身提供了以下五种数据格式: string:字符串 list:列表 hash:散列表 set:无序集合 zset:有序集合 bstring 因为redis使用c语言开发,所以自然没有java和c++的那些字符串类库,在redis中,其自己定义了一种字符串格式,叫做SDS(S...
Redis 数据类型分为:字符串类型、散列类型、列表类型、集合类型、有序集合类型。 一、String 是redis中最基本的数据类型,一个key对应一个value。 String类型是二进制安全的,意思是 redis 的 string 可以包含任何数据。如数字,字符串,jpg图片或者序列化的对象。 二、hash 指value本身又是一种键值对结构,如 value={{field1,value1},...
redis五种数据结构底层实现 String list hash set zset 对应结构的讲解 动态字符串SDS 空间预分配 惰性空间释放 int 双向链表 ziplist 哈希表 intset 跳表 性质 String 其中:embstr和raw都是由SDS动态字符串构成的。唯一区别是:raw是分配内存的时候,redisobject和 sds 各分配一块内存,而embstr是redisobj...
开头 redis的五种数据结构分别是string,hash,list,set,zset。它们内部编码其实是有多种实现的。 数据结构 内部编码 String int,raw,embstr hash ziplist,hashtable list ziplist,linkedlist,quicklist set intset,hashtable zset ziplist,skiplist redis可以...
This is another variation of an old theme: The initialization order of static objects in different translation units is not defined. Below is a stripped-down example of my particular scenario. The cla...
I use Tamir.SharpSSH library to make my SFTP operations. I can upload file from client, delete or list files located in an SFTP server directory. But I cannot find how to append a text file. I don't w...
I've been struggling days just to upload my nodejs app on a cloud and i tried openshift because it seems nice and i've commited my folder and files into my github, i've created a ssh key and everythin...
Can one create .APK file from set of files/folder inside Android Application? (for example, inside application like fdroid) For example, I have uncompressed files of my apk file and I want to recreate...
I have multiple audio files which are held in several subfolders in my working directory. I have a loop which reads in the first minute of each file and then saves them as a new file. Now, there are a...