SQL实践篇(三):什么是Redis

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: SQL实践篇(三):什么是Redis

 

简介

Redis是一种基于内存的键值数据库,键值数据库会使用哈希表存储key和value。其中key和value可以是任何内容,无论是简单对象还是复杂对象。

键值数据库是NoSQL思想,其规则是"只提供你想要的",因此模型很灵活,查询效率也高,成本也低。

而RDBMS是建立在关系模型的基础上,强调的是数据的一致性和各种约束条件,成本很高。

本节我们将从以下几个方面,简单了解下Redis:

· Redis是什么,为什么它这么快?

· Redis支持的数据类型都有哪些?

Redis是什么,为什么这么快?

Redis,全称是REmote Dictionary Server

Redis的查询效率非常高,根据官方的数据,Redis每秒最多处理的请求可以达到10w次。

为什么这么快呢?

Redis是采用ANSI C语言编写的,跟SQLite一样。这样的好处是底层代码执行效率更高,相比面向对象的语言,依赖性也更低。系统兼容性好,稳定性高。

 

另外,Redis是基于内存的数据库,没有磁盘IO的限制,自然快的飞起。

 

其次,数据结构简单,采用key-value的方式进行存储,也就是使用Hash结构进行操作,数据的操作复杂度为O(1)。

 

但是Redis快的原因远不止这些,还有很多各种各样的原因,比如说它采用单进程单线程的模型,避免了上下文切换和不必要的线程资源争抢问题。

 

在技术上,Redis还采用了多路IO复用技术。这里的多路指的是多个socket网络连接,复用指的是复用同一个线程。这样的好处是可以在同一个线程中处理多个IO请求,尽量减少网络IO的损耗。

 

可以看到,Redis可以说是把效率做到了极致,各方各面可能存在的时间消耗都被优化过。

 

2023-11-10 00:47:47 不过,在2020年新推出的Redis6.0版本里,还是引进了多线程模型,来提高Redis的性能和并发能力。不过Redis默认情况下不会开启多线程模式,官方建议是除非达到了性能瓶颈,否则没必要开启多线程。

Redis的数据类型

Memcached也是一个键值型数据库,但与它相比,Redis还有一个非常大的优势,就是支持多种数据类型。

 

Redis支持的数据类型包括字符串、哈希、列表、集合、有序集合等。

 

字符串

字符串类型是Redis提供的最基本的数据类型。对应的结构是key-value

 

如果我们想要设置某个键的值,可以使用set key value,如果想要获取某个值,那就用get key。如图:

image.png

Hash

哈希(hash)进一步提供了字段和字段值的映射,对应的结构是key-field-value。

设置某个键的哈希值hset key field value

比如说要给user1设置username为zhangfei,设置age为28,可以写成:

image.png


或者可以连写成:

image.png

取出某个键的某个field字段hget key field

比如说hget user1 username

一次性取出某个键的多个field字段hmget key field_1 field_2...

比如说hmget user1 usename age

image.png

字符串列表

字符串列表(list)的底层是一个双向链表结构,所以我们可以向链表的两头添加元素,时间复杂度都是O(1),同时我们也可以比较方便的获取列表中的某个片段。

向列表左侧添加元素LPUSH key value [...]

比如说我要在heroslist列表左侧添加zhagnfei、guanyu、liubei这三条数据,可以写成:

image.png

向列表右侧添加元素RPUSH key value [...]

获取某一片段的内容

image.png

如获取herolist从0到4位置的数据,写成:LRANGE herolist 0 4即可。

image.png


字符串集合

字符串集合(set)是字符串类型的无序集合,与列表(list)的区别是集合内的元素是无序且不重复的。

在集合中添加元素SADD key member [....]

比如我想在heroSet集合添加zhangfei、guanyu、liubei、dianwei和lvbu这五个元素,可以写成:

image.png

在集合中删除元素SREM key member [....]

比如我们想在heroSet集合中删除liubei和lvbu两个元素,可以写成:

image.png

获取集合内全部元素SISMEMBER key

比如我想获取heroSet集合中的所有元素,可以写成(可以理解成s is member):

image.png

判断集合内是否存在某个元素SISMEMBER key member

比如要判断集合中是否存在zhangfei和liubei,可以写成:

image.png

image.png

有序字符串集合

有序字符串集合(SortedSet,简称ZSET),可以理解成是集合的升级版,是内部有序的集合。

 

实际上,ZSET是在集合的基础上增加了一个分数属性,这个属性在添加和修改元素的时候可以被指定。每次指定后,ZSET都会按照分数来自动排序。

 

有序集合跟列表有一定程度上的相似性。比如这俩都是有序的,都可以获取某一范围内的数据,但是它们在数据结构上有很大的不同。

 

列表是通过双向链表的结构来实现的,因此在操作左右两侧的数据时比较快,但是越到中间的数据,操作的越慢,整体查询的时间复杂度是O(n)。

 

有序集合的实现结构比较复杂,它在内部是通过Hash表的形式来存储所有元素和分数,因此查找指定元素的分数时,时间复杂度是O(1),因为通过哈希值可以直接找到位置。

同时它还通过跳表(skiplist)来维护元素的顺序,类似二叉树或者二分查找,不管读哪部分的数据都会比较快,因此涉及到顺序的操作时,查询的时间复杂度是O(log(N))。同时有序集合可以通过score来灵活调整元素位置,但是列表就不行了,它调整比较麻烦。

 

什么是跳表呢?在参考文献4里扒了一张图,描述的很形象:

image.png

其实非常类似B+树结构。

 

假设链表有N个节点,每2个节点生成一个上层索引,则第一层索引的节点数为N/2,第二层则是第一层的一半,即N/4,依次类推,第h层的节点个数就是N / ( 2 h ) N/(2^h)N/(2

h

),因此整个跳表的高度就是l o g 2 ( N ) log_2(N)log

