Redis专题(二)——Redis数据类型(1)

Redis专题(二)——Redis数据类型(1)

(原创内容,转载请注明来源,谢谢)

一、概述

Redis是一种Key-Value类型的数据库,属于非关系型数据库,NoSQL的一种。Redis共有5种数据类型:字符串(string)、散列(hash)、列表(list)、集合(set)、有序集合(zset)。

1、通配符

Redis支持部分通配符,包括?、*、[]、\x,和正则表达式一致,?表示匹配0或1个,*匹配任意个,[]匹配框内的任意一个内容,\x转义,例如\?表示匹配?。

2、获取键 KEYS

当要获取键值时,可以用KEYS* 获取所有的键,也可以用KEYS a*获取所有a开头的键。该方法会遍历所有的键,影响性能,不建议使用。

3、判断键是否存在 EXISTS

如 EXISTS test,判断test键是否存在,存在返回整数1,不存在返回0。

4、删除键 DEL

DELtest,如果test存在,则删除,返回1;如果不存在,则返回0。

该命令不支持通配符,因此要删除多个键时,可以在linux命令行下,通过管道符的方式获取与删除,例如redis-cli KEYS “user*” | xargs redis-cli DEL。其中xargs是将管道符前面的命令的执行结果作为参数传给xargs后面的命令。也可以使用redis-cli DEL “user*”的方式删除。

5、获取键的数据类型 TYPE

TYPEtest 可以获取test键的数据类型,返回值即上述五种数据类型中的一种。

6、原子性

redis的所有命令都是原子性的,例如自增命令incr,当并发调用incr对某个key的value设置自增,只会增加一次。其他命令也是如此。

7、存储方式

redis存储元素都是用hash的方式存储,将每个键用hash进行计算后,存储在hash(key)的位置,每个位置即为一个bucket。当hash(key1)和hash(key2)相同时,会采用链表的方式,将key1和key2都存储在同一个bucket的结果中,bucket根路径指向key1,key1再指向key2。

二、字符串类型(String)

字符串是redis的最基本数据类型,其他的数据类型可以看作是各种方式把字符串集合在一起的类型。字符串的一个键允许存储512MB的值,因此可以存放绝大多数的内容。

1、使用方式

赋值:SET keyvalue,给key赋值为value。获取:GET key。当get不存在的键,会返回(nil)。

用PHP连接redis,并接收命令行的参数,使用set和get操作redis,如下:

<?php  
$redis = new Redis();
$redis->pconnect('127.0.0.1', 6379);
$name = $argv[1];
$redis->set('test:1:name', $name);
echo $redis->get('test:1:name');
echo PHP_EOL;

2、递增数字

INCRkey,当key对于的value是数字时自增1,否则会报error。当key没有设定value时,默认是0,所以执行INCR会变成1。

redis中的操作都是都是原子操作,因此当有多个客户端并发对某个键使用INCR时,最后的结果也仅加1次,不会出现多次加的情况。

3、实现文章访问量统计

给每篇文章设置一个名字,名字为article:id:page.view,表示文章的id中某个页面的访问量。

1)id可以选用文章在数据库(如mysql)中的id。如果文章不用数据库存储,而用redis,则也可以自制自增的id。自增id的设置方法为,新建一个字段为articles:count,初始值为1,每有一篇文章要计算时,就把这个值INCR,返回的结果就是文章的id。

2)当要用redis存储文章标题、内容等信息时,需要将文章的各类内容存储在数组中,通过PHP序列化后进行存储,取出则同样是反序列化后使用。

4、字符串相关其他命令

1)增加指定整数:INCRBY、自减一:DECR、减少指定整数:DECRBY、增加浮点数:INCRBYFLOAT。

2)尾部追加内容:APPEND、获取串长度:STRLEN。

3)同时获取/设置多个值:MGETkey1 key2…. ,MSET key1 value1 key2 value2…

4)位操作:SETBIT ival、GETBIT,获取或者操作变量的第i位,由于是二进制操作,因此值只有0或1。此方法用于获取或设置数量较小的内容时,效率极高,如性别、状态等,只有几个数字的可能的情况,用此方法比较好。

三、散列类型(Hash)

散列存储了字段和字段值的映射,即每个key对应的值仍是field =>value的形式,每个key可以对应多个field =>value形式的内容,最多支持232-1。但是字段值只能是string,不能是其他类型,即不支持嵌套。

redis的每种类型都只支持字符串,不支持类型的嵌套。

1、设置与获取

1)单次单个:HGETkey field、HSET key field value

2)单次多个:HMGETkey field1 field2… 、HMSET key field1 value1 field2 value2…

3)获取某个key的全部:HGETALL,返回的是field1、value1、field2、value2…,不是很直观,但是很多语言都已经将结果封装。

在PHP中,$redis->hgetall(key)会返回key对应的field=>value的一个二维数组。

但是,当字段数量非常多时,由于redis是单线程的,hgetall要遍历某个key所有的field和value,因此会发生阻塞,甚至可能是服务器宕机。

因此,可以将key和field另外进行存储。

2、判断

1)field是否存在:HEXISTSkey field

2)field不存在时赋值:HSETNXkey field value,由于具有原子性,当多个hsetnx命令同时发出时,只会执行第一个命令,后面的命令由于已经有值了所以不会再次设置。

3)增加数字:HINCRBYkey field increment

4)删除field:HDEL keyfield1 field2…

3、存储文章数据

当使用序列化将文章的标题、内容等存储,反序列化取出时,存在的问题由于反序列化以及修改的操作不是在redis执行,不是原子性,因此并发情况下有可能发生问题。另外,反序列化则如果只修改标题也需要取出全部内容,浪费资源。

使用散列可以很好解决此问题,存储的方法是关键字设置为article:id,然后里面的field分别是title、content等,要修改也可以用HSET进行修改。

4、其他命令

1)部分获取:只获取field——HKEYS key,只获取value——HVALS key,获取field的数量:HLEN key

——written by linhxx 2017.08.04

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-08-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏农夫安全

【weakfilescan】敏感文件扫描工具

weakfilescan 基于爬虫,动态收集扫描目标相关信息后进行二次整理形成字典规则,利用动态规则的多线程敏感信息泄露检测工具,支持多种个性化定制选项,包括...

3678
来自专栏Java工程师日常干货

【随笔】JVM核心:JVM运行和类加载

本篇博客将写一点关于JVM的东西,涉及JVM运行时数据区、类加载的过程、类加载器、ClassLoader、双亲委派机制、自定义类加载器等,这些都是博主自己的一点...

613
来自专栏Spark学习技巧

JAVA之ClassLoader

JAVA基础系列之ClassLoader 一,Java类的加载、链接与初始化 1,加载:查找并加载类的二进制数据 • 通过一个类的全限定名来获取定义此类的二进制...

2049
来自专栏数据小魔方

NoSQL学习笔记之——Redis基础

之前练习过一篇NoSQL之Mongodb基础的笔记,这一篇开始练习NoSQL系列的又一重要利器——Redis。 Redis是一个开源的,基于内存并可持久化的日志...

2566
来自专栏我是攻城师

Nodejs笔记(三)

3329
来自专栏LuckQI

redis初识~String命令介绍

1093
来自专栏爱撒谎的男孩

Spring依赖注入

4117
来自专栏java 成神之路

Java 序列化 之 Serializable

34913
来自专栏康怀帅的专栏

PHP 变量与常量

本文介绍了 PHP 变量与常量。 官方文档:http://php.net/manual/zh/language.variables.php 官方文档:http:...

2594
来自专栏用户2442861的专栏

为什么很多类甚者底层源码要implements Serializable ?

在碰到异常类RuntimeException时,发现Throwable实现了 Serializable,还有我们平进的javabean一般也要实现Seriali...

331

扫码关注云+社区