【Redis】五大数据类型 、历史概述、nosql分类

news2024/11/25 6:48:57

文章目录

  • NoSql概述
    • NoSql年代
      • 缓存 Memcached + MySQL+垂直拆分(读写分离)
      • 分库分表+水平拆分+Mysql集群
      • 最近
      • 为什么要用
  • NoSql
    • NoSql的四大分类
  • Redis
    • 测试性能
  • 五大数据类型
    • key
    • String
    • Set
    • Hash
    • Zset

前言:本文为看狂神视频记录的笔记

NoSql概述

NoSql年代

image-20230926140610643

问题:数据量过大、数据索引过大(B+Tree),机器内存不够、访问量(读写混合),服务器承受不了

缓存 Memcached + MySQL+垂直拆分(读写分离)

网站80%的情况下在读取,用MySQL太过繁琐;希望减轻数据库的压力,可以使用缓存保证效率

发展过程:优化数据结构和索引->文件缓存(IO)->Memcached(当时最热门技术)

image-20230926141231699

分库分表+水平拆分+Mysql集群

image-20230926142142451

本质:数据库的读和写

早些年MyISAM:表锁,(读写时,所在的表被锁,十分影响并发性)

Innodb:行锁

最近

MySQL关系型数据库不够用,数据多且变化快

用:图型;JSON

MySQL有的使用他来存储较大文件,数据库很大,效率变低,如果有专门数据库负责,压力就会变小

目前一个基本的互联网项目

image-20230926143549331

为什么要用

用户的个人信息、地理位置,用户自己产生的数据、用户日志爆炸式增长,nosql能很好的处理以上问题

NoSql

NoSql = Not Only Sql(不仅仅是Sql)

关系型数据库:表格,行,列

泛指非关系型数据库,传统关系型数据库很难对付web2.0时代,尤其是超大规模的高并发的社区。NoSql在当今大数据环境下发展十分迅速,Redis是发展最快的,而且是我们当下必须要掌握的一个技术!

很多的数据类型用户的个人信息,社交网络,地理位置。这些数据类型存储不需要一个固定的格式,不需要多余的操作就可以横向扩展!使用键值对来存放。

NoSql特点—解耦

1、方便扩展(数据之间没有关系,很好扩展)

2、大数据量高性能(NoSql的缓存记录级,是一种细粒度的缓存,性能会比较高,redis一秒写8万次读11万次)

3、数据类型是多样型(不需要设计数据库,随取随用)

4、传统的RDBMS和NoSql

传统的 RDBMS(关系型数据库)

  • 结构化组织
  • SQL
  • 数据和关系都存在单独的表中
  • 操作语言,定义语言
  • 严格的一致性

Nosql

  • 不仅仅是数据
  • 没有固定的查询语言
  • 键值对存储,文档存储,图形数据库(社交关系)
  • 最终一致性
  • CAP定理和BASE (异地多活)
  • 高性能,高可用,高可扩

了解:3V+3高

  • 大数据时代的3V:主要是描述问题的

1、海量Volume

2、多样Variety

3、实时Velocity

  • 互联网需求的3高:主要是对程序的要求

1、高并发(Java JUC)

2、高可拓(随时水平拆分,机器不够了,扩展机器来解决)

3、高性能(保证用户体验和性能)

NoSql+RDBMS->《阿里巴巴的架构演进》

NoSql的四大分类

KV键值对

  • 新浪:Redis
  • 美团:Redis+Tair
  • 阿里、百度:Redis+MemCache

文档型数据库:(bson格式和json一样)

  • MongoDB
    • mongodb基于分布式文件存储的数据库,C++编写,主要用来处理大量的文档
    • MongoDB是一个介于关系型数据库和非关系型数据库中间的产品,MongoDB是非关系型数据库中功能最丰富,最想关系型数据库的。
  • ConthDB

列存储数据库

  • HBase
  • 分布式文件系统

图关系数据库

不是存图形,放的是关系,比如朋友圈社交网络

  • neo4j
  • InfoGrid
  • redisgraph

image-20230926212210667

Redis

Redis是什么?

Redis(RemoteDictionaryServe),即远程字典服务

Redis能干嘛?

1、内存存储,持久化,内存中是断电即失,所以说持久化很重要(rdb、aof)

