一、关系型数据库与NoSQL数据库的区别
- 结构化与非结构化: 传统关系型数据库是结构化数据,每一张表都有严格的约束信息:字段名、字段数据类型、字段约束等等信息,插入的数据必须遵守这些约束;而NoSql则对数据库格式没有严格约束,往往形式松散,自由。
- 关联和非关联:传统数据库的表与表之间往往存在关联,例如外键;非关系型数据库不存在关联关系,要维护关系要么靠代码中的业务逻辑,要么靠数据之间的耦合。
- 查询方式:传统关系型数据库会基于Sql语句做查询,语法有统一标准;而不同的非关系数据库查询语法差异极大,五花八门各种各样。
- 事务:传统关系型数据库能满足事务ACID(原子性、一致性、隔离性、持久性)的原则;而非关系型数据库往往不支持事务,或者不能严格保证ACID的特性,只能实现基本的一致性。
- 存储方式:关系型数据库基于磁盘进行存储,会有大量的磁盘IO,对性能有一定影响;非关系型数据库,他们的操作更多的是依赖于内存来操作,内存的读写速度会非常快,性能自然会好一些。
- 扩展性:关系型数据库集群模式一般是主从,主从数据一致,起到数据备份的作用,称为垂直扩展;非关系型数据库可以将数据拆分,存储在不同机器上,可以保存海量数据,解决内存大小有限的问题。称为水平扩展。关系型数据库因为表之间存在关联关系,如果做水平扩展会给数据查询带来很多麻烦。
二、什么是Redis
2.1 概述
Redis是一个基于内存的键值型的NoSql数据库,可以存储键和五种不同类型的值之间的映射。
键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。
特征:
- 键值(key-value)型,value支持多种不同数据结构,功能丰富
- 单线程,每个命令具备原子性
- 低延迟,速度快(基于内存、IO多路复用、良好的编码)。
- 支持数据持久化
- 支持主从集群、分片集群
- 支持多语言客户端
2.2 数据类型
数据类型 | 可以存储的值 | 操作 |
---|---|---|
STRING | 字符串、整数或者浮点数 | 对整个字符串或者字符串的其中一部分执行操作对整数和浮点数执行自增或者自减操作 |
LIST | 列表 | 从两端压入或者弹出元素 对单个或者多个元素进行修剪,只保留一个范围内的元素 |
SET | 无序集合 | 添加、获取、移除单个元素 检查一个元素是否存在于集合中 计算交集、并集、差集 从集合里面随机获取元素 |
HASH | 包含键值对的无序散列表 | 添加、获取、移除单个键值对 获取所有键值对 检查某个键是否存在 |
ZSET | 有序集合 | 添加、获取、删除元素 根据分值范围或者成员来获取元素计算一个键的排名 |
三、使用场景
计数器
可以对 String 进行自增自减运算,从而实现计数器功能。
Redis 这种内存型数据库的读写性能非常高,很适合存储频繁读写的计数量。
缓存
将热点数据放到内存中,设置内存的最大使用量以及淘汰策略来保证缓存的命中率。
查找表
例如 DNS 记录就很适合使用 Redis 进行存储。
查找表和缓存类似,也是利用了 Redis 快速的查找特性。但是查找表的内容不能失效,而缓存的内容可以失效,因为缓存不作为可靠的数据来源。
消息队列
List 是一个双向链表,可以通过 lpush 和 rpop 写入和读取消息
不过最好使用 Kafka、RabbitMQ 等消息中间件。
会话缓存
可以使用 Redis 来统一存储多台应用服务器的会话信息。
当应用服务器不再存储用户的会话信息,也就不再具有状态,一个用户可以请求任意一个应用服务器,从而更容易实现高可用性以及可伸缩性。
分布式锁实现
在分布式场景下,无法使用单机环境下的锁来对多个节点上的进程进行同步。
可以使用 Redis 自带的 SETNX 命令实现分布式锁,除此之外,还可以使用官方提供的 RedLock 分布式锁实现。
其它
Set 可以实现交集、并集等操作,从而实现共同好友等功能。
ZSet 可以实现有序性操作,从而实现排行榜等功能。