Redis对象
typedef struct redisObject{
//类型
unsigned type:4;
//编码
unsigned encoding:4;
//指向底层数据结构的指针
void *ptr;
//引用计数
int refcount;
//记录最后一次被程序访问的时间
unsigned lru:22;
}robj
type : 五大数据类型(字符串,列表,集合)
encoding:指的是每种数据结构存储的不同数据(例如字符串可以存储字符类型,也可以存储数值类型).也用来数据类型的不同实现方式(list的压缩列表实现和双端链表实现).
prt : 指向的是底层数据结构的物理存储地址
String(字符串)
定义
字符串,能保存任何类型的数据,包括二进制数据,最大512M(单个的key-value)
所有的key都是string类型,另外其他数据结构的构成元素也是字符串
127.0.0.1:6379> set key1 v1 # 设置值
127.0.0.1:6379> get key1 # 获取值
"v1"
127.0.0.1:6379> keys * # 获取所有的key
1) "key1"
2) "views"
127.0.0.1:6379> exists key1 # 判断是否存在指定key
(integer) 1
127.0.0.1:6379> append key1 "appendcontent" #追加字符串
(integer) 20
127.0.0.1:6379> get key1
"v1helloappendcontent"
incr #+1
decr #-1
INCRBY views 10 # 对指定key+指定数量
DECRBY view 5 # 对指定key -指定数量
GETRANGE key1 0 3 # 截取字符串[0,3]的字符
SETRANGE key1 1 xxx # 从指定位置开始替换为 指定字符串
####################################################################################
# setex(set with expire) # 设置过期时间
# setnx(set if not exit) # 不存在设置
setex key3 30 "hellow" # 设置key3 的值喂hello,30秒之后过期
setnx mykey "redis" # 如果mykey不存在,创建mykey
setnx mykey "MongoDB" # 如果mykey存在,创建失败
####################################################################################
mset
mget
mset k1 v1 k2 v2 k3 v3 # 同时设置多个值
mget ke1 k2 k3 #同时获取多个值
msetnx k1 v1 k4 v4 # 此操作是原子性操作,要莫一起成功,要莫一起失败
# 对象
# key设计方法: user:{id}:{field}, 可以使用这种方法在redis使用key
set user:1 {name:zhangsanm age:3} # 设置一个user:1 对象值喂json字符来保存一个对象
mset user:1:name zhangsan user:1:age 2
####################################################################################
getset # 先get然后再set
127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb
"redis"
127.0.0.1:6379> get db
"mongodb"
String类似的使用场景:value出了我们的字符串还可以是我们的数字
- 计数器
- 统计多单位的数量
- 粉丝数
- 对象缓存存储
List
定义
list:列表,简单的字符串列表,按照插入顺序排序
可以头添加和尾添加,底层使用链表实现
格式: lpush name value1 value2…
####################################################################################
127.0.0.1:6379> LPUSH list one # 将一个值或者多个值插入到list中
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1 # 获取list中的值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> RPush list rightr # 将一个值或者多个值,插入到列表右(尾部)
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1 # 通过区间获取具体的值
1) "three"
2) "two"
3) "one"
4) "rightr"
####################################################################################
LPOP
RPOP
Lindex
LPOP list # 移除list的左(头部数据)
RPOP list # 移除list的右(尾部数据)
Lindex list # 列出list长度
Lrem list two # 移除指定
ltrim mylist 1 2 # 通过下标截取指定的长度,list已经发生改变,截取了剩下的元素
消息排列,消息队列(Lpush Rpop)
hset
定义
set:集合,无序,成员唯一
格式: sadd name value1 value2…
####################################################################################
127.0.0.1:6379> sadd myset "hello" # set集合中添加元素
127.0.0.1:6379> smembers myset # 查看指定set的所有值
127.0.0.1:6379> sismember myset world # 查看set中是否存在key
127.0.0.1:6379> scard myset # 获取set集合内元素个数
127.0.0.1:6379> srem myset hello # 移除元素中指定元素
127.0.0.1:6379> SRANDMEMBER myset
"guan"
####################################################################################
将一个指定的值,移动到另一个集合中
smove myset myset2 "hello" # 将一个指定的值,移动到另外一个set集合
####################################################################################
数字集合类
- 差集
- 交集
- 并集
SDIFF key1 key2 # 差集
SINTER key1 key2 # 交集
SUNION key1 key2 # 并集
Hash
Map集, key-map。hset是一个map集合, 本质和String没有太大的区别,是一个简单的key-value
哈希类型,是一个string类型的field和value的映射表(参考Map,name指的是数据类型的名称,下同)
格式: hmset name key1 value1 key2 value2…
不能存储相同的元素
ypedef struct dictht{
//哈希表数组
dictEntry **table;
//哈希表大小
unsigned long size;
//哈希表大小掩码,用于计算索引值 总是等于 size-1
unsigned long sizemask;
//该哈希表已有节点的数量
unsigned long used;
}dictht;
typedef struct dictEntry{
//键
void *key;
//值
union{
void *val;
uint64_tu64;
int64_ts64;
}v;
//指向下一个哈希表节点,形成链表,链地址法解决哈希冲突
struct dictEntry *next;
}dictEntry;
收缩和扩容
二倍扩容/收缩.对每一个元素重新哈希后放入新的内存空间,然后将原内存空间释放.
负载因子 = 哈希表大小/数组长度
执行磁盘访问时(BGSAVE和BGREWRITEAOF),负载因子大于5才会扩容,否则大于1就会扩容.
127.0.0.1:6379> hset myhash field1 guan # set一个具体 key-value
(integer) 1
127.0.0.1:6379> hget myhash field1 # 获取一个字段值
"guan"
127.0.0.1:6379> hmset myhash field1 hello field2 world # set多个key -value
OK
127.0.0.1:6379> hmget myhash field1 field2 # 获取多个字段值
1) "hello"
2) "world"
127.0.0.1:6379> hgetall myhash # 获取全部字段值
1) "field1"
2) "hello"
3) "field2"
4) "world"
Zset
定义
有序集和,每一个value都对应一个score(double类型)用以排序
格式: zadd name score1 value1 score2 value2…
zset的成员是唯一的,但分数(score)却可以重复
使用了跳表进行数据结构存储