2、效率高,可以用于高速缓存

3、发布订阅系统

4、地图信息分析

5、计时器、计数器(浏览量! )

特性

1、多样的数据类型

2、持久化

3、集群

4、事物

测试性能

image-20231002173758453

简单测试

# 测试:100个并发连接 100000请求
redis-benchmark -h localhost -p 6379 -c 100 -n 100000

测试图

image-20231002183118491

redis默认有16个数据库,默认使用第0个

127.0.0.1:6379> config get databases # 命令行查看数据库数量databases
1) "databases"
2) "16"

127.0.0.1:6379> select 8 # 切换数据库 DB 8
OK
127.0.0.1:6379[8]> dbsize # 查看数据库大小
(integer) 0

# 不同数据库之间 数据是不能互通的,并且dbsize 是根据库中key的个数。
127.0.0.1:6379> set name sakura 
OK
127.0.0.1:6379> SELECT 8
OK
127.0.0.1:6379[8]> get name # db8中并不能获取db0中的键值对。
(nil)
127.0.0.1:6379[8]> DBSIZE
(integer) 0
127.0.0.1:6379[8]> SELECT 0
OK
127.0.0.1:6379> keys *
1) "counter:__rand_int__"
2) "mylist"
3) "name"
4) "key:__rand_int__"
5) "myset:__rand_int__"
127.0.0.1:6379> DBSIZE # size和key个数相关
(integer) 5

keys * :查看当前数据库中所有的key。

flushdb:清空当前数据库中的键值对。

flushall:清空所有数据库的键值对。

Redis是单线程的,Redis是基于内存操作的。所以Redis的性能瓶颈不是CPU,而是机器内存和网络带宽。

那么为什么Redis的速度如此快呢,性能这么高呢?QPS达到10W+

Redis为什么单线程还这么快?

误区1:高性能的服务器一定是多线程的?
误区2:多线程(CPU上下文会切换!)一定比单线程效率高!
核心:Redis是将所有的数据放在内存中的,所以说使用单线程去操作效率就是最高的,多线程(CPU上下文会切换:耗时的操作!),对于内存系统来说,如果没有上下文切换效率就是最高的,多次读写都是在一个CPU上的,在内存存储数据情况下,单线程就是最佳的方案。

五大数据类型

Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。

key

在redis中无论什么数据类型,在数据库中都是以key-value形式保存,通过进行对Redis-key的操作,来完成对数据库中数据的操作。

exists key:判断键是否存在
del key:删除键值对
move key db:将键值对移动到指定数据库
expire key second:设置键值对的过期时间
type key:查看value的数据类型

127.0.0.1:6379> keys * # 查看当前数据库所有key
(empty list or set)
127.0.0.1:6379> set name qinjiang # set key
OK
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> move age 1 # 将键值对移动到指定数据库
(integer) 1
127.0.0.1:6379> EXISTS age # 判断键是否存在
(integer) 0 # 不存在
127.0.0.1:6379> EXISTS name
(integer) 1 # 存在
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> keys *
1) "age"
127.0.0.1:6379[1]> del age # 删除键值对
(integer) 1 # 删除个数


127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> EXPIRE age 15 # 设置键值对的过期时间

(integer) 1 # 设置成功 开始计数
127.0.0.1:6379> ttl age # 查看key的过期剩余时间
(integer) 13
127.0.0.1:6379> ttl age
(integer) 11
127.0.0.1:6379> ttl age
(integer) 9
127.0.0.1:6379> ttl age
(integer) -2 # -2 表示key过期,-1表示key未设置过期时间

127.0.0.1:6379> get age # 过期的key 会被自动delete
(nil)
127.0.0.1:6379> keys *
1) "name"

127.0.0.1:6379> type name # 查看value的数据类型
string

关于TTL命令

Redis的key,通过TTL命令返回key的过期时间,一般来说有3种:

当前key没有设置过期时间,所以会返回-1.
当前key有设置过期时间,而且key已经过期,所以会返回-2.
当前key有设置过期时间,且key还没有过期,故会返回key的正常剩余时间.
关于重命名RENAME和RENAMENX

RENAME key newkey修改 key 的名称
RENAMENX key newkey仅当 newkey 不存在时,将 key 改名为 newkey 。
更多命令学习:https://www.redis.net.cn/order/

String

