NoSQL数据库(二)02-Redis数据类型——实践-散列类型命令之散列存储逻辑、获取id、修改缩略名

NoSQL数据库(二)02-Redis数据类型——实践-散列类型命令之散列存储逻辑、获取id、修改缩略名

实践

刚才存储文章的例子,需要序列化和反序列化之后在进行读写。会造成2个问题:

  1. 会产生竞态, 2个客户端同时操作会冲突,最终只有一个属性被修改。没有原子化操作
  2. 每次修改或者读取都需要反序列化,消耗性能。

新增一个需求,一般文章都会有缩略名。比如文章的标题叫做"This is a great post",它的缩略名可以为"this-is-a-greate-post"。缩略名可以用于生成文章的地址栏或者其它用处。

使用散列改造

在这里插入图片描述

// 散列其实就是hash  hget hset
var redis = require('redis');
var client = new redis({
//一些配置
});

// # 1. 文章的赋值
// # 自增的id 
var $post_id = client.incr('posts:count');
var $slug = 'hello-world';
var $title = 'hello world';
var $content = 'xxxxxxxxxxxxx';
var views = 0;
// # 文章的缩略名和id互相有一个引用来维持关系  slug.to.id
// # HSETNX 也是赋值  如果这个值已经存在 则返回0,并且赋值失败  反之返回1, 赋值成功
var isSlug = client.hsetnx(`slug.to.id ${$slug} ${$post_id}`);

// # 1.通过散列去存储文章
if(isSlug === 0) {
    client.exit();
} else {
    client.hmset(`post:${$post_id} title ${$title} content ${$content} views ${$views}`)
}

// # 2. 读取文章
var postID = client.hget('slug.to.id $slug'); 
if (!postID) {
    client.exit('文章不存在')
} else {
    var post = client.hgetall(`post:${postID}`, (err, data) => {
        console.log(data)
    })
}

// # 3.修改缩略名
// # 加入你要给id=42的文章  修改缩略名
var newSlug = 'xxx';
var isSlugExit = client.hsetnx(`slug.to.id ${newSlug} 42`) 

if(isSlugExit === 0) {
    exit('缩略名已存在,请换其它')
} else {
    var oldSlug = client = client.hget(`post:42 slug`);
    client.hset(`post:42 slug ${newSlug}`);
    client.hdel(`slug.to.id ${$oldSlug}`);
}



命令补充
  1. 只获取字段名或字段值

HKEYS key

HVALS key

  1. 获得字段数量

HLEN key

实例

hash_demo.js

var data = {
    a: 1,
    b: 2
}

// a做了一个操作   data.a = 10;
// b 也做了一个操作 data.b = 20;

// "{a: 1, b: 2}"

// a  "{a: 10, b: 2}"
// b  "{a: 1, b: 20}"

var redis = require('redis');
var client = new redis({
    // option
});

var $post_id =  client.incr('post:count');

var $slug = 'hello-world';
var $title = 'hello world';
var content = 'xxxxxxxxxxxxxx';
var $views = 0;

// 存储逻辑
// 生成文章之前,校验缩略名是否可用    hsetnx, 属性存在则修改失败,反之成功
// 用关系性数据库 会额外建一张表来存储  文章的ID  和 缩略名直接的映射关系 。 散列 类型 叫做 slug.to.ld 专门存储 文章的ID  和 缩略名
var isSlug = client.hsetnx(`slug.to.id ${$slug} $post_id`);  // 缩略名和id就能一一对应

if (isSlug === 0) {
    client.exit('缩略名已存在');
} else {  // 散列存储逻辑
    client.hmset(`post:${$post_id} title ${$title} content ${$content} views ${$views}`);
}

// 读取
// 1. 获取id

var postID = client.hget(`slig.to.id ${$slug}`);

if (!postID) {
    client.exit('文章不存在')
} else {
    var post = client.hgetall(`post:${$post_id}`, (err, data) => { //node会封装
        console.log(data);
    });
}

// 修改缩略名

var newSlug = 'xxxxx';
var isSlugExit = client.hsetnx(`slug.to.id ${newSlug} 42`);

if(!isSlugExit) {
    client.exit('缩略名已经存在');
} else {
    var olgSlug = client.hget(`post:42 slug`);  // 先获取旧的
    client.hset(`post:42 slug ${newSlug}`);  // 赋值新的
    
    client.hdel(`slug.to.id ${olgSlug}`);
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值