1.为什么用NoSql
随着网站得用户量增长,数据信息增长,读写压力变大,关系型数据库已经不能满足要求了。
这个时候NoSQl 非关系型数据库就诞生了。NoSQL+RDBMS
2.NoSQL的特点
- 方便扩展,数据之间没关系 例如Map<String,Object>
- 大量数据的高性能(Redis支持读 11万次/秒,写8万次/秒)
- 数据库类型的多样性,不需要实现设计数据库,随取随用
3.Redis(远程字典服务)中文网地址
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
Redis能干什么(它可以用作数据库、缓存和消息中间件)
1.内存存储,持久化,内存是断电即失。
2.效率高,可以用于告诉缓存。
3.发布订阅系统。
4.地图信息。
5.计时器,计数器。
6.。。。。。
安装
windows
1.下载 https://github.com/MicrosoftArchive/redis/releases
2.解压
3.启动:
4.使用redis客户端连接redis,成功连接
Linux
1.将linux版本的安装包,复制到linux中解压。
2.进入解压文件夹中 make install
3.redis的默认安装路径在 usr/local/bin 中
4.将redis.connf文件复制到 我们需要的地方 [root@localhost bin]# cp /opt/redis-5.0.8/redis.conf config
5.修改redis.connf文件 绕过redis后台启动
6. 启动redis服务(通过指定的配置文件启动)
7.测试
8.关闭退出
基础知识
redis有16个数据库 默认使用0号数据库
一些命令
设置key的过期时间为10s
flashdb
清空当前数据库
flashall
清空所有数据库
使用select 2
切换为2号数据库
EXISTS key
判断这个key是否存在
type key 查看key的类型
move key 1 移除当前key
ttl key 查看剩余时间
遇到不会的命令可以在官网查看
redis是单线程,因为cpu不是redis的瓶颈,单线程可以解决了
Redis五大数据类型
字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)
1. String操作(字符串类型)
APPEND key1 ‘abc’
STRLEN key 获取字符串长度
incr key 加1
INCRBY key 10 加10
decr 减1
DECRBY key 10 减10
127.0.0.1:6379> getrange key 5 10 截取字符串
"dasdas"
127.0.0.1:6379> getrange key 0 -1 查看全部字符串
"adadsdasdasdas"
127.0.0.1:6379> setrange key 1 mko 替换中间字符
(integer) 14
127.0.0.1:6379> get key
"amkosdasdasdas"
setex key "dasdas" 60 存在时间60秒
setnx key "dasdas" 如果已经存在key测绘返回0 表示不成功
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 批量设置
OK
127.0.0.1:6379> keys *
1) "key"
2) "k1"
3) "key1"
4) "k3"
5) "k2"
127.0.0.1:6379>
127.0.0.1:6379> mget k1 k2 k3 批量获取
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 有原子性 一起成功一起失败
储存对象
mset user:1:age 10 user:1:name asdasda
OK
127.0.0.1:6379> mget user:1:age user:1:name
1) "10"
2) "asdasda"
127.0.0.1:6379>
先得到再设置
127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
List
项式一个管道 可以左加入和又加入,相当于两头栈
左加入数据
127.0.0.1:6379> lpush list one
(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
1) "three"
2) "two"
127.0.0.1:6379> llen list 长度
(integer) 2
127.0.0.1:6379> lset list 0 as 将list中0下表的值替换为as,如果不存在列表就会报错
127.0.0.1:6379> rpush list vvv
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "vvv"
127.0.0.1:6379> lpop list
"three"
127.0.0.1:6379> rpop list
"vvv"
按照下表查询值
127.0.0.1:6379> lindex list 0
"two"
127.0.0.1:6379> lrem list 1 one 移除指定的值 一个one
127.0.0.1:6379> ltrim list 0 1 list就只剩下截断的
set
127.0.0.1:6379> sadd set1 da
sdiff key1 key2 返回这两个set的差集
sinter key1 key2 返回这两个set的交集
sunion key1 key2 返回这两个set的并集
Hash
key-Map 更加适合用于存对象。
127.0.0.1:6379> hset myhast k1 v1 k2 v2
(integer) 1
127.0.0.1:6379> hget myhast k1
"v1"
127.0.0.1:6379> hget myhast k1 k2
127.0.0.1:6379> hgetall myhast
1) "k1"
2) "v1"
127.0.0.1:6379> hdel myhast k1 删除
(integer) 1
127.0.0.1:6379> hlen myhast 获取长度
Zste
自动 对number的key进行排序
127.0.0.1:6379> zadd myset 1 one 添加一个值
(integer) 1
127.0.0.1:6379> zadd myset 3 three 2 two 添加多个值
(integer) 2
127.0.0.1:6379> zrange myset 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> zrangebyscore myset -inf +inf 排序输出 从小到大
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> zrangebyscore myset 0 -1 排序输出 从大到小
127.0.0.1:6379> zrangebyscore myset -inf +inf withscores
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
127.0.0.1:6379> zrem myset one 移除操作
(integer) 1
127.0.0.1:6379> zrangebyscore myset -inf +inf
1) "two"
2) "three"
127.0.0.1:6379>
127.0.0.1:6379> zcard myset 查看长度
(integer) 2
三个特殊类型
地理空间(geospatial)
插入城市经纬度
127.0.0.1:6379> geoadd china:city 116.397128 39.916527 beijing
(integer) 1
127.0.0.1:6379> geoadd china:city 121.47 31 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 1.6 29 chongqing
(integer) 1
127.0.0.1:6379> geoadd china:city 108.69 34 xian
(integer) 1
获取经纬度
127.0.0.1:6379> geopos china:city beijing
1) 1) "116.39712899923324585"
2) "39.91652647362980844"
查询两点的直线距离
127.0.0.1:6379> geodist china:city beijing xian km
"949.1553"
127.0.0.1:6379> georadius china:city 100 30 5000 km //查看100 30 周围5000km的所有的位置
1) "xian"
2) "shanghai"
3) "beijing"
127.0.0.1:6379> georadius china:city 100 30 5000 km withdist //加上显示距离
1) 1) "xian"
2) "932.1327"
2) 1) "shanghai"
2) "2057.4183"
3) 1) "beijing"
2) "1852.5507"
127.0.0.1:6379> georadius china:city 100 30 5000 km withcoord
1) 1) "xian"
2) 1) "108.68999987840652466"
2) "34.00000062127011091"
2) 1) "shanghai"
2) 1) "121.47000163793563843"
2) "31.00000097648057817"
3) 1) "beijing"
2) 1) "116.39712899923324585"
2) "39.91652647362980844"
127.0.0.1:6379> georadius china:city 100 30 5000 km withcoord count 2
1) 1) "xian"
2) 1) "108.68999987840652466"
2) "34.00000062127011091"
2) 1) "beijing"
2) 1) "116.39712899923324585"
2) "39.91652647362980844"
127.0.0.1:6379> georadiusbymember china:city shanghai 5000 km//指定城市
1) "xian"
2) "shanghai"
3) "beijing"
hyperloglog
基数统计的算法,比如再网站统计访问量的时候有用,官方给出误差0.81%
127.0.0.1:6379> pfadd mykey a b c d e f g
(integer) 1
127.0.0.1:6379> pfcount mykey
(integer) 7
127.0.0.1:6379> pfadd mykey2 a s i k h g f t u i h
(integer) 1
127.0.0.1:6379> pfmerge mykey3 mykey mykey2
OK
127.0.0.1:6379> pfcount mykey3
(integer) 12
BitMap
位储存(查看活跃人数,看看用户有没有打卡,只要是只有两种状态的都可以用)
127.0.0.1:6379> pfcount mykey3
(integer) 12
127.0.0.1:6379> setbit sign 0 0
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 1
(integer) 0
127.0.0.1:6379> setbit sign 3 0
(integer) 0
127.0.0.1:6379> getbit sign 2
(integer) 1
127.0.0.1:6379> bitcount sign 统计
(integer) 1
事务(Redis没有隔离的概念)
事务:本质上是一组命令的集合(一次性,顺序性,排他性)
Redis单挑命令保证原子性,但是Redis事务不保证原子性,且事务没有直接执行只有在调用命令时 才会执行
Redis事务:
- 开启事务(multi)
- 命令入队
- 执行事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) "v1"
127.0.0.1:6379>
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> discard 放弃事务
编译型异常会导致所有的事务都执行失败,所有的命令都不会执行
运行时语法逻辑错误,其他的命令还是会正常实行,所以没有原子性
悲观锁
乐观锁
Redis watch
127.0.0.1:6379> set m 100
OK
127.0.0.1:6379> set o 0
OK
127.0.0.1:6379> watch m
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby m 20
QUEUED
127.0.0.1:6379> incrby o 20
QUEUED
//如果再执行前 m被改变,则这个事务就会提交失败
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
//用完只有记得 unwatch
127.0.0.1:6379> unwatch