image-20230928204239818

127.0.0.1:6379> set views 0    #初始浏览量为0  
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views    #自增1,浏览量变为1
(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     #自减1
(integer) 1
127.0.0.1:6379> incrby views 10   #自增10
(integer) 11
127.0.0.1:6379> incrby views 10
(integer) 21
127.0.0.1:6379> decrby views 5   #自减5
(integer) 16

截取字符串getrange

127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set key1 "fang"
OK
127.0.0.1:6379> get key1
"fang"
127.0.0.1:6379> getrange key1 0 2  #截取012字符串
"fan"
127.0.0.1:6379> getrange key1 0 -1 #获取全部字符串
"fang"
127.0.0.1:6379> 

替换setrange

127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> get key2
"abcdefg"
127.0.0.1:6379> setrange key2 1 xx
(integer) 7
127.0.0.1:6379> get key2
"axxdefg"
127.0.0.1:6379> 

setex:设置过期时间
setnx :不存在在设置(在分布式锁中常常使用)**

127.0.0.1:6379> setex key3 30 "hello"
OK
127.0.0.1:6379> ttl key3
(integer) 17
127.0.0.1:6379> setnx mykey "redsi" #如果mykey存在,则创建失败。
(integer) 1
127.0.0.1:6379> keys *
1) "mykey"
2) "key2"
3) "key1"
127.0.0.1:6379> ttl key3
(integer) -2
127.0.0.1:6379> setnx mykey "MongDB"
(integer) 0
127.0.0.1:6379> get mykey
"redsi"

一次性获取,设置多个值:mset,mget

127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3     #同时设置多个值
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> mget k1 k2 k3    #同时获取多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k4 v4   #msetnx是一个原子性操作,要么成功要么失败
(integer) 0
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379> 

对象

mset user:1{name:zhangsan,age:3}   #设置一个user:1对象 值为json字符来保存一个对象

这里的key设计:user:{id}:{field}

127.0.0.1:6379> mset user:1:name fang user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "fang"
2) "2"
127.0.0.1:6379> 

先get在set-------getset

127.0.0.1:6379> getset db redis #没有值则返回nil
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb #先获取原来的值再设置新的值
"redis"
127.0.0.1:6379> get db
"mongodb"

string类型的使用场景:value除了字符串还可以是数字

  • 计数器
  • 统计多单位数量
  • 粉丝数
  • 对象缓存存储

Set

redis里面可以把list完成栈,队列,阻塞队列!
所有的list命令以l开头

127.0.0.1:6379> lpush list one #将一个或多个值插入列表头部(左)尾部添加值为Rpush
(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"
3) "one"
127.0.0.1:6379> lrange list 0 1
1) "three"
2) "two"

移除元素

127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LPOP list #移除list第一个元素
"three"
127.0.0.1:6379> RPOP list #移除list最后一个元素
"one"

lindex 通过下标获得值

127.0.0.1:6379> lindex list 1
"one"
127.0.0.1:6379> lindex list 0
"two"

llen返回列表长度

...
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> llen list #返回列表长度
(integer) 3

移除指定值lrem

127.0.0.1:6379> LPUSH list three one four
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "four"
2) "one"
3) "three"
4) "two"
127.0.0.1:6379> LREM list 2 one #移除list中指定个数的value,2个one
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "four"
2) "three"
3) "two"

trim 修剪list

127.0.0.1:6379> LRANGE LIST 0 -1
1) "four"
2) "one"
3) "three"
4) "two"
5) "five"
127.0.0.1:6379> LTRIM LIST 1 3 #通过下标截取指定长度, LIST已被改变
OK
127.0.0.1:6379> LRANGE LIST 0 -1
1) "one"
2) "three"
3) "two"

rpop lpush,将列表右边元素移到另一个列表的左边

...
127.0.0.1:6379> rpush mylist "2"
(integer) 3
127.0.0.1:6379> rpoplpush mylist myother  #移除列表中最后一个元素,将他add到新列表中
"2"
127.0.0.1:6379> lrange mylist 0 -1
1) "0"
2) "1"
127.0.0.1:6379> lrange myother 0 -1
1) "2"

lset list 0 item将下标为0的元素替换为item

127.0.0.1:6379> exists list    #判断列表是否存在
(integer) 0
127.0.0.1:6379> lset list 0 item  #如果不存在列表。则会报错
(error) ERR no such key
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lrange list 0 0
1) "value1"
127.0.0.1:6379> lset list 0 item  #存在则更新下标
OK
127.0.0.1:6379> LSET list 1 other
(error) ERR index out of range

linsert 在指定值的前面或者后面插入具体值

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> LINSERT list before two three
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LINSERT list AFTER two five
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "five"
4) "one"

小结:
1.实际上是一个双向链表
2.key不存在,创建新链表
3.移除所有元素,相当于空链表,代表不存在
4.在两边插入或者改动值,效率高,中间元素,相对效率低
可以做消息队列

Hash

redis hash是一个String类型的field和value映射表,hash特别适合用来存储对象

set是一个简化的hash,只变动key,而value使用默认值填充,可以将一个Hash表作为一个对象存储,表中存放对象的信息

命令作用
HSET key field value将哈希表key的字段field的值设为value,重复设置则被覆盖,返回0
HMSET key field1 value1[field2 value2]…同时将多个键值对设置到哈希表key中
HSETNX key field value当字段不存在时,设置字段值
HEXISTS key field查看哈希表key中field是否存在
HGET key field value获取存储在field中的值
HMGET key field1 [field2…]获取所有给定field的值
HGETALL key获取在哈希表key的所有字段和值
HKEYS key获取哈希表key中的所有field
HLEN key获取哈希表中字段的数量
HVALS key获取所有的值
HDEL key field1 [field2…]删除哈希表key中的一个或多个field
HINCRBY key field n为key中的指定field整数值加上增量n,并返回增量后结果一样只适用于整数型字段
HINCRBYFLOAT key field n为key的指定字段的浮点数值加上增量n
HSCAN key cursor [MATCH pattern] [COUNT count]迭代哈希表中的键值对

Zset

有序集合,每一个元素都会关联一个double类型的分数,redis通过分数来为集合中的成员进行从小到大的排序。socre相同,按字典顺序排序

有序集合成员是唯一的,但分数是可以重复的

image-20231002190314728

应用案例:

  • set排序 存储班级成绩表 工资表排序!
  • 普通消息,1.重要消息 2.带权重进行判断
  • 排行榜应用实现,取Top N测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1056814.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Django】4 Django模型

每个模型是一个Python 类,集成django.db.models.Modle类 该模型的每个属性表示一个数据库表字段 通过API 自动生成数据库访问 .../sign/modles.py 文件,通过模型完成表创建。 TypeError: ForeignKey.__init__() missing 1 required positional argumen…

ChatGPT多模态升级,支持图片和语音,体验如何?

一、前言 9 月 25 日,ChatGPT 多模态增加了新的语音功能和图像功能。这些功能提供了一种新的、更直观的界面,允许我们与 ChatGPT 进行语音对话或展示我们正在谈论的内容。 ChatGPT 现在可以看、听、和说话了,而不单单是一个文本驱动的工具了。…

算法通过村第十一关-位运算|白银笔记|高频题目

文章目录 前言1. 位移的妙用1.1 位1的个数1.2 比特位计算1.3 颠倒无符号整数 2. 位实现加减乘除专题2.1 位运算实现加法2.2 递归乘法 总结 前言 提示:他不是不想多明白些,但是每每在该用脑子的时候,他用了感情。 --老舍《黑白李》 与位运算和…

Centos7安装php-fpm

目录 第一步:查看系统IP地址和网卡名称 第二步:更改网络配置模式 第三步、重启network 查看iptablies ,将第十行,十一行删除 第四步:关闭config 第五步:创建nginx 文件夹 查看目录下的文件 进入nginx文件夹 第…

基于java的鲜花销售系统/网上花店

摘 要 本毕业设计的内容是设计并且实现一个基于Spring Boot框架的驿城鲜花销售系统。它是在Windows下,以MYSQL为数据库开发平台,Tomcat网络信息服务作为应用服务器。驿城鲜花销售系统的功能已基本实现,主要包括首页、个人中心、用户管理、鲜…

【VIM】初步认识VIM-2

2-6 Vim 如何搜索替换_哔哩哔哩_bilibili 1-6行将self改成this 精确替换quack单词为交

CSS基础语法第二天

目录 一、复合选择器 1.1 后代选择器 1.2 子代选择器 1.3 并集选择器 1.4 交集选择器 1.4.1超链接伪类 二、CSS特性 2.1 继承性 2.2 层叠性 2.3 优先级 基础选择器 复合选择器-叠加 三、Emmet 写法 3.1HTML标签 3.2CSS 四、背景属性 4.1 背景图 4.2 平铺方式 …

NPDP产品经理知识(市场调研-文化,团队,领导力)

--- VOC --- 市场调研的关键步骤 1.> 定义问题 2.>定义结果的准确度 3.>收集数据 4.>分析和解读数据 5.>得出结论 6.>实施 --- 二级市场研究/一级市场研究 --- 定性 > 焦点小组 > 深度访谈 > 人种学(On-Site In-Home) > 客户…

基于web的医院预约挂号系统/医院管理系统

摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代&a…

【ElasticSearch 集群】Linux安装ElasticSearch集群(图文解说详细版)

上次我们讲了linux环境安装ElasticSearch Linux安装ElasticSearch以及Ik分词器(图文解说详细版) 这次我们来将一下ElasticSearch的集群安装 安装es的前置条件: Linux安装Java环境(OracleJDK) 这次我们安装的是Elasti…

GraphQL全面深度讲解

目录 一、GraphQL 是什么 二、GraphQL 规范 数据模型 字段 参数 三、运行示例 四、优势和劣势 优势 劣势 一、GraphQL 是什么 GraphQL 是一种用于 API 的查询语言,也是一个基于服务端的运行引擎。 GraphQL 提供了一套完整的规范和描述用于查询 API&#xf…

Django基础入门操作 (Django-01)

一 背景介绍 Django是一个开源的 Web应用框架,由Python写成。采用了MTV的框架模式,它最初是被用来做CMS(内容管理系统)软件。 官方中文文档:Django 文档 | Django 文档 | Django 应用:做内容管理系统(新…

JUC第十三讲:JUC锁: ReentrantLock详解

JUC第十三讲:JUC锁: ReentrantLock详解 本文是JUC第十三讲,JUC锁:ReentrantLock详解。可重入锁 ReentrantLock 的底层是通过 AbstractQueuedSynchronizer 实现,所以先要学习上一章节 AbstractQueuedSynchronizer 详解。 文章目录 …

数据结构与算法基础(青岛大学-王卓)(8)

哎呀呀,sorry艾瑞波地,这次真的断更一个月了,又发生了很多很多事情,秋风开始瑟瑟了,老父亲身体查出肿瘤了,有病请及时就医,愿每一个人都有一个健康的身体,God bless U and FAMILY. 直…

实现简单BS架构案例

BS架构简单通俗理解 就是 浏览器–服务器模式,浏览器 充当 我们的客户端。 目录 简单BS架构实现案例基本原理视图访问规则案例要求改造前服务端线程模版类 改造后(优化)优化策略服务端线程模版类 参考视频 简单BS架构实现案例 基本原理视图 注:服务器必…

【VsCode】SSH远程连接Linux服务器开发,搭配cpolar内网穿透实现公网访问

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…

奥斯卡·王尔德

奥斯卡王尔德 奥斯卡王尔德(Oscar Wilde,1854年10月16日—1900年11月30日),出生于爱尔兰都柏林,19世纪英国(准确来讲是爱尔兰,但是当时由英国统治)最伟大的作家与艺术家之一&#xf…

【Java 进阶篇】JDBC ResultSet 遍历结果集详解

在Java数据库编程中,经常需要执行SQL查询并处理查询结果。ResultSet(结果集)是Java JDBC中用于表示查询结果的关键类之一。通过遍历ResultSet,我们可以访问和操作从数据库中检索的数据。本文将详细介绍如何使用JDBC来遍历ResultSe…

手把手教你做个智能加湿器(一)

一、前言 目前常见的加湿器类电子产品一般是由PCBA和外壳组成,我们将从PCB设计,然后编写软件,接着设计外壳,设计出一个完整的产品出来。 需要使用到软件: Altium Designer 17 SolidWorks 2019 Keil 4 二…

C++--位图和布隆过滤器

1.什么是位图 所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。比如int 有32位,就可以存放0到31这32个数字在不在某个文件中。当然,其他类型也可以。 2.位…