2

(N),跟二叉树一样了,所以查询的时间复杂度就是l o g ( N ) log(N)log(N)。

 

有兴趣了解跳表结构的话,可以看一下参考文献4,写的非常形象。

在有序列表中添加元素和分数ZADD key score member [...]

比如我们给heroScore集合添加下面5个英雄的hp_max数值作为score,如下表:

image.png

所以可以写成:

image.png

获取某个元素的分数ZSCORE key member

比如获取关羽的分数:

image.png

删除一个或多个元素ZREM key member [member...]

比如删除guanyu这个元素:

image.png

获取某个范围内的元素列表

· ZRANGE key start stop [WITHSCORES]:按分数从小到大排序,即ASC;

· ZREVRANGE key start stop [WITHSCORES]:按分数从大到小排序,即DESC;

其中WITHSCORES是个可选项,加上的表示需要将分数一起显示出来。

比如说要查询heroScore这个有序集合中分数排名前3的英雄及数值,可以写成:

image.png

image.png

其他数据类型

除了以上5种数据类型之外,Redis还支持位图(Bitmaps)数据结构。

 

在2.8版本之后,增加了基数统计(HyperLogLog)。

 

3.2版本之后,加入了地理空间(Geospatial)以及索引半径查询的功能。

 

5.0版本,引入了数据流(Streams)数据类型。

总结

了解Redis还是非常重要的。在实际的工作中,我们经常会将RDBMS和Redis配合使用,优势互补。

 

作为常见的 NoSQL 数据库,Redis 比Memcached 的优势要高很多:

 

Redis支持的数据类型比 Memcached 丰富得多,

在 I/O 性能上,Redis 采用的是单线程 I/O 复用模型,而 Memcached 是多线程,可以利用多核优势。

在持久化上,Redis 提供了两种持久化的模式(RDB和AOF),可以让数据永久保存,这是 Memcached 不具备的。

MongoDB里可以通过mmp调用来将数据映射到内存中。可以将mmp理解成是一种加速的手段。其将文件映射到调用进程的地址空间里,实现了文件所在的磁盘物理地址与进程空间的虚拟地址一一映射的关系,这样就可以直接在内存中进行操作,然后写完成之后同步一下就可以存放到文件中,效率非常高。有兴趣可以去了解一下。

 

另外,Redis中的有序集合比较特殊,它通过Hash表的形式来存储所有元素和分数,同时使用跳表来维护元素的顺序。因此不同场景下的查询时间复杂度会有不同。

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
存储 缓存 NoSQL
深入理解Django与Redis的集成实践
深入理解Django与Redis的集成实践
74 0
|
3月前
|
SQL 存储 API
Flink实践:通过Flink SQL进行SFTP文件的读写操作
虽然 Apache Flink 与 SFTP 之间的直接交互存在一定的限制,但通过一些创造性的方法和技术,我们仍然可以有效地实现对 SFTP 文件的读写操作。这既展现了 Flink 在处理复杂数据场景中的强大能力,也体现了软件工程中常见的问题解决思路——即通过现有工具和一定的间接方法来克服技术障碍。通过这种方式,Flink SQL 成为了处理各种数据源,包括 SFTP 文件,在内的强大工具。
191 15
|
4月前
|
SQL 存储 Unix
Flink SQL 在快手实践问题之设置 Window Offset 以调整窗口划分如何解决
Flink SQL 在快手实践问题之设置 Window Offset 以调整窗口划分如何解决
69 2
|
17天前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
34 8
|
1月前
|
缓存 NoSQL Redis
Redis 缓存使用的实践
《Redis缓存最佳实践指南》涵盖缓存更新策略、缓存击穿防护、大key处理和性能优化。包括Cache Aside Pattern、Write Through、分布式锁、大key拆分和批量操作等技术,帮助你在项目中高效使用Redis缓存。
232 22
|
2月前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:百万级数据统计优化实践
【10月更文挑战第21天】 在处理大规模数据集时,传统的单体数据库解决方案往往力不从心。MySQL和Redis的组合提供了一种高效的解决方案,通过将数据库操作与高速缓存相结合,可以显著提升数据处理的性能。本文将分享一次实际的优化案例,探讨如何利用MySQL和Redis共同实现百万级数据统计的优化。
99 9
|
2月前
|
SQL 关系型数据库 MySQL
Go语言项目高效对接SQL数据库:实践技巧与方法
在Go语言项目中,与SQL数据库进行对接是一项基础且重要的任务
87 11
|
2月前
|
SQL 存储 关系型数据库
添加数据到数据库的SQL语句详解与实践技巧
在数据库管理中,添加数据是一个基本操作,它涉及到向表中插入新的记录
|
2月前
|
SQL 关系型数据库 数据库
SQL数据库:核心原理与应用实践
随着信息技术的飞速发展,数据库管理系统已成为各类组织和企业中不可或缺的核心组件。在众多数据库管理系统中,SQL(结构化查询语言)数据库以其强大的数据管理能力和灵活性,广泛应用于各类业务场景。本文将深入探讨SQL数据库的基本原理、核心特性以及实际应用。一、SQL数据库概述SQL数据库是一种关系型数据库
96 5
|
2月前
|
SQL 开发框架 .NET
ASP连接SQL数据库:从基础到实践
随着互联网技术的快速发展,数据库与应用程序之间的连接成为了软件开发中的一项关键技术。ASP(ActiveServerPages)是一种在服务器端执行的脚本环境,它能够生成动态的网页内容。而SQL数据库则是一种关系型数据库管理系统,广泛应用于各类网站和应用程序的数据存储和管理。本文将详细介绍如何使用A
84 3