Nosql
NoSQL:即Not-OnlySQL(泛指非关系型的数据库),作为关系型数据库的补充
作用:应对基于海量用户和海量数据前提下的数据处理问题
特性:
1.可扩容,可伸缩
2.大数据量下高性能
3.灵活的数据模型
4.高可用
常见Nosql数据库:
1.Redis
2.Memcache
3.Hbase
4.MongoDB
解决方案:
商品基本信息:
名称、价格、厂商—mysql
商品附加信息:
描述、详情、评论—MongoDB
图片信息 ---分布式文件系统
搜索关键字 ES、Lucene、solr
热点信息 –高频、波段性---Redis、Memcache、tair

Redis
概念:
Redis是C语言开发的开源高性能键值对(key-value)数据库
特征:
1.数据间没有必然的关联关系
2.内部采用单线程机制进行工作
3.高性能:50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s
4.多数据类型支持
字符串类型 String
列表类型 list
散列类型 hash
集合类型 set
有序集合类型 sorted_set
5.持久化支持。可以进行数据灾难恢复
Redis的应用
为热点数据加速查询(主要场景),如热点商品、热点新闻、热点资讯、推广类等高访问量信息等
任务队列:如秒杀、抢购、购票排队等
即时信息查询,如各位排行榜、各类网站访问统计、公交到站信息、在线人数信息(聊天室、网站)、设备信号等
时效性信息控制,如验证码控制、投票控制等
分布式数据共享,如分布式集群架构中的session分离
消息队列
分布式锁
Redis的下载与安装
Linux(适用于企业级开发)
Redis高级开始使用
以4.0版本为主版本
Windows版本(零基础学习)
Redis入门
以3.2版本为主版本
下载地址:https://github.com/MSOpenTech/redis/tags
PID:就相当于Redis的对象ID

命令行模式工具使用思考
功能性命令
清除屏幕信息
帮助信息查阅
退出指令
信息添加:
功能:设置key、value数据
命令:set key value
范例:set name itheima
信息查询:
功能:根据key查询对应的value,如果不存在,返回空(nil)
命令:get key
范例:get name
获取帮助:
功能:获取命令帮助信息
命令:
help 命令名
help @组名
以下就是Redis的帮助信息

退出客户端命令行模式
功能:退出客户端
命令:quit exit <ESC>
数据存储类型介绍:
业务数据的特殊性:
作为缓存使用:
1.原始业务功能设计:
秒杀、618、双11活动、排队购票
2.运营平台监控到的突发高频访问数据
突发时政要闻,被强势关注围观
3.高频、复杂的统计数据
在线人数、投票排行榜
业务数据的特殊性
附加功能:
系统功能优化或升级
单服务器升级集群、Session管理、Token管理
和java的数据类型对比:

String
Redis数据存储格式
1.redis自身是一个Map,其中所有的数据都是采用key:value的形式存储
2.数据类型指的是存储的数据的类型,也就是value部分的类型,key部分永远都是字符串

String类型:
1.存储的数据:单个数据,最简单的数据存储类型,也是最常用的数据存储类型
2.存储数据的格式:一个存储空间保存一个数据
3.存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用

string类型数据的基本操作
1.添加/修改数据
set key value
2.获取数据
get key
3.删除数据
del key
4.添加/修改多个数据
mset key1 value1 key2 value2 (Multiple:)
5.获取多个数据
mget key1 key2
6.获取数据字符个数(字符串长度)
strlen key
7.追加信息到原始信息后部(如果原始信息存在就追加,否则新建)
append(追加) key value
#这里我们对单数据与多数据操作的选择问题

String类型数据的扩张操作
业务场景:
在大型企业级应用当中,分表操作是基本操作,使用多张表存储同类型数据,但是对应的主键id必须保证统一性
不能重复。在Orcle当中有sequence设定,可以保证多表id不重复,但是MysSQL数据库并不具有类似的机制,如何解决?

解决方案:
1.设置数值数据增加指定范围的值
incr key(可以对数字做增加的操作)
incrby key increment(对指定数字加值的操作,对整数的操作)
incrbyfloat key increment(对浮点型操作的)
2.设置数值数据减少指定范围的值
decr key (可以对数字做减少的操作)
decrby key increment(对指定数字减值的操作)
String作为数值操作
1.String在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算
2.reids所有的操作都是原子性的,采用单线程处理所有的业务,命令是一个一个执行的,因此无需考虑并发带来的数据影响
3.注意:按数值进行操作的数据,如果原始数据不能转成数值,或超越了redis数值上限范围,将报错。
9223372036854775807(java中long型数据最大值,Long.MAX_VALUE)
Tips1
1.redis用于控制数据库表主键id,为数据库表主键提供生成策略,保证数据库表的主键唯一性
2.此方案适用于所有数据库,且支持数据库集群
扩展操作
业务场景例子:
1.“最强女生”启动海选投票,只能通过微信投票,每个微信号每4小时只能投1票
2.电商商家开启热门商品推荐,热门商品不能一直处于热门期,每种商品热门期维持3天,3天后自动取消热门
3.新闻网站会出现热点新闻,热点新闻最大的特征是时效性,如何自动控制热点新闻的时效性
解决方案:
在投票的时候,我们会给投票的人加一个新的id:例:news_id:HB314790725 加一个实效时间:4小时
等倒计时结束以后,我们将这个id进行删除,就可以重新投票
数据具有指定的生命周期
命令:
setex key seconds value(以秒为单位)
psetax key milliseconds value(以毫秒为单位)
解决方案2
redis控制数据的生命周期,通过数据是否实效控制业务行为,适用于所有具有时效性限定控制的操作
注意事项:
1、数据操作不成功的反馈与数据正常操作之间的差异
①表示运行结果是否成功
(1)(integer)0 –false 失败
(2)(integer)1 –true 成功
②表示运行结果值
(1)(integer)3 – 3 3个
(2)(integer)1- 1 1个
数据为获取到
(nil)等同于null
数据最大储存量:512MB
数据计算最大范围(java中long的最大值):9223372036854775807
案例:业务场景
业务高频访问信息显示控制,例如新浪微博大V主页显示粉丝数与微博数量

