NoSQL概述
为什么要用NoSql
大数据时代,一般的数据库已经无法进行分析处理了
什么是NoSQL?
NoSQL = Not Only SQL
泛指非关系型数据库
NoSQL特点
1、方便扩展(数据之间没有关系,很好扩展)
2、大数据量、高性能(NoSQL的缓存记录级,是一种细粒度的缓存,性能比较高)
3、数据类型是多样性的(不需要实现设计数据库,随取随用)
4、传统的RDBMS和NoSQL
传统的RDBMS | NOSQL |
---|---|
结构化组织 | 不仅仅是数据 |
SQL | 没有固定的查询语言 |
数据和关系都存在单独的表中 | 键值对存储、列存储、文档存储、图形数据库 |
操作,数据定义语言 | 最终一致性 |
严格的一致性 | CAP定理、BASE(异地多活) |
基础的事物 | 高性能、高可用、高可扩 |
NoSQL的四大分类
KV键值对
- Redis
文档型数据库
- MongoDB
- MongoDB是一个基于分布式文件存储的数据库,C++编写,主要用来处理大量文档
- MongoDB是一个介于关系型数据库和非关系型数据库的中间产品,是非关系型数据库中功能最丰富,最像关系型数据库的
- ConthDB
列存储数据库
-
HBase
-
分布式文件系统
图关系数据库
-
存的不是图片,存的是关系,如朋友圈社交网络、广告推荐等
-
Neo4j
四者对比
Redis入门
概述
Redis是什么?
(Remote Dictionary Server ),即远程字典服务
是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
也被人们称之为结构化数据库
Redis能干嘛?
1、内存存储、持久化(rdb、aof)
2、效率高、可以用于高速缓存
3、发布订阅系统
4、地图信息分析
5、计时器、计数器(浏览量)
6、····
特性
1、多样的数据类型
2、持久化
3、集群
4、事务
····
学习中用到的东西
1、官网:https://redis.io/
2、中文网:http://www.redis.cn/
Linux安装
1、下载安装包,并上传至服务器(如果有的话)
2、解压安装包
压缩包放在opt目录
并解压
解压完成
3、进入解压后的Redis目录
4、基本的环境安装
5、Redis的默认安装路径
/usr/local/bin
6、在安装路径下新建myconfig文件夹,将redis.conf复制到此文件夹
7、redis默认不是后台启动,修改配置文件,设置后台启动
vim打开文件
此处改为yes
最后
:wq保存退出
8、启动redis服务
通过指定的配置文件启动redis服务
9、连接测试:
10、查看redis的进程是否开启
11、关闭redis服务
测试性能
redis-benchmark是官方自带的压力测试工具,测试性能
命令格式:
redis-benchmark 命令参数
简单测试:
#测试:100个并发连接,100000请求
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
基础知识
Redis有16个数据库
默认使用的是第0个
可以使用select
进行切换数据库
dbsize
查看db大小
127.0.0.1:6379> select 3 #切换数据库
OK
127.0.0.1:6379[3]>
127.0.0.1:6379[3]> dbsize #查看db大小
(integer) 0
=======================================
127.0.0.1:6379[3]> set name zhiyu
OK
127.0.0.1:6379[3]> dbsize
(integer) 1
127.0.0.1:6379[3]>
=======================================
127.0.0.1:6379[3]> select 7
OK
127.0.0.1:6379[7]> dbsize
(integer) 0
127.0.0.1:6379[7]> get name
(nil)
=======================================
127.0.0.1:6379[7]> select 3
OK
127.0.0.1:6379[3]> get name
"zhiyu"
127.0.0.1:6379[3]>
keys *
查看数据库中所有的key
flushdb
清空当前数据库
flushall
清空所有数据库
127.0.0.1:6379[3]> keys * #查看数据库中所有的key
1) "name"
=======================================
127.0.0.1:6379[3]> flushdb #清空当前数据库 flushall 清空所有数据库
OK
127.0.0.1:6379[3]> keys *
(empty list or set)
127.0.0.1:6379[3]>
Redis是单线程的
Redis是基于内存操作,CPU不是性能瓶颈
五大数据类型
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
Redis-Key
EXISTS
key
查询key是否存在
127.0.0.1:6379> set name zhiyu
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> EXISTS name
(integer) 1
127.0.0.1:6379> EXISTS name1
(integer) 0
127.0.0.1:6379>
move
key
dbname
移动指定的key到指定的数据库中
127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "name"
expire
key
seconds
设置指定key的过期时间,单位为秒
ttl
name
查看指定key还有多长时间过期
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> get name
"zhiyu"
127.0.0.1:6379> expire name 10
(integer) 1
127.0.0.1:6379> ttl name
(integer) 5
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379>
type
key
查看指定key的数据类型
127.0.0.1:6379> type name
string
127.0.0.1:6379> type age
string
127.0.0.1:6379>
String
append
key
value
向指定key追加值,如果指定的key不存在,则新建这个key并set值
127.0.0.1:6379> set key1 v1
OK
127.0.0.1:6379> get key1
"v1"
127.0.0.1:6379> append key1 hello
(integer) 7
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379>
strlen
key
获取指定key的长度
127.0.0.1:6379> strlen key1
(integer) 7
127.0.0.1:6379>
incr
key
将指定的key值+1
decr
key
将指定的key值-1
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> get views
"0"
127.0.0.1:6379>
incrby
key
decrement(步长)
将指定key值增加指定步长
decrby
key
decrement(步长)
将指定key值减少指定步长
127.0.0.1:6379> incrby views 10
(integer) 10
127.0.0.1:6379> get views
"10"
127.0.0.1:6379> decrby views 10
(integer) 0
127.0.0.1:6379> get views
"0"
127.0.0.1:6379>
getrange
key
start
end
截取指定key的指定位置的字符串,若为0,-1则代表全部
127.0.0.1:6379> set key1 hello,world
OK
127.0.0.1:6379> get key1
"hello,world"
127.0.0.1:6379> getrange key1 0 3
"hell"
127.0.0.1:6379> getrange key1 0 -1
"hello,world"
127.0.0.1:6379>
setrange
key
offset(位置)
value(修改的字符串)
127.0.0.1:6379> setrange key1 1 xxx
(integer) 11
127.0.0.1:6379> get key1
"hxxxo,world"
127.0.0.1:6379>
setex
key
seconds
value
设置键值对并设置过期时间
setnx
key
value
如果指定key不存在则设置指定值,如果存在则不操作
127.0.0.1:6379> setex key3 30 hello
OK
127.0.0.1:6379> ttl key3
(integer) 23
127.0.0.1:6379> get key3
"hello"
127.0.0.1:6379> setnx key4 redis
(integer) 1
127.0.0.1:6379> get key4
"redis"
127.0.0.1:6379> setnx key4 mongodb
(integer) 0
127.0.0.1:6379> get key4
"redis"
127.0.0.1:6379> ttl key3
(integer) -2
127.0.0.1:6379> get key3
(nil)
127.0.0.1:6379>
mset
[key
value]
设置一组KV
mget
[key]
获取一组key的值
msetnx
[key
value]
设置一组KV,如果key不存在则新建,key存在则创建失败,则后面的k4也会创建失败(原子性)
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
3) "k3"
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 vv k4 v4
(integer) 0
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379>
这里的Key是一个巧妙的设计:user:{id}:{filed(属性名)}
127.0.0.1:6379> mset user:1:name zhiyu user:1:age 20
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhiyu"
2) "20"
127.0.0.1:6379>
getset
key
value
先get再set
127.0.0.1:6379> getset key1 v1
(nil)
127.0.0.1:6379> get key1
"v1"
127.0.0.1:6379> getset key1 v2
"v1"
127.0.0.1:6379> get key1
"v2"
127.0.0.1:6379>
List
所有的List命令都是以L
开头的
lpush
key
[value]
新建list并设置值,如果存在该list则追加值(向左边头部
添加值)
rpush
key
[value]
新建list并设置值,如果存在该list则追加值(向右边尾部
添加值)
lrange
key
start
stop
查看指定下标的值;(0,-1)代表全部
127.0.0.1:6379> lpush list one two three
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 1
1) "three"
2) "two"
127.0.0.1:6379> rpush list right
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379>
lpop
key
移除左边(头部)第一个元素
rpop
key
移除右边(尾部)第一个元素
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379> lpop list
"three"
127.0.0.1:6379> rpop list
"right"
127.0.0.1:6379> lrange list
(error) ERR wrong number of arguments for 'lrange' command
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379>
lindex
key
index(下标)
通过下标获取值
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lindex list 0
"two"
127.0.0.1:6379> lindex list 1
"one"
127.0.0.1:6379>
llen
key
获取list的长度
127.0.0.1:6379> llen list
(integer) 2
127.0.0.1:6379>
lrem
key
range(数量)
value
移除指定数量的、指定的值
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "three"
4) "two"
5) "one"
127.0.0.1:6379> lrem list 1 three
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lrem list 2 three
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379>
ltrim
key
start
stop
修剪list
127.0.0.1:6379> rpush list hello hello1 hello2 hello3
(integer) 4
127.0.0.1:6379> ltrim list 1 2
OK
127.0.0.1:6379> lrange list 0 -1
1) "hello1"
2) "hello2"
127.0.0.1:6379>
rpoplpush
source
destination
将一个list的尾部元素移动到另一个list的头部,如果新list不存在则创建
127.0.0.1:6379> lrange list 0 -1
1) "hello1"
2) "hello2"
127.0.0.1:6379> rpoplpush list mylist
"hello2"
127.0.0.1:6379> lrange list 0 -1
1) "hello1"
127.0.0.1:6379> lrange mylist 0 -1
1) "hello2"
127.0.0.1:6379>
lset
key
index
value
给指定list的指定下标设置值,相当于更新操作。当该list不存在或指定下标不存在时报错
127.0.0.1:6379> lset list 0 item0
(error) ERR no such key
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> lpush list item0
(integer) 1
127.0.0.1:6379> lset list 1 ltem1
(error) ERR index out of range
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> lset list 0 item000
OK
127.0.0.1:6379> lrange list 0 -1
1) "item000"
127.0.0.1:6379>
linsert
key
BEFORE
|AFTER
pivot
value
向指定value的前或后插入一个value
127.0.0.1:6379> rpush mylist hello world
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> linsert mylist before world other
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "other"
3) "world"
127.0.0.1:6379>
小结:
- List实际上是一个链表,before Node after ,left,right 都可以插值
- 如果key不存在,创建新的链表
- 如果key存在,新增内容
- 如果移除所有值,-> 空链表,也代表不存在
- 在两边改动效率最高
- 消息队列(Lpush Rpop),栈(Lpush Lpop)
Set
set中的值是不能重复的!
关于set的命令都是S开头
sadd
key
member
[member ...]
新建一个Set
smembers
key
查看指定set的全部value
127.0.0.1:6379> sadd myset hello zhiyu
(integer) 2
127.0.0.1:6379> smembers myset
1) "zhiyu"
2) "hello"
127.0.0.1:6379>
sismember
key
member
判断某个value在不在指定set中
127.0.0.1:6379> sismember myset hello
(integer) 1
127.0.0.1:6379> sismember myset world
(integer) 0
127.0.0.1:6379>
scard
key
获取set中元素的个数
127.0.0.1:6379> scard myset
(integer) 2
127.0.0.1:6379>
srem
key
member
[member ...]
移除指定set中指定的value
127.0.0.1:6379> srem myset hello
(integer) 1
127.0.0.1:6379> smembers myset
1) "zhiyu"
127.0.0.1:6379>
srandmember
key
[count]
获取指定set中的随机元素,可指定一次获取的元素数量
127.0.0.1:6379> SMEMBERS myset
1) "zhiyu"
2) "zhiyu3"
3) "zhiyu2"
127.0.0.1:6379> SRANDMEMBER myset
"zhiyu3"
127.0.0.1:6379> SRANDMEMBER myset
"zhiyu"
127.0.0.1:6379> SRANDMEMBER myset
"zhiyu"
spop
key
[count]
随机移除元素
127.0.0.1:6379> SMEMBERS myset
1) "zhiyu"
2) "zhiyu3"
3) "zhiyu2"
127.0.0.1:6379> spop myset
"zhiyu2"
127.0.0.1:6379> spop myset
"zhiyu3"
127.0.0.1:6379> smembers myset
1) "zhiyu"
127.0.0.1:6379>
smov
source
destination
member
将指定的值移动到另一个set中
127.0.0.1:6379> sadd myset hello world zhiyu
(integer) 3
127.0.0.1:6379> sadd myset2 set2
(integer) 1
127.0.0.1:6379> smove myset myset2 zhiyu
(integer) 1
127.0.0.1:6379> smembers myset
1) "hello"
2) "world"
127.0.0.1:6379> smembers myset2
1) "zhiyu"
2) "set2"
127.0.0.1:6379>
sdiff
key
[key ...]
得到key1 和 key2 的差集,以key1的视角
sinter
key
[key ...]
得到交集
sunion
key
[key ...]
得到并集
127.0.0.1:6379> sadd key1 a b c
(integer) 3
127.0.0.1:6379> sadd key2 c d e
(integer) 3
127.0.0.1:6379> sdiff key1 key2
1) "a"
2) "b"
127.0.0.1:6379> sinter key1 key2
1) "c"
127.0.0.1:6379> sunion key1 key2
1) "c"
2) "b"
3) "d"
4) "a"
5) "e"
Hash
Map集合, key-map(key-value)
Zset
Q.E.D.