Redis存储Key的一种设计实现方式:模式匹配

一、前言

Redis是Key-Value数据库,存储的时候需要一个唯一的Key值,查询的时候根据根据key值进行查询,但是Redis毕竟只是key-value存储,所以有很多局限性。例如:

(1)无法实现多条件组合的查询,如:

硬要实现的话需要多条命令并计算并集或交集。

(2)模糊查询中文比较费劲;

因此,如何设计一个合适的Key来优化我们的查询操作,是一个比较有意义的事情。

对于Key的设计网上有很多资料,但对我来说,都太过于凌乱,并没有找到一个合适的方案。下边,和大家一起学习一种较为简单的模式匹配方式的Key值设计方法。

下边的学习,主要介绍项目中使用的方式,有兴趣的同学可以clone代码一起学习,仓库地址:

https://git.oschina.net/xuliugen/redis-demo.git

二、项目结构

SSM框架(Spring+Spring MVC+MyBatis),除了实现了对Redis的存储,还通过注解的方式实现了数据库的读写分离功能,实现了Spring对数据库和Redis的事务管理,JSR303校验,以及简单的领域驱动DDD思想项目。

(1)项目结构:

(2)数据库脚本:

(3)Spring配置文件位置:

其中,db-redis.xml文件中,如下代码表示开启Redis事务:

(4)Redis和MyBatis代码位置:

三、Key值设计

上述,大致看了依托的项目结构,还没有开始Redis Key值得设计,因此可以跳过,下边主要学习一下,如何设计一种Key实现模式匹配查询方式。

(1)情景假设

有实体对象SecurityUserDTO,如下:

这里假设用户对象最常用的查询条件是:用户名(userName)和单位类型(unitType),因此,对于数据库设计的时候,我们应该对这两个属性加上索引(题外话,完全和Key的设计无关!只是在于点一下这种最常见的数据库加索引的方式)。

数据库做了索引,那我,我们将数据存储到Redis中的时候,如何在把他取出来那?

(2)首先,看一下最终存放在Redis中的数据格式:

其中:

SU1_县级单位_wangwu_0000000035

可以分为四个部分:

1、简化的实体对象名称,就是SecurityUserDTO的简写,为了缩短Key的长度;
2、unitType的值,第一个查询条件;
3、userName的值,第二个查询条件;
4、ID的值,十位数值,前边不足十位补0;

(3)如何拼接,核心代码如下:

assembleRedisKeyPrefix()方法:

assemberIdForKey()方法:

到这里,基本已经知道了大致拼接的过程,因此存放到Redis的数据是如下格式:

注:可以SecurityUserController#addUser(SecurityUserDTO userDTO)方法测试效果。

(4)如何查询:

查询的话可以参考SecurityUserController#listByCondition()方法:

查询的时候,也是需要根据查询条件构造Key值,然后读取数据。

如果,查询条件都有的话,构造的Key值如下:

如果,查询条件只有一个的话,构造的Key值如下:

(5)修改数据和删除数据:

因为ID在拼接的时候肯定是唯一的,因此,删除的直接拼接为如下形式即可:

*39

四、总结

拼接Key的方式很简单,以常用的查询条件属性作为拼接Key的依据,当然还可以通过其他的方式,但最主要的是如何去实践。上述,很简略的介绍了一下,因为对于这个项目来说,很多的细节,以博客的形式写出来确实受限,还请大家移步代码仓库地址:

https://git.oschina.net/xuliugen/redis-demo.git

有什么疑问和可以改进的地方,希望多多留言,相互学习。

原文发布于微信公众号 - Java后端技术(JavaITWork)

原文发表时间:2017-06-19

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏草根专栏

用ASP.NET Core 2.1 建立规范的 REST API -- HATEOAS

本文所需的一些预备知识可以看这里: http://www.cnblogs.com/cgzl/p/9010978.html 和 http://www.cnblog...

1444
来自专栏QQ音乐技术团队的专栏

打通Android Gradle编译过程的任督二脉

本文主要是基于自己在工作当中的一些Android Gradle实践经验,对gradle相关知识做的一个简单总结和分享,希望对大家有帮助。 首先会讲Gradle大...

1.4K9
来自专栏一个会写诗的程序员的博客

CAS指令与MESI缓存一致性协议、 “轻量级锁” 与原子操作CAS指令与MESI缓存一致性协议、 “轻量级锁” 与原子操作

CAS指令,在Intel CPU上称为CMPXCHG。最常见的原子操作有Compare and Exchange,Self Increase/Decrease等...

1595
来自专栏程序员的知识天地

使用 JS 实现一个本地数据库

前端很多时候还是需要保存一些数据的,这里的保存指的是长久的保存。以前的思想是把数据保存在 Cookie 中,或者将 key 保存在 Cookie 中,将其他数据...

3052
来自专栏Kevin-ZhangCG

[ Java面试题 ]持久层篇

2666
来自专栏安恒网络空间安全讲武堂

堆利用之double-free

2434
来自专栏腾讯Bugly的专栏

《Android 创建线程源码与OOM分析》

| 导语 企鹅FM近几个版本的外网Crash出现很多OutOfMemory(以下简称OOM)问题,Crash的堆栈都在Thread::start方法上。该文详细...

9305
来自专栏友弟技术工作室

MongoDB简易教程mongo简介及应用场景安装和使用mongodbPHP中操作mongo数据库python中操作mongo数据库

传统数据库中,我们要操作数据库数据都要书写大量的sql语句,而且在进行无规则数据的存储时,传统关系型数据库建表时对不同字段的处理也显得有些乏力,mongo应运而...

4156
来自专栏JavaEdge

线程安全与锁优化1 线程安全2 锁优化

3439
来自专栏lgp20151222

Vue生命周期-手动挂载理解

浏览器缓存,试了下确实一定概率可以显示,但是,哪怕浏览器不行,我们也只能从自己的代码里修改来配合它,兼容它。

1011

扫码关注云+社区