解决方案:
(1)在redis中为大V用户设定用户信息,以用户主键和属性值作为key,后台设定定时刷新策略即可
粉丝数:set user:id:3506728370:fans – 12210917
微博数:set user:id:3506728370:blogs – 6164
关注数:set user:id:3506728370:focuss – 83
(2)在redis中以json格式存储大V用户信息,定时刷新(也可以使用hash类型)
eg:user:id:3506728370—{id: 3506728370,name:春晚,fans:12210862,blogs:6164,focus:83}
(3)redis应用于各种结构型和非机构型高热度数据访问加速
热点数据key命名惯例
表名:主键名:主键值:字段名 Eg1: order: id :29437595:name Eg2: equip:id :390472345:type Eg3: news:id :202004150:title |
hash类型:
首先说一下存储方式的问题:
我们采取如下的存储方式,在对数据有频繁的更新需求操作的时候,会显的十分的笨重

这里如果采取hash存储方式:

特征:
1.新的储存需求:对一系列储存的数据进行编组,方便管理,典型应用存储对象信息
2.需要的存储结构:一个存储空间保存多个键值对数据
3.hash类型:底层使用哈希表结构实现数据存储

这里需要注意的地方:hash存储结构优化
1.如果field(即hash表中小的键)数量较少,存储结构优化为类数组结构
2.如果field数量较多,储存结构使用HashMap结构
Hash类型数据的基本操作:
1.增加数据
hset key (field value)
2.获取数据
hget key field(获取单个value)
hgetall key(获取key的所有hash值)
3.删除数据
hdel key field1[field2]
多数据操作:
1.添加/修改多个数据
hmset key field1 value1 field2 value2…
2.获取多个数据
hmget key field1 field2…
3.获取哈希表中字段的数量(判断有几个field)
hlen key
4.获取哈希表中是否存在指定的字段
hexists key field
*hash拓展操作
1.获取哈希表中所有字段名或字段值
hkeys key(获取所有的field)
hvals key(获取所有的value)
2.设置指定字段的数值数据增加指定范围的值
hincrby key field increment
hincrbyfloat key field increment
注意事项:
hash类型下的value只能存储字符串,不允许存储其他数据类型,不存在嵌套现象(禁止套娃:就是hash里面再存hash表的现象),如果数据未获取到,对应的值为(nil)
每个hash可以存储-1个键值对
hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存储大量对象而设计的,不可以“滥用”,更不可以将hash作为对象列表使用
hgetall操作可以获取全部属性,如果内部field过多,遍历整体数据效率就会很低,很有可以成为数据访问瓶颈。
业务场景:(1)购物车:
电商网站购物车设计与实现:
如图所示:
购物车相应的命令结构

这里我们做业务分析:
仅分析购物车的redis存储模型,添加、浏览、更改数量、删除、清空
购物车和数据库间持久化同步(不讨论)
购物车和订单间关系(不讨论)
提交购物车:读取数据生成订单
商家临时价格调整:隶属于订单级别
4. 未登录用户购物车信息存储(不讨论)
cookie存储
解决方案:
以客户id作为key,每位客户创建一个hash存储结构存储对应的购物车信息
以商品编号作为field,购买数量作为value进行存储
添加商品:追加全新的field与value
浏览:遍历hash
更改数量:自增/自减,设置value值
删除商品:删除field
清空:删除key
问题:当前的设计购物车时候存在问题,是否加速了购物车的呈现
当前仅仅是将数据存储到redis当中,并没有起到加速的作用,商品信息还需要二次查询数据库。
每条购物车中的商品记录保存成两条field
field1专门用于保存购买数量:
命名格式:商品id:nums
保存数据:数值
field2专门用于保存购物车中显示的信息,包含文字描述,图片地址,所属商家信息等
命名格式:商品id:info---
保存数据:json------ 可以独立出一个单独的hash—
(这里我们就可以在redis当中,独立出来一个商品,因为redis为key value数据库,这样可以加快查询速度)
如下图所示:(这样我们的购物车中,只保存商品数量,这里的商品信息走公共区域)

这里可能会出现一个问题,就是,有一个用户我们添加一下,有一个添加一个,会显得特别麻烦,这里我们使用
hsetnx key field value 做一个检查,如果有这个商品,那么我们就不用再次进行条件操作。

Tips4:
redis应用于购物车数据存储设计
(2)业务场景2
双11活动日,销售手机充值卡的商家对移动、联通、电信的30元、50元、100元商品推出抢购活动,每种商品抢购上限1000张

解决方案:
以商家id作为key
将参与抢购的商品id作为field
将参与抢购的商品数量作为对应的value
抢购时使用降值的方式控制产品数量
#实际业务中还有超卖等实际问题,这里就不做讨论了,具体解决方案,可以参考一下方案:
秒杀业务场景中如何实现不超卖的问题(文章还没发,先等等,嘻嘻)
原则:redis只提供数据的保存,不要把业务压到redis当中,最好是放到编程语言当中
redis应用于抢购、限购类、限量发放优惠券、激活码等业务的数据存储设计
String存储对象(json)与hash存储对象---不同和相同点
String类型更讲究一种整体性,更讲究一种读操作
Hash更倾向于更新操作
学习来源:(p1-p15)笔记
https://www.bilibili.com/video/BV1CJ411m7Gc?p=16




