## 1. String (字符类型)
```
set key 1
get key
INCR key
DECR key
追加
append key 33 4
字符长度
strlen key
```
使用场景 使用的是最多的, 像保存登录人信息, 保存验证码, 保存流水号, 像字符串的递增数值 INCR key 和 递减数值 DECR key 可以用来做 播放量 阅读量等
## 2. Hash (散列类型)
```
结构类似 Map<String, Map<Object, Object>>
多个的时候 有个m
hset name key1 value1
hget name key2 获取key中的一个值
hmset name key1 value1 key2 value2
hmget name key1 key2 获取key中的多个值
hgetall name 获取key的所有值
hdel name key1
hlen name 获取key的全部数量
hdel name
增量是1
hset age 张三 18
hincrby age 张三 1 就从18变成19了
hincrby age 张三 -1 就从19变回18了
```
使用场景:购物车
shopCar:uid + 用户id 做key
新增商品:hset shopCar:uid111 555 1
再新增商品:hset shopCar:uid111 556 1
购物车现有商品数量增加1个: hincrby shopCar:uid111 555 1
总数: hlen shopCar:uid111
全选: hgetall shopCar:uid111
## 3. List (列表类型)
按照添加顺序保存, 可做排序的业务, 相当于按照添加时间倒序保存的
尽量不要做分页, 因为当添加的数据过快, 原来是在第一页显示, 后来有添加了数据, 就会导致之前第一页显示的, 又在第二页 或第n页再显示。后面的数据一直在添加, 这样原来是最新的数据, 就变成旧数据了, 页码里的数据也就会重复了
```
在 key 对应 list 的头部添加字符串元素
lpush name value
在 key 对应 list 的尾部添加字符串元素
rpush name value
返回 key 对应 list 的长度
llen name
读取列表
lrange name 0 9
```
使用场景: 商品足迹
lpush 商品足迹:userId 商品id1 商品id2
使用场景:订阅号
lpush likeArticle:userId 文章id1 文章id2 文章id3
// 前 10 条
lrange likeArticle:userId 0 9
## 4. Set (集合类型)
```
集合差集 属于A但不属于B
SDIFF keyA keyB [key...]
集合交集 属于A同时也属于B
SINTER keyA keyB [key...]
集合并集 属于A或者属于B的元素合并后的集合
SUNION keyA keyB [key...]
添加
SADD name value
移除集合中一个或多个成员
SREM name value[value2]
获取key 的全部成员
smembers name
获取key 的总数
scard key
随机选择n个元素, 元素不删除
srandmember key n
随机选择n个元素, 元素会删除
spop key n
判断 value 元素是否是集合 key 的成员
SISMEMBER key value
```
使用场景:抽奖
srandmember key n 和 spop key n 用作抽奖 如 奖品是一个手机 则key是手机id, value 则是一个个用户id
使用场景:点赞
sadd like:videoId userId1 userId2 userId3 新增点赞
srem like:videoId userId3 删除点赞
smembers like:videoId 点赞用户列表
scard like:videoId 点赞总数
sismember like:videoId userId2 判断某个用户是否点赞
使用场景:关注
sadd follow:meFollow:11 2 3 5 6 19 我关注的
sadd follow:followMe:11 5 14 16 9 关注我的
sadd follow:followMe:2 15 14 36 19 关注用户 2 的
sadd follow:meFollow:2 5 33 45 99 用户 2 关注的
SINTER follow:meFollow:11 follow:followMe:11 我关注他, 他也关注我
SINTER follow:meFollow:11 follow:meFollow:2 11和 2 共同关注的
SINTER follow:meFollow:11 follow:followMe:2 我关注的人, 同时也关注他 (用户11 关注用户19 和 用户2, 同时用户19也关注 用户2)
使用场景:qq 内推 可能认识的人 使用 SDIFF keyA keyB 或者 SDIFF keyB keyA 互相取差集
## 5. SortedSet(有序集合 简称 zset)
做排序分页
```
添加一个元素和该元素的分数 分数在前(score)
zadd key score member
zadd code 1 java
zadd code 2 css
zadd code 3 html
按照分数从小到大的顺序 返回索引从start 到 stop之间的元素
zrange key start stop [WITHSCORES]
zrange code 0 2 WITHSCORES
获取元素的分数
zscore key member
删除 元素
zrem key member
获取指定分数范围的元素
zrangebyscore key min max [WITHSCORES] [limit offset count]
获取指定分数范围的元素 前5个
zrangebyscore key min max limit 0 5
增加某个元素的分数
zincrby key increment member
zincrby key 5 member 增加5分
获取集合中元素的数量
zcard key
获取指定分数范围内的元素个数
zcount key min max
按照排名范围删除元素
zremrangebyrank key start stop
从小到大排名
zrank key member
从大到小排名
zrevrank key member
```
使用场景: 排行榜 热搜
zadd goods:sell 20 1111 50 2222 商品 1111 售出20 , 商品2222 售出 50
zrange goods:sell 0 9 withscores 前10
zincrby goods:sell 3 1111 商品 1111 又售出3
实战: 抖音面试题=> 获取抖音视频最新评论留言
涉及排序 分页 高并发
可以使用 list 和 zset
list 做分页可能会导致分页数据重复, 因为每次添加都会顶到最前面
zset 把时间戳到分数, 视频id 做值 zadd 抖音视频最新评论 时间戳 视频id 时间戳 视频id
zrank zrevrank 进行从小到大和从大到小排序
## 6. Bigmap(位图)
```
给指定 key 的值 的第 offset 赋值val
setbit key offset val
获取指定 key 的第offset位
getbit key offset
返回指定 key 中 [start, end] 中为1的数量
bitcount key start end
对不同的二进制存储数据进行位运算(AND OR NOT XOR)
bigop operation destkey key
```
bigmap 支持位数是2的32次方位, 512m大小
由0和1状态表现的二进制位的big数组 , 从0开始
底层是用String实现, get 命令也能获取, 获取道德是 ascii码
strlen 获取长度时, 每8位是一个长度
setbit key 6 0 使用 strlen key 获取的长度是1
setbit key 23 0 使用 strlen key 获取的长度是3
setbit key 364 0 使用 strlen key 获取的长度是46
场景: 用于状态统计, 用户是否登录过, 如京东每日签 到送京豆, 电影、广告是否被点击播放过
钉钉打卡上下班, 签到统计
日活统计
连续签到打卡
最近一周的活跃用户
统计指定用户一年中的登录天数
某用户按照一年365天, 哪几天登陆过
签到:mysql 也能做, 数据量小可以用,数据量大了就算了。
按月=> key =>业务前缀:用户id:年月 , 从0开始
0 未签到, 1签到了
setbig sign:uid1:202101 0 1 2021年1月1日 签到了
setbig sign:uid1:202101 1 1 2021年1月2日 签到了
setbig sign:uid1:202101 20 1 2021年1月21日 签到了
getbit sign:uid1:202101 0 判断 2021年1月1日 是否签到 这个返回1
getbit sign:uid1:202101 10 判断 2021年1月11日 是否签到 这个返回0
bigcount sign:uid1:202101 2021年1月签到总数
bigcount sign:uid1:202101 0 9 2021年1月1日到10日 签到总数
按年=> key =>业务前缀:用户id:年 , 从0开始
setbig sign:uid1:2021 0 1 2021年第一天 签到了
setbig sign:uid1:2021 364 1 2021年第365天 签到了
其他和按月的一样, 就是key变了
## 7. HyperLogLog(统计)
1\. 去重复
2\. 不直接存储数据本身
3\. 通过牺牲准确率来换取空间, 它不准确
UV(Unique visitor):指通过互联网访问、浏览这个网页的自然人。00:00-24:00 同一个访客多次访问算一次
PV(Page View):浏览量或点击量
VV(Visit View):访客1天内访问网站的次数。
DAU:daily active user(日活跃用户)
MAU:monthly active user(月活跃用户)
PV与VV区别:PV是指页面的浏览次数,VV是指你访问网站的次数。
统计某个网站的UV 统计某个文章的UV
用户搜索网站关键词的数量
统计用户每天搜索不同词条个数
基数统计:统一一个集合中不重复的元素个数
基数:是一种数据集,去重复后的真实个数
```
将所有元素添加到 key 中
pfadd key element1 element2 element3
统计 key 的估算值(不精确)
pfcount key
合并去重 key 至新key
pgmerge new_key key1 key2
```
8. GEO(地理)
geo 本质是 zset
type key 会返回zset
```
添加地理位置的坐标
geoadd key longitude latitude member [longitude latitude member ...]
获取地理位置的坐标
geopos key member [member ...]
计算两个位置之间的距离
geodist key member1 member2 [m|km|ft|mi]
根据用户给定的经纬度坐标来获取指定范围内的地理位置集合,用的最多,
像外卖平台的 查找多少km内的的商家
georadius key longitude latitude radius m|km|ft|mi [WITHCOORD]
[WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合
georadiusbymember key member radius m|km|ft|mi [WITHCOORD] [WITHDIST]
[WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
返回一个或多个位置对象的 geohash 值
geohash key member [member ...]
```
[https://www.runoob.com/redis/redis-geo.html](https://www.runoob.com/redis/redis-geo.html) geo 命令
- 学习地址
- MySQL
- 查询优化
- SQL优化
- 关于or、in、not in、!=等走不走索引的说明
- 千万级数据查询优化
- MySQL 深度分页问题
- 嵌套循环 Block Nested Loop 导致索引查询慢
- MySQL增加日志统计表优化各种日志表的统计功能
- MySQL单机读写QPS(性能)优化
- sqlMode 置 select 的值可以比 group 里的多
- drop、delete、truncate的区别
- 尚硅谷MySQL数据库高级学习笔记
- MySQL架构
- 事务部分
- MySQL知识点
- mysql索引
- Linux docker安装 mysql 8.0.25
- docker 安装mysql 5.7
- mysql Field ‘xxx’ doesn’t have a default value
- mysql多实例
- docker中的sql文件导入
- mysql进阶知识
- mysql字符集
- 连接的原理
- redo日志
- InnoDB存储引擎
- InnoDB的数据存储结构
- B+树索引
- 文件系统-表空间
- Buffer Pool
- 亿级数据导入到es
- MySQL数据复制
- MySQL缺少主键的表数据
- mysql update 其中更新的字段根据另一个更新字段作为条件去更新
- MySQL指定字段值排序(将指定值排在前面)
- 设置MySQL连接数、时区
- Navicat15右键删除数据刷新就又恢复了
- MySQL替换字段部分内容
- Java和MySQL统计本周本月本季和年
- 分页时order by 排序数据重复,丢失
- mysql同一张表根据某个字段删除重复数据
- mysqldump定时全量热备
- 专题总结
- 事务
- MySQL事务
- spring事务
- spring事务本类调用
- spring事务传播行为
- spring事务失效问题
- 锁和Transactional注解一块使用的问题
- 数据安全
- 敏感数据
- SQL注入
- 数据源
- XSS
- 接口设计
- 缓存设计
- 限流
- 自定义注解实现根据用户做QPS限流
- 架构
- 高可用
- Java
- Unsatisfied dependency expressed through field ‘baseMapper‘
- mybatisplus多数据源
- 单个字母前缀的java变量
- spring
- spring循环依赖解决
- 事务@Transactional
- yml 文件配置信息绑定到java工具类的静态变量上
- @Configuration @Component 区别
- springboot启动yml文件报错
- spring方法重试注解Retryable
- spring读取yml集合数据
- spring自定义注解
- 获取resource下的图片资源
- 手机号和电话号的正则验证
- 获取字符串中的数字
- mybatis
- mybatis多参数添加数据并返回主键
- 统一异常处理
- 分组校验
- Java读取Python json.dumps 函数保存的redis数据
- springboot整合springCache
- 若依mybatis值为null的字段没有返回
- 若依
- 接口白名单
- @JsonFormat时区问题
- RequestParam.value() was empty on parameter 0
- jdk8和hutool请求第三方的https报错
- springMVC
- springMVC与vue使用post传数组
- elementUI 时间组件报错问题
- vue具名插槽slot
- springboot配置maven的profiles(配置微服务多环境切换打包)
- resources 配置文件读取顺序
- Windows的cmd部署jar注意事项
- Java基础
- JUC(锁-并发-线程池)
- CAS
- Java 锁简介
- synchronized和Logk有什么区别?用新的ock有什么好处
- synchronized锁介绍
- CompletableFuture
- 多线程
- 线程池
- 集合类
- map见过的小问题
- 退出双层循环
- StringBuilder和StringBuffer核心区别
- 日志打印
- 打印log日志
- log日志文件生成配置
- 日期时间
- 时间戳转为时间
- 并发工具
- 连接池
- http调用
- 内网访问天地图
- 判等问题
- 数值计算
- null问题
- 异常处理
- 文件IO
- 序列化
- 内存溢出OOM
- 子线程的错误, 全局异常处理捕获不到
- vue同一个项目访问多个不同ip地址接口
- Autowired注解导入为null
- shiro
- UnavailableSecurityManagerException错误
- Windows服务器80端口被占用
- java图片增加水印
- springcloud
- Feign方法配置错误导致jar包启动失败
- feign调用超时
- 定时任务quartz
- JavaPOI导出Excel
- 合并行和列
- 设置样式
- 设置背景色
- docker
- Linux 安装
- docker命令
- docker网络
- docker数据卷
- dockerfile
- docker安装ping命令
- docker-compose
- docker-compose文件内容介绍
- Linux关闭docker开机启动
- jar打包为镜像
- 迁移docker容器存储位置
- Nginx
- Linux在线安装Nginx
- nginx.conf 核心配置文件
- vue 和 nginx 刷新页面会报404
- nginx 转发给三个集群的tomcat
- ServerName匹配规则
- Nginx负载均衡策略
- location 匹配规则
- Nginx 搭建前端调用后台接口的集群
- alias与root
- nginx 拦截 post 请求, 带参数转发到前端页面
- 防盗链配置
- Nginx的缓存
- 通用Nginx配置
- nginx配置文件服务器
- 后台jar包得不到正确ip,nginx代理时要处理
- 升级使用websocket协议
- 设置IP黑/白名单
- Redis
- 缓存数据一致性
- 内存淘汰策略
- Redis数据类型
- gmt6
- Linux安装GMT6
- GMT6配置中文
- GMT文件修改Windows版本到Linux版本
- 注意GMT不同字体导致符号不同的问题
- GMT绘制南海诸岛小图
- GMT生成中文图例
- elasticsearch
- 安装配置
- Linux安装配置elasticsearch7.6.2
- Linux 安装 kibana 7.6.2
- 安装7.6.2中文分词器
- docker 安装elasticsearch7.6.2
- 安装Logback7.6.2
- springboot使用
- 0. elasticsearch账号密码模式访问
- 1. 配置连接
- 2. 索引
- 3. 批量保存更新
- Result window is too large 10000
- elasticsearch 分词的字段做排序 fielddata, 设置fielddata=true 无效果
- elasticsearch 完全匹配查询(精确查询)
- 模糊搜索
- 日期区间查询
- 6.x基础知识
- 自定义词库
- elasticsearch集群
- 搜索推荐Suggester
- 查询es保存的数组
- 亿级mysql数据导入到es
- es 报错 ORBIDDEN/12/index read-only
- es核心概念
- es的分布式架构原理
- 优化大数据量时的ES查询性能
- canal
- 1. mysql的Binlog
- 2. Canal 的工作原理
- 3. canal同步es
- JVM
- 1 类的字节码
- 2. 类的加载
- JVM知识点
- Maven
- 依赖冲突
- xxl-job
- docker 安装配置 xxl-job
- idea
- springboot启动报错命令过长
- services统一启动微服务各模块
- 云服务器安装宝塔面板
- 突然出现启动或者运行特别慢
- 有导入依赖但是显示红色同时点击进去也有依赖
- Linux
- sh文件执行报错: command not found
- 使用vagrant安装虚拟机
- Linux 开启端口
- 开放端口
- 复制文件夹及其文件到另一个文件夹
- 两个服务器之间映射端口
- TCP协议
- 分层模型
- TCP概述
- 支撑 TCP 协议的基石 —— 首部字段
- 数据包大小对网络的影响 —— MTU 与 MSS 的奥秘
- 端口号
- 三次握手
- TCP 自连接
- 四次挥手
- TCP 头部时间戳
- 分布式
- 分布式脑裂问题
- 分布式事务
- 基础知识
- 实现分布式事务的方案
- 阿里分布式事务中间件seata
- 幂等性问题
- 其他工具
- webstorm git提交代码后project目录树不显示
- 消息队列
- 如何保证消费的顺序
- 数据结构
- 漫画算法:小灰的算法之旅