1 NoSQL型数据库
1.1简介
NoSQL(NoSQL = *Not Only SQL* ),意即“不仅仅是SQL”,泛指****非关系型的数据库****。
NoSQL 不依赖业务逻辑方式存储,而以简单的key-value模式存储。因此大大的增加了数据库的扩展能力。
l 不遵循SQL标准。
l 不支持ACID。
l 远超于SQL的性能。
适用场景:
l 对数据高并发的读写
l 海量数据的读写
l 对数据高可扩展性的
不适用场景:
l 需要事务支持
l 基于sql的结构化查询存储,处理复杂的关系,需要即席查询。
l (用不着sql的和用了sql也不行的情况,请考虑用NoSql)
1.2 常见的NoSQL型数据库
1)Memcache
很早出现的NoSql数据库数据都在内存中,一般不持久化,支持简单的key-value模式,支持类型单一,一般是作为缓存数据库辅助持久化的数据库
2)Redis
几乎覆盖了Memcached的绝大部分功能,数据都在内存中,支持持久化,主要用作备份恢复,除了支持简单的key-value模式,还支持多种数据结构的存储,比如 list、set、hash、zset等。一般是作为缓存数据库辅助持久化的数据库
3)MongoDB
高性能、开源、模式自由(schema free)的文档型数据库,数据都在内存中, 如果内存不足,把不常用的数据保存到硬盘,虽然是key-value模式,但是对value(尤其是json)提供了丰富的查询功能,支持二进制数据及大型对象,可以根据数据的特点替代RDBMS ,成为独立的数据库。或者配合RDBMS,存储特定的数据。
4)大数据时代数据库
①行式数据库
②列式数据库
列式数据库包括:
1.3.2.1.Hbase
HBase是Hadoop项目中的数据库。它用于需要对大量的数据进行随机、实时的读写操作的场景中。
HBase的目标就是处理数据量非常庞大的表,可以用普通的计算机处理超过10亿行数据,还可处理有数百万列元素的数据表。
1.3.2.2.Cassandra
Apache Cassandra是一款免费的开源NoSQL数据库,其设计目的在于管理由大量商用服务器构建起来的庞大集群上的海量数据集(数据量通常达到PB级别)。在众多显著特性当中,Cassandra最为卓越的长处是对写入及读取操作进行规模调整,而且其不强调主集群的设计思路能够以相对直观的方式简化各集群的创建与扩展流程。
2 redis数据库安装与启动
安装在linux centos7下
2.1 安装c语言环境(gcc)
[root@localhost opt]# gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
Copyright ? 2015 Free Software Foundation, Inc.
本程序是自由软件;请参看源代码的版权声明。本软件没有任何担保;
包括没有适销性和某一专用目的下的适用性担保。
如果没有,就安装
yum install centos-release-scl scl-utils-build
yum install -y devtoolset-8-toolchain
scl enable devtoolset-8 bash
2.2安装redis
将redis-6.2.1.tar.gz 传输到 /opt下
所需要文件的网盘链接:
https://www.aliyundrive.com/s/1po4Rz9jBrE
提取码:3st5
1.解压
由于网盘不支持分享tar.gz类型的文件,我直接将解压后的文件夹发送过来,不知道能不能用,如果不能用,请联系我
[root@localhost opt]# ^C
[root@localhost opt]# tar -zxvf redis-6.2.1.tar.gz
redis-6.2.1/
redis-6.2.1/.github/
redis-6.2.1/.github/ISSUE_TEMPLATE/
redis-6.2.1/.github/ISSUE_TEMPLATE/bug_report.md
redis-6.2.1/.github/ISSUE_TEMPLATE/crash_report.md
redis-6.2.1/.github/ISSUE_TEMPLATE/feature_request.md
redis-6.2.1/.github/ISSUE_TEMPLATE/other_stuff.md
redis-6.2.1/.github/ISSUE_TEMPLATE/question.md
redis-6.2.1/.github/workflows/
redis-6.2.1/.github/workflows/ci.yml
redis-6.2.1/.github/workflows/daily.yml
2.编译(进入解压好的文件中)
[root@localhost opt]# cd redis-6.2.1/
[root@localhost redis-6.2.1]# make
cd src && make all
make[1]: 进入目录“/opt/redis-6.2.1/src”
CC Makefile.dep
make[1]: 离开目录“/opt/redis-6.2.1/src”
make[1]: 进入目录“/opt/redis-6.2.1/src”
…
INSTALL redis-check-rdb
INSTALL redis-check-aof
Hint: It’s a good idea to run ‘make test’ ;
Hint: It’s a good idea to run ‘make test’ 😉
make[1]: 离开目录“/opt/redis-6.2.1/src”
[root@localhost redis-6.2.1]# ^C
若出现错误:
[root@zy redis-3.2.5]# make
cd src && make all
make[1]: 进入目录/opt/ redis-3.2.5/src”
CC adlist.o
In file included from adList. c:34:0:
zmalloc .h:50:31:致命错误: j emalloc/jemalloc.h:没有那个文件或目录
#include <j emalloc/ j emalloc .h>
编译中断.
make[1]: *** [adlist.o] 错误1
make[1]: 离开目录/opt/ redis-3.2.5/src"
make:水水*
[all]错误2
这是没有准备好从语言环境导致的
解决:
检查gcc是否安装成功
[root@localhost opt]# gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
Copyright ? 2015 Free Software Foundation, Inc.
本程序是自由软件;请参看源代码的版权声明。本软件没有任何担保;
包括没有适销性和某一专用目的下的适用性担保。
清除残留的文件
make distclean
再次编译
make
3.安装
[root@localhost redis-6.2.1]# make install
cd src && make install
make[1]: 进入目录“/opt/redis-6.2.1/src”
CC Makefile.dep
make[1]: 离开目录“/opt/redis-6.2.1/src”
make[1]: 进入目录“/opt/redis-6.2.1/src”
Hint: It’s a good idea to run ‘make test’ 😉
INSTALL install
INSTALL install
INSTALL install
make[1]: 离开目录“/opt/redis-6.2.1/src”
[root@localhost redis-6.2.1]#
默认安装到
/usr/local/bin
2.3 启动
1.前台启动(不推荐)
进入/usr/local/bin目录下
[root@localhost bin]# redis-server
12409:C 03 Aug 2022 16:48:47.999 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
12409:C 03 Aug 2022 16:48:47.999 # Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=12409, just started
12409:C 03 Aug 2022 16:48:47.999 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
12409:M 03 Aug 2022 16:48:48.002 * Increased maximum number of open files to 10032 (it was originally set to 1024).
12409:M 03 Aug 2022 16:48:48.002 * monotonic clock: POSIX clock_gettime
2.后台启动(推荐)
1)拷贝一份redis.conf到其他目录
[root@localhost bin]# cd /opt
[root@localhost opt]# ll
总用量 1648860
drwxrwxr-x. 7 root root 4096 3月 2 2021 redis-6.2.1
-rw-r–r–. 1 root root 2438367 8月 3 16:22 redis-6.2.1.tar.gz
drwxr-xr-x. 2 root root 20 6月 1 09:28 rh
drwxr-xr-x. 2 root root 6 6月 1 08:43 tmp
[root@localhost opt]# cd redis-6.2.1/
[root@localhost redis-6.2.1]# ll
总用量 232
-rw-rw-r–. 1 root root 21594 3月 2 2021 README.md
-rw-rw-r–. 1 root root 92222 3月 2 2021 redis.conf
-rwxrwxr-x. 1 root root 275 3月 2 2021 runtest
-rwxrwxr-x. 1 root root 279 3月 2 2021 runtest-cluster
-rwxrwxr-x. 1 root root 1046 3月 2 2021 runtest-moduleapi
-rwxrwxr-x. 1 root root 281 3月 2 2021 runtest-sentinel
-rw-rw-r–. 1 root root 13768 3月 2 2021 sentinel.conf
drwxrwxr-x. 3 root root 12288 8月 3 16:45 src
drwxrwxr-x. 11 root root 182 3月 2 2021 tests
-rw-rw-r–. 1 root root 3055 3月 2 2021 TLS.md
drwxrwxr-x. 9 root root 4096 3月 2 2021 utils
[root@localhost redis-6.2.1]# cp redis.conf /etc/redis.conf
2)后台启动设置daemonize no改成yes
[root@localhost redis-6.2.1]# cd /etc
[root@localhost etc]# ll
[root@localhost etc]# vim redis.conf
3)在次进入 /usr/local/bin目录开启服务
[root@localhost etc]# cd /usr/local/bin
[root@localhost bin]# redis-server /etc/redis.conf
2.4 客户端访问
root@localhost bin]# redis-cli //客户端访问
127.0.0.1:6379> ping
PONG //表示正常
127.0.0.1:6379> exit //exit表示退出客户端
2.5 redis关闭服务
单实例关闭:redis-cli shutdown
也可以进入终端后再关闭 shutdown
多实例关闭,指定端口关闭:redis-cli -p 6379 shutdown
2.6 设置redis密码
redis加密码的方式一共有两种,前者属于一次性的,关闭后就不再生效了,后者属于永久性设置。
1.临时性设置
找到你redis的安装目录。运行redis-cli.exe。 如果提示“由于目标计算机积极拒绝,无法连接。”是由于你的redis服务没有正常运行导致的的
运行下面的指令
config set requirepass 123456
设置密码后,需要使用auth重新登录,我们继续输入
auth 123456
然后执行
config get requirepass
可以看到刚才的密码
但是这种做法有个弊端,就是一旦你关闭或者重启redis服务,那么设置的密码就不生效了。所以,你想设置长久密码推荐第二种。
2.永久设置密码
打开redis的文件夹。找到redis的配置文件:/etc/redis.conf。然后打开它。搜索”requirepass”, 这行代码原来是被注释掉的,我们取消注释,并在后面给他设置密码。设置完毕后,我们重启redis服务。
使用
auth redis123
config get requirepass
就可以看到刚才设置的密码了。
3 常用命令
3.1 key键操作
127.0.0.1:6379[15]> select 0 //选择要操作的数据库
OK
127.0.0.1:6379> keys * //查看当前库中所有的key
(empty array)
127.0.0.1:6379> set k1 lucy //添加key-value数据
OK
127.0.0.1:6379> set k2 mary
OK
127.0.0.1:6379> set k3 jack
OK
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
3) "k3"
127.0.0.1:6379> exists k1 //查看key为k1的数据是否存在
(integer) 1
127.0.0.1:6379> exists k1 k2 k3 //查看key为k1,k2,k3的数据存在几个
(integer) 3
127.0.0.1:6379> exists k1 k2 k3 k4
(integer) 3
127.0.0.1:6379> k1 k4
(error) ERR unknown command `k1`, with args beginning with: `k4`,
127.0.0.1:6379> exists k1 k4
(integer) 1
127.0.0.1:6379> type k2 //查看某个key的数据类型
string
127.0.0.1:6379> del k3 //直接删除
(integer) 1
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
127.0.0.1:6379> set k3 jack
OK
127.0.0.1:6379> unlink k3 //根据value选择非阻塞删除
(integer) 1
127.0.0.1:6379> expire k1 10 //设置某个key的过期时间,单位秒
(integer) 1
127.0.0.1:6379> ttl k1 //查看某个key还有多少时间过期,-1表示永不过期,-2表示已经过期
(integer) 6
127.0.0.1:6379> ttl k2
(integer) -1 //永不过期
127.0.0.1:6379> ttl k1
(integer) -2 //已经过期
127.0.0.1:6379> keys *
1) "k2"
127.0.0.1:6379>
127.0.0.1:6379> dbsize //查看当前数据库的key数量
(integer) 1
127.0.0.1:6379> flushdb //清空当前数据库
OK
127.0.0.1:6379> flushall //清空所有数据库,通杀
OK
127.0.0.1:6379>
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
127.0.0.1:6379> get k1 //根据key值得到value值
"v100"
127.0.0.1:6379> get k2
"v200"
127.0.0.1:6379> set k1 v1100 //如果key不存在就添加,如果存在就修改
OK
127.0.0.1:6379> get k1
"v1100"
127.0.0.1:6379> append k1 abc //根据key值在原有的字符串上追加一段字符串
(integer) 8 //返回追加后的总长度
127.0.0.1:6379>
127.0.0.1:6379> strlen k1 //查看指定ket值长度
(integer) 8
127.0.0.1:6379> setnx k1 v1 //添加一条数据,如果存在则添加失败
(integer) 0
127.0.0.1:6379> setnx k4 v4 //添加一条数据,如果存在则添加失败
(integer) 1
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 //一次性设置多条数据
OK
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
3) "k3"
127.0.0.1:6379> mget k1 k2 k3 //一次性查询多条数据
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k11 v11 k12 v12 k1 v11 //一次性添加多条数据,如果有一个已经存在,则全部添加失败,否则添加成功
(integer) 0
127.0.0.1:6379> msetnx k11 v11 k12 v12 k13 v13
(integer) 1
127.0.0.1:6379> set name lucymary
OK
127.0.0.1:6379> getrange name 0 3 //查看从索引0到3指定截取的字符串
"lucy"
127.0.0.1:6379> setrange name 3 abc //从指定索引开始修改字符串
(integer) 8
127.0.0.1:6379> get name
"lucabcry"
127.0.0.1:6379>
127.0.0.1:6379> setex age 20 value //在设置值的时候设置过期时间
OK
127.0.0.1:6379> ttl age
(integer) 15
127.0.0.1:6379> get age
"value"
127.0.0.1:6379> get age
(nil)
127.0.0.1:6379> get fill
(nil)
127.0.0.1:6379> getset name fill //以新值换旧值,设置了旧值,同时获得了新值
"lucabcry"
4 数据类型
4.1字符串
String的数据结构为简单动态字符串(Simple Dynamic String,缩写SDS)。是可以修改的字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配.
如图中所示,内部为当前字符串实际分配的空间capacity一般要高于实际字符串长度len。当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次只会多扩1M的空间。需要注意的是字符串最大长度为512M。
4.2List(列表)
单键多值
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。
4.2.1 常用命令
127.0.0.1:6379> lpush k1 v1 v2 v3 //添加一个列表并设置值,从左边开始放,可以理解为左边是栈的开口
(integer) 3
127.0.0.1:6379> lrange k1 0 -1 //0左边第一个,-1右边第一个,(0-1表示获取所有)
1) "v3"
2) "v2"
3) "v1"
127.0.0.1:6379> rpush k2 v1 v2 v3 //添加一个列表并设置值,从右边开始放,可以理解为右边是栈的开口
(integer) 3
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> lpop k1 //拿到最左边的值,也就是第一个值
"v3"
127.0.0.1:6379> lpop k2
"v1"
127.0.0.1:6379> rpop k1 //拿到最右边的值,也就是最后一个值,取完就不存在这个key了
"v1"
127.0.0.1:6379> rpop k2
"v3"
127.0.0.1:6379> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> rpush k2 v11 v22 v33
(integer) 3
127.0.0.1:6379> rpoplpush k1 k2 //从k1的最右边取值放到k2的最左边,也就是将k1的最后一个值放到k2的最前面
"v1"
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "v11"
3) "v22"
4) "v33"
127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v2"
127.0.0.1:6379> lindex k2 1 //获得index值为1的列表值,index从0开始,不是取出
"v11"
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "v11"
3) "v22"
4) "v33"
127.0.0.1:6379>
127.0.0.1:6379> llen k2 //查看指定列表的长度
(integer) 4
127.0.0.1:6379> linsert k2 before "v11" "newv11" //在指定value值的前面加上一个值
(integer) 5
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newv11"
3) "v11"
4) "v22"
5) "v33"
127.0.0.1:6379> linsert k2 after "v11" "newv11" //在指定value值的后面加上一个值
(integer) 6
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newv11"
3) "v11"
4) "newv11"
5) "v22"
6) "v33"
127.0.0.1:6379> linsert k2 before "v33" "newv11"
(integer) 7
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "newv11"
3) "v11"
4) "newv11"
5) "v22"
6) "newv11"
7) "v33"
127.0.0.1:6379> linsert k2 before "newv11" "new" //如果有多个相同的value值,默认插入到最左边在这个value值最之前
(integer) 8
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "new"
3) "newv11"
4) "v11"
5) "newv11"
6) "v22"
7) "newv11"
8) "v33"
127.0.0.1:6379> lrem k2 2 "newv11" //从左边开始,删除2个key值为newv11的数据
(integer) 2
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "new"
3) "v11"
4) "v22"
5) "newv11"
6) "v33"
127.0.0.1:6379> linsert k2 before v33 newv33
(integer) 7
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "new"
3) "v11"
4) "v22"
5) "newv11"
6) "newv33"
7) "v33"
127.0.0.1:6379> lset k2 1 new1 //将下标为1的位置value值设置为new1
OK
127.0.0.1:6379> lrange k2 0 -1
1) "v1"
2) "new1"
3) "v11"
4) "v22"
5) "newv11"
6) "newv33"
7) "v33"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379>
127.0.0.1:6379> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"
127.0.0.1:6379> lpush k1 v1 v2 v3
(integer) 6
127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"
4) "v3"
5) "v2"
6) "v1"
127.0.0.1:6379> lpush k1 v4 v5 v6
(integer) 9
127.0.0.1:6379> lrange k1 0 -1
1) "v6"
2) "v5"
3) "v4"
4) "v3"
5) "v2"
6) "v1"
7) "v3"
8) "v2"
9) "v1"
127.0.0.1:6379>
4.2.2 底层结构
List的数据结构为快速链表quickList。
首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也即是压缩列表。
它将所有的元素紧挨着一起存储,分配的是一块连续的内存。
当数据量比较多的时候才会改成quicklist。
因为普通的链表需要的附加指针空间太大,会比较浪费空间。比如这个列表里存的只是int类型的数据,结构上还需要两个额外的指针prev和next。
Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。
4.3set集合
Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。Redis的Set是string类型的无序集合。它底层其实是一个value为null的hash表,所以添加,删除,查找的复杂度都是O(1)。一个算法,随着数据的增加,执行时间的长短,如果是O(1),数据增加,查找数据的时间不变
4.3.1 常用命令
127.0.0.1:6379> sadd k1 v1 v2 v3 //添加一个set集合,并向里面复制
(integer) 3
127.0.0.1:6379> sadd k1 v1 v2 //如果指定set集合中已经存在,将不能添加
(integer) 0
127.0.0.1:6379> smembers k1 //查看指定set集合中所有在值,无序
1) "v3"
2) "v1"
3) "v2"
127.0.0.1:6379> sismember k1 v1 //判断指定集合中是否存在某个值
(integer) 1
127.0.0.1:6379> sismember k1 v4
(integer) 0
127.0.0.1:6379> scard k1 //查看set集合中的数据量
(integer) 3
127.0.0.1:6379> srem k1 v1 v2 //删除指定set集合中的指定value值
(integer) 2
127.0.0.1:6379> sadd k2 v1 v2 v3 v4
(integer) 4
127.0.0.1:6379> spop k2 //随机土出一个指定set集合中的一个值
"v1"
127.0.0.1:6379> smembers k2
1) "v3"
2) "v2"
3) "v4"
127.0.0.1:6379> spop k2 2 //随机土出一个指定set集合中的多个值
1) "v4"
2) "v3"
127.0.0.1:6379> smembers k2
1) "v2"
127.0.0.1:6379> srandmember k2 2 //随机获得一个2个value值,set集合中不会消失,不够2个,将会取出全部数据
1) "v2"
127.0.0.1:6379> srandmember k2 1
1) "v2"
127.0.0.1:6379>
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> sadd k2 v3 v4 v5
(integer) 3
127.0.0.1:6379> smove k1 k2 v3 //将k1中的v3值移动到k2中
(integer) 1
127.0.0.1:6379> smembers k1
1) "v1"
2) "v2"
127.0.0.1:6379> smembers k2
1) "v3"
2) "v5"
3) "v4"
127.0.0.1:6379> sadd k3 v4 v6 v7
(integer) 3
127.0.0.1:6379> sinter k2 k3 //获得两个set集合中的交集,两个集合值不变
1) "v4"
127.0.0.1:6379> smembers k2
1) "v3"
2) "v5"
3) "v4"
127.0.0.1:6379> smembers k3
1) "v7"
2) "v6"
3) "v4"
127.0.0.1:6379>
127.0.0.1:6379> sunion k2 k3 获得两个set集合中的并集,两个集合值不变
1) "v5"
2) "v4"
3) "v3"
4) "v7"
5) "v6"
127.0.0.1:6379> smembers k3
1) "v7"
2) "v6"
3) "v4"
127.0.0.1:6379> sdiff k2 k3 //获得两个set集合中的差集,两个集合值不变
1) "v3"
2) "v5"
127.0.0.1:6379> smembers k3
1) "v7"
2) "v6"
3) "v4"
127.0.0.1:6379> smembers k2
1) "v3"
2) "v5"
3) "v4"
4.3.2 底层结构
Set数据结构是dict字典,字典是用哈希表实现的。Java中HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。Redis的set结构也是一样,它的内部也使用hash结构,所有的value都指向同一个内部值。
4.4 hash
4.4.1 常用命令
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> hset user:1001 id 1 //添加一个key值为user:1001 的hash集合,属性为id
(integer) 1
127.0.0.1:6379> hset user:1001 name zhangsan
(integer) 1
127.0.0.1:6379> hget user:1001 id
"1"
127.0.0.1:6379> hget user:1001 name
"zhangsan"
127.0.0.1:6379> hmset user:1002 id 2 name lisi age 30 //hmset可以添加多个属性,添加一个key值为user:1001 的hash集合,属性为id,name
OK
127.0.0.1:6379> hget user:1002 id //获得指定hash集合中的指定属性
"2"
127.0.0.1:6379> hget user:1002 age
"30"
(integer) 0
127.0.0.1:6379> hexists user:name name //查看指定hash集合中的指定属性是否存在
(integer) 0
127.0.0.1:6379> hmexists user:1002 name,age
(error) ERR unknown command `hmexists`, with args beginning with: `user:1002`, `name,age`,
127.0.0.1:6379> hmexists user:1002 name
(error) ERR unknown command `hmexists`, with args beginning with: `user:1002`, `name`,
127.0.0.1:6379> hexists user:1002 name
(integer) 1
127.0.0.1:6379> hkeys user:1002 //查看指定hash集合中所有的属性名
1) "id"
2) "name"
3) "age"
127.0.0.1:6379> hvals user:1002 //查看指定hash集合中所有的属性值
1) "2"
2) "lisi"
3) "30"
127.0.0.1:6379> hincrby user:1002 age 2 //为指定hash集合中指定属性值加一
(integer) 32
127.0.0.1:6379> hsetnx user:1002 gender 1 //先判断指定hash集合中是否存在指定属性gender,如果不存在就添加一个属性
(integer) 1
127.0.0.1:6379> hkeys user:1002
1) "id"
2) "name"
3) "age"
4) "gender"
127.0.0.1:6379> hvals user:1002
1) "2"
2) "lisi"
3) "32"
4) "1"
4.4.2底层结构
Hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。
4.5 zset有序集合
4.5.1 常用命令
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> zadd topn 200 java 300 c++ 400 mysql 500 php //添加一个zset集合,并未每个元素score和value赋值
(integer) 4
127.0.0.1:6379> zrange topn 0 -1 //查看指定zset集合所有value值
1) "java"
2) "c++"
3) "mysql"
4) "php"
127.0.0.1:6379> zrange topn -1 0
(empty array)
127.0.0.1:6379> zrange topn 0 -1 withscores //查看指定zset集合所有value和score值,从小到大
1) "java"
2) "200"
3) "c++"
4) "300"
5) "mysql"
6) "400"
7) "php"
8) "500"
127.0.0.1:6379> zrangebyscore topn 300 500 //根据score范围查看指定zset集合的value值,从小到大
1) "c++"
2) "mysql"
3) "php"
127.0.0.1:6379> zrangebyscore topn 300 500 withscores //根据score范围查看指定zset集合的value和score值,从小到大
1) "c++"
2) "300"
3) "mysql"
4) "400"
5) "php"
6) "500"
127.0.0.1:6379> zrevrangebyscore topn 500 200 //根据score范围查看指定zset集合的value值,从大到小
1) "php"
2) "mysql"
3) "c++"
4) "java"
127.0.0.1:6379> zrevrangebyscore topn 500 200 withscores //根据score范围查看指定zset集合的value和score值,从大到小
1) "php"
2) "500"
3) "mysql"
4) "400"
5) "c++"
6) "300"
7) "java"
8) "200"
127.0.0.1:6379> zincrby topn 50 java //为指定zset集合的指定元素的score值添加50
"250"
127.0.0.1:6379> zcount topn 200 300 //查看指定zset集合score指定范围的数量
(integer) 2
127.0.0.1:6379> zrank topn java //查看指定zset集合的指定元素索引,从小到大
(integer) 0
127.0.0.1:6379> zrank topn mysql
(integer) 2
4.5.2 底层结构
Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。
不同之处是有序集合的每个成员