Redis String 类型操作及常用命令
七个原则
- Redis 是一个操作数据结构的语言工具,它提供基于 TCP 的协议以操作丰富的数据结构。在 Redis 中,数据结构这个词的意义不仅表示在某种数据结构上的操作,更包括了结构本身及这些操作的时间空间复杂度。
- Redis 定位于一个内存数据库,正是由于内存的快速访问特性,才使得 Redis 能够有如此高的性能,才使得 Redis 能够轻松处理大量复杂的数据结构, Redis 会尝试其它的存储方面的选择,但是永远不会改变它是一个内存数据库的角色。
- Redis 使用基础的 API 操作基础的数据结构, Redis 的 API 与数据结构一样,都是一些最基础的元素,你几乎可以将任何信息交互使用此 API 格式表示。作者调侃说,如果有其它非人类的智能生物存在,他们也能理解 Redis 的 API。因为它是如此的基础。
- Redis 有着诗一般优美的代码,经常有一些不太了解 Redis 有的人会建议 Redis 采用一些其它人的代码,以实现一些 Redis 未实现的功能,但这对我们来说就像是非要给《红楼梦》接上后四十回一样。
- Redis 始终避免复杂化,我们认为设计一个系统的本质,就是与复杂化作战。我们不会为了一个小功能而往源码里添加上千行代码,解决复杂问题的方法就是让复杂问题永远不要提复杂的问题。
- Redis 支持两个层成的 API,第一个层面包含部分操作 API,但它支持用于分布式环境下的 Redis。第二个层面的 API 支持更复杂的 multi-key 操作。它们各有所长,但是我们不会推出两者都支持的 API,但我们希望能够提供实例间数据迁移的命令,并执行 multi-key 操作。
- 我们以优化代码为乐,我们相信编码是一件辛苦的工作,唯一对得起这辛苦的就是去享受它。如果我们在编码中失去了乐趣,那最好的解决办法就是停下来。我们决不会选择让 Redis 不好玩的开发模式。
String 类型及操作
String 是最简单的类型,一个 key 对应一个 value。
String 类型是二进制安全的。意思是 redis 的 String 可以包含任何数据, 比如 jpg 图片或者序列化的对象。 从内部实现来看其实 string 可以看作 byte 数组,最大上限是 1G 字节, 下面是 String 类型的定义:
struct sdshdr {
long len;
long free;
char buf[];
};
len 是 buf 数组的长度。
free 是数组中剩余可用字节数, 由此可以理解为什么 string 类型是二进制安全的了, 因为它本质上就是个 byte 数组, 当然可以包含任何数据了。
buf 是个 char 数组用于存贮实际的字符串内容, 其实 char 和 c#中的 byte 是等价的,都是一个字节。
另外 string 类型可以被部分命令按 int 处理.比如 incr 等命令, 如果只用 String 类型, redis 就可以被看作加上持久化特性的 memcached。
常用命令及操作
set
设置 key 对应的值为 string 类型的 value。
例如:我们添加一个 name=Jacob 的键值对,可以这样做:
127.0.0.1:6379> set name Jacob
OK
setnx
设置 key 对应的值为 string 类型的 value。 如果 key 已经存在,返回 0, nx 是 not exist 的意思。
例如:我们添加一个 name=Jacob 的键值对,可以这样做:
127.0.0.1:6379> get name
"Jacob"
127.0.0.1:6379> setnx name Jacob
(integer) 0
由于原来 name 有一个对应的值,所以本次的修改不生效,且返回码是 0。
setex
设置 key 对应的值为 string 类型的 value,并指定此键值对应的有效期。 例如:我们添加一个 haircolor= red 的键值对,并指定它的有效期是 10 秒,可以这样做:
127.0.0.1:6379> setex color 10 red
OK
127.0.0.1:6379> get color
"red"
127.0.0.1:6379> get color
(nil)
可见由于最后一次的调用是 10 秒以后了,所以取不到 haicolor 这个键对应的值。
setrange
设置指定 key 的 value 值的子字符串。 例如我们希望将 HongWan 的 126 邮箱替换为 gmail 邮箱,那么我们可以这样做:
127.0.0.1:6379> setrange name 5 @jacob.com
(integer) 15
127.0.0.1:6379> get name
"Jacob@jacob.com"
其中的 8 是指从下标为 8(包含 8)的字符开始替换
mset
一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值被设置。
127.0.0.1:6379> mset name1 Jacob1 name2 Jacob2
OK
127.0.0.1:6379> get name1
"Jacob1"
127.0.0.1:6379> get name2
"Jacob2"
msetnx
一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值被设置, 但是不会覆盖已经存在的 key。
127.0.0.1:6379> get name1
"Jacob1"
127.0.0.1:6379> get name2
"Jacob2"
127.0.0.1:6379> msetnx name2 Jacob2 name3 Jacob3
(integer) 0
127.0.0.1:6379> get name2
"Jacob2"
127.0.0.1:6379> get name3
(nil)
可以看出如果这条命令返回 0,那么里面操作都会回滚,都不会被执行。(原子性)
get
获取 key 对应的 string 值,如果 key 不存在返回 nil。 例如我们获取一个库中存在的键 name,可以很快得到它对应的 value
127.0.0.1:6379> get name
"Jacob"
127.0.0.1:6379> get name3
(nil)
nil:表示无此键值对。
getset
设置 key 的值,并返回 key 的旧值。 如果 key 不存在,那么将返回 nil。
127.0.0.1:6379> get name
"Jacob@jacob.com"
127.0.0.1:6379> getset name Jacob_new
"Jacob@jacob.com"
127.0.0.1:6379> get name
"Jacob_new"
127.0.0.1:6379> getset name4 Jacob4
(nil)
getrange
获取指定 key 的 value 值的子字符串。
127.0.0.1:6379> get name
"Jacob_new"
127.0.0.1:6379> getrange name 0 1
"Ja"
字符串左面下标是从 0 开始的。
127.0.0.1:6379> getrange name -3 -1
"new"
字符串右面下标是从-1 开始的。
127.0.0.1:6379> getrange name 6 10
"new"
当下标超出字符串长度时,将默认为是同方向的最大下标。
mget
一次获取多个 key 的值,如果对应 key 不存在,则对应返回 nil。
127.0.0.1:6379> mget name name2 name3
1) "Jacob_new"
2) "Jacob2"
3) (nil)
name3 由于没有这个键定义,所以返回 nil。
incr
对 key 的值做加加操作,并返回新的值。注意 incr 一个不是 int 的 value 会返回错误, incr 一个不存在的 key,则设置 key 为 1
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> incr age
(integer) 19
incrby
同 incr 类似,加指定值 , key 不存在时候会设置 key,并认为原来的 value 是 0
127.0.0.1:6379> get age
"19"
127.0.0.1:6379> incrby age 6
(integer) 25
decr
对 key 的值做的是减减操作, decr 一个不存在 key,则设置 key 为-1
127.0.0.1:6379> get age
"25"
127.0.0.1:6379> decr age
(integer) 24
127.0.0.1:6379> get age
"24"
decrby
同 decr,减指定值。
127.0.0.1:6379> get age
"24"
127.0.0.1:6379> decrby age 6
(integer) 18
127.0.0.1:6379> get age
"18"
append
给指定 key 的字符串值追加 value,返回新字符串值的长度。 例如:我们向 name 的值追加一个@126.com 字符串,那么可以这样做:
127.0.0.1:6379> append name @jacob.com
(integer) 19
127.0.0.1:6379> get name
"Jacob_new@jacob.com"
strlen
取指定 key 的 value 值的长度。
127.0.0.1:6379> get name
"Jacob_new@jacob.com"
127.0.0.1:6379> strlen name
(integer) 19
hashes 类型及操作
- actionbar完全解析(一)
- android galley实现画廊效果
- RavenDB:基于Windows/.NET平台的NoSQL数据库
- 神经网络算法交易:波动预测与定制损失函数
- 贝叶斯深度学习:桥接PyMC3和Lasagne构建层次神经网络
- How does it work in Mono's C# compiler?
- Cross-Origin Resource Sharing协议介绍
- 战斗民族开源神器ClickHouse:一款适合于构建量化回测研究系统的高性能列式数据库(二)
- Microsoft StreamInsight 构建物联网
- 利用 Microsoft StreamInsight 控制较大数据流
- HTML Agility Pack 搭配 ScrapySharp,彻底解除Html解析的痛苦
- 看看你是哪种级别的Python程序员(已跪)
- SignalR 在IE中无法工作 - Internet Explorer
- SQL Server 2012 中的 Service Broker功能的一些改进或增强
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- javascript入门到进阶 - js系列七:生命周期
- 时序数据库 InfluxDB(六)
- [058]SQLite on Android
- 【Rust日报】2020-07-15 用Rust重写FORTRAN科学软件
- 一文读懂 DEX 文件格式解析
- Guava集合--新集合类型
- 从 Node.js 到 Go
- 性能不达标,计将安出?
- Yaml 速成查询表
- 设计模式实战-策略模式,想让你的代码变幻莫测吗?
- 设计模式实战-模板模式,代码复用神器
- CSS Flexbox 布局完全指南 (二):3000字,多示例讲解
- 设计模式实战-访问者模式,减少代码体积
- Spring Security 实战干货:UsernamePasswordAuthenticationFilter 源码分析
- 打卡群刷题总结0715——旋转链表