对比着关系型数据库,我们对redis key的设计一般有以下两种格式:

  • 表名:主键名:主键值:列名
  • 表名:主键值:列名 在所有主键名都是id的情况下(其实我个人不喜欢这种情况,比如user表,它的主键名就应该是user_id,而不是id,这样在表与表之间关联的时候一目了然)

用冒号作为分割是设计key的一种不成文的原则,遵循这种格式设计出的key在某些redis客户端下可以有效的识别;

但是,在关系型数据中,除主键外,还有可能根据其他列来查询。

如上表中, username 也是极频繁查询的,往往这种列也是加了索引的。

转换到k-v数据中,则也要相应的生成一条按照该列为主的key-value。

Set user:username:lisi:uid  9  #但是要保证username是唯一的; 这样,我们可以根据username:lisi:uid ,查出userid=9, 再查user:9:password/email ...

mysql与redis的数据转换实例

mysql数据准备

CREATE TABLE `book` (
`book_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '书名',
`add_time` int(10) NOT NULL DEFAULT '0' COMMENT '添加时间',
PRIMARY KEY (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='书本表'; INSERT INTO book VALUES (5, 'PHP圣经', UNIX_TIMESTAMP() ), (6, 'ruby实战', UNIX_TIMESTAMP() ), (7, 'mysql运维', UNIX_TIMESTAMP() ), (8, 'ruby服务端编程', UNIX_TIMESTAMP() ); CREATE TABLE `tag` (
`tag_id` int(11) NOT NULL AUTO_INCREMENT,
`tag_name` char(40) NOT NULL DEFAULT '' COMMENT '标签名',
PRIMARY KEY (`tag_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='标签表'; INSERT INTO tag VALUES (1, 'PHP'), (2, 'ruby'), (3, 'mysql'), (4, 'database'); CREATE TABLE `tag_book` (
`tag_id` int(11) NOT NULL DEFAULT '0' COMMENT '标签ID',
`book_id` int(11) NOT NULL DEFAULT '0' COMMENT '书ID',
KEY `tag_id` (`tag_id`),
KEY `book_id` (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='标签与书关系表'; INSERT INTO `tag_book` (`tag_id`, `book_id`) VALUES ('4', '7'),('1', '5'),('2', '6'),('2', '8');

我们有以下查询需求:

# 《mysql运维》有几个标签:
SELECT tag_name FROM `book` AS b INNER JOIN tag_book AS tb ON b.book_id = tb.book_id INNER JOIN tag AS t ON tb.tag_id = t.tag_id WHERE `name` = 'mysql运维'; # 标签ruby下有几本书:
SELECT b.name FROM `book` AS b INNER JOIN tag_book AS tb ON b.book_id = tb.book_id INNER JOIN tag AS t ON tb.tag_id = t.tag_id WHERE t.`tag_name` = 'ruby';

换到redis中,我们可以如下操作:

一个标签下面可以包含很多书籍,一个书籍也可以包含很多标签。这种从属关系如果没有排序需求的,我们可以使用集合:

  1. 可以准确表达从属关系,一个标签PHP的集合下面有:哪些书籍(存ID就可以了)
  2. 集合不仅可以方便CURD,还可以求并集交集等
set book:book_id:5:name 'PHP圣经'
set book:book_id:6:name 'ruby实战'
set book:book_id:7:name 'mysql运维'
set book:book_id:8:name 'ruby服务端编程' sadd tag:tag_name:php:book_id 5
sadd tag:tag_name:ruby:book_id 6 8
sadd tag:tag_name:database:book_id 7
sadd tag:tag_name:mysql:book_id 7 # ruby下面有哪些书
127.0.0.1:6379> sort tag:tag_name:ruby:book_id get book:book_id:*:name
ruby实战
ruby服务端编程 # 标签同时包含mysql,与database的书 【取交集】
127.0.0.1:6379> sinter tag:tag_name:database:book_id tag:tag_name:mysql:book_id
7
# 在根据book:book_id:7:name获得书籍名称,但如果返回的数据量大,可以先添加一个store参数存到一个临时集合里,然后再用sort分页取回; # 查所有的PHP以及mysql的书;【取并集】
127.0.0.1:6379> sunion tag:tag_name:php:book_id tag:tag_name:mysql:book_id
5
7 set book:book_id:9:name 'javascript权威指南'
set book:book_id:10:name 'HTML+CSS'
sadd tag:tag_name:web:book_id 5 9 10 #查web标签中的非PHP书籍
127.0.0.1:6379> sdiff tag:tag_name:web:book_id tag:tag_name:php:book_id
9
10

总结如下:

  1. 表达从属关系(一对多,多对多),最好用集合; 比如: 书名和标签,关注与被关注(微博粉丝关系)等等。
  2. 求最近的,一般利用链表后入后出的特性。比如:最近N个登录的用户,可以维护一个登录的链表,控制他的长度,使得里面永远保存的是最近的N个登录用户。
  3. 对于排序,积分榜这类需求,可以用有序集合,比如:我们把用户和登录次数统一存储在一个sorted set里,然后就可以求出登录次数最多用户。
  4. 对于大数据量的非是即否关系,还可以通过位图(setbit)的方式,比如:1亿个用户, 每个用户 登陆/做任意操作,记为今天活跃,否则记为不活跃;(每天一个位图来记录,会员id就是位图的位置);

【redis专题(10)】KEY设计原则与技巧的更多相关文章

  1. 17 redis -key设计原则

    书签系统 create table book ( bookid int, title char(20) )engine myisam charset utf8; insert into book va ...

  2. 大型Java进阶专题(三) 软件架构设计原则(下)

    前言 ​ 今天开始我们专题的第二课了,本章节继续分享软件架构设计原则的下篇,将介绍:接口隔离原则.迪米特原则.里氏替换原则和合成复用原则.本章节参考资料书籍<Spring 5核心原理>中的 ...

  3. Java程序员应该了解的10个设计原则

    引用: http://www.cnblogs.com/leehongee/archive/2012/03/18/2404760.html 面向对象设计原则是OOPS(Object-Oriented P ...

  4. 大型Java进阶专题(二) 软件架构设计原则(上)

    前言 ​ 今天开始我们专题的第一课了,也是我开始进阶学习的第一天,我们先从经典设计思想开始,看看大牛市如何写代码的,提升技术审美.提高核心竞争力.本章节参考资料书籍<Spring 5核心原理&g ...

  5. iOS应用开发应遵循的10条设计原则

    转自:http://mobile.51cto.com/design-309719.htm 1.操控便捷 iOS应用的控制设计应该具有圆润的轮廓和程式化的梯度,操作便捷. 2.结构清晰.导航方便 充分利 ...

  6. 最新Dashboard设计实例、技巧和资源集锦,视觉和功能两不误,妥妥的!

    Dashboard设计,尽管设计师们叫法各不相同(例如:“数据面板设计”, “控制面板设计”, “仪表盘设计”或“后台界面设计”等等).但,此类设计的最终目都是力求以最直观.最简洁的方式呈现各种信息和 ...

  7. 9个永恒的UI设计原则

    很多人都在寻找那些能够帮助他们快速提升设计能力的方法,但你是否想过,自己身上的哪些方面会对你的设计产生影响呢?是使用工具的技巧,对设计的理解和态度,还是你的生活习惯呢?我想说所有这些都是决定你的设计是 ...

  8. Java 程序员应在2019年学习的10条面向对象(OOP)设计原则

    面向对象的设计原则 是 OOP 编程的核心,但是我看到大多数 Java 程序员都在追求诸如 Singleton 模式,Decorator 模式或 O​​bserver 模式之类的设计模式,而对学习面向 ...

  9. Java程序员应该了解的10个面向对象设计原则

    面向对象设计原则: 是OOPS(Object-Oriented Programming System,面向对象的程序设计系统)编程的核心,但大多数Java程序员追逐像Singleton.Decorat ...

随机推荐

  1. sql server 索引阐述系列二 索引存储结构

    一.概述. "流光容易把人抛,红了樱桃,绿了芭蕉“ 转眼又年中了,感叹生命的有限,知识的无限.在后续讨论索引之前,先来了解下索引和表数据的内部结构,这一节将介绍页的存储,页分配单元类型,区的 ...

  2. 全能系统监控工具dstat

    一.什么是dstat? 通过man帮助,可以看到官方对dstat的定义为:多功能系统资源统计生成工具( versatile tool for generating system resource st ...

  3. 剑指offer例题分享--8

    前言:继续分享,加油! 面试题44: 代码如下: #include<iostream> #include<stdlib.h> using namespace std; int ...

  4. 对小程序框架WePY的精简总结

    一.注意点 关闭ES6转ES5关闭上传代码时样式自动补全关闭代码压缩上传本地开发选择dist目录,dist目录也用在开发者工具上实时预览和调试WePY框架对应的开发目录为src二.代码规范 - 变量方 ...

  5. [Be a Coding Plasterer] Components 1:get Basic Things

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. Written In The Font I a ...

  6. DWR第一篇之入门示例

    1. 新建maven-web项目,目录结构如下: 2. 在pom.xml里添加dwr所需的依赖 <dependency> <groupId>org.directwebremot ...

  7. NuGet包和功能

    Microsoft.AspNetCore.Razor.Tools:提供TagHelper的智能感知提示和代码加粗高亮显示. Microsoft.AspNetCore.Session:管理会话状态的中间 ...

  8. 教你如何在React及Redux项目中进行服务端渲染

    服务端渲染(SSR: Server Side Rendering)在React项目中有着广泛的应用场景 基于React虚拟DOM的特性,在浏览器端和服务端我们可以实现同构(可以使用同一份代码来实现多端 ...

  9. Perl中的hash类型

    hash类型 hash类型也称为字典.关联数组.映射(map)等等,其实它们都是同一种东西:键值对.每一个Key对应一个Value. hash会将key/value散列后,按序放进hash桶.散列后的 ...

  10. MySQL系列详解七:MySQL双主架构演示-技术流ken

    前言 在企业中,数据库高可用一直是企业的重中之重,中小企业很多都是使用mysql主从方案,一主多从,读写分离等,但是单主存在单点故障,从库切换成主库需要作改动.因此,如果是双主或者多主,就会增加mys ...