纸上得来终觉浅,绝知此事要躬行
2008 年,一家意大利创业公司嫌弃 MySQL 的性能,所以就自己搞了套数据库:Redis。这个个人开发的数据库究竟有哪些特性吸引着开发者?我将一一研读探秘:
特性
存储结构
Redis 的全称是 Remote Dictionary Server(远程字典服务器)
Redis 的键值除了是字符串还可以是其他数据类型:
- 字符串
- 散列
- 列表
- 集合
- 有序集合
内容存储与持久化
所有的数据都存储在内存中,内存的读写速度快于硬盘,一秒内可读写超过十万个键值。
功能丰富
键值的 TTL 、单线程模型、可实现队列
简单稳定
入门
字符串类型
字符串类型是 Redis 中最基本的类型,它能存储任何形式的字符串,包括二进制数据。是其他 4 种数据类型的基础,一个字符串类型键最大哦的容量是 512 MB。
SET key value |
散列类型
散列即 hash,其存储了字段 field 和 字段值的映射,「但字段值只能是字符串」,不支持其他数据类型。所以散列类型不能嵌套其他数据类型。
命名规范一般遵守:
key: 对象类型:id |
HSET key field value |
列表类型
Redis 列表类型内部使用双向链表(double linked list)实现,越接近两端速度越快,常用操作是两列表两端添加元素,或者获取列表片段。列表类型适合用来记录日志或者网站新鲜事。
LPUSH key value or RPUSH key value |
集合类型
集合:不保证顺序、唯一
SADD key member |
有序集合
- 内部是通过散列表和跳跃表实现的,所以即使读取中间的数据速度也很快(O(log(N)))
- 列表对于位置的调整不太方便,但有序集合可以(更改元素分数即可)
- 有序集合更消耗内存
ZADD key score memeber |
类型对比
数据类型 | 使用场景 | 备注 |
---|---|---|
string | 用于存储普通数据,int,string等等类型的基本类型数据 | |
hash | 通常用于存储数据对象类型 | |
list | 用于存储一些有序列表 | 双端操作较快,适用于日志、 可实现队列(其实我也没实践过,哭 |
set | 无序集合 | |
sort set | 有序集合 |
有些关于 Redis Key 命名的设计规范,我借鉴了 Redis 开发设计规范及案例分析 做了以下总结,并且在实际场景中有所运用
- 可读性: 以业务名为前缀,用冒号分隔,可使用业务名:子业务名:id 的结构命名,子业务下多单词可再用下划线分隔。
- 简洁性:这里需要控制 key 的长度,key 的占用内存不容忽视。
- 不包含转义:不包含空格、换行、单双引号以及其他转义字符。
一些高级用法
事务
事务是「一组命令」的集合:要么执行,要么都不执行。只有所有的命令都执行完成才能得到每个结果的返回值。
事务的错误:
- 语法错误:只要有一个错误就会不会执行。
- 运行错误:如果某条命令错误,那么其他命令会继续执行。(Redis 并没有事务回滚 rollback 的功能
WATCH
防止竞态:在 GET 获得键值后不被其他客户端修改。直到函数完成后才允许其他客户端修改。
请出事务家族的另外一位成员「WATCH」
WATCH 命令可以监控一个或者多个键,一旦其中一个键被修改或删除之后的事务就不再执行。监控直到 EXEC 执行。
过期时间
通过 EXPIRE 设置某个 key 的过期时间