需要帮助在 Redis/NoSQL 中进行概念化 [英] Need help conceptualizing in Redis/NoSQL

查看:44
本文介绍了需要帮助在 Redis/NoSQL 中进行概念化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我已经很好地掌握了使用 Redis 的所有命令,但我很难找出使用它的最佳方式.我正在设计一个客户通知系统,当他们的任何电路出现警报时,该系统将通过他们的首选方法(电子邮件、SNMP、系统日志)通知他们.

I think I have a good grasp of all the commands to use Redis, but I'm having difficulty figuring out the best way to use it. I'm designing a customer notification system that will notify them via their preferred method (Email, SNMP, Syslog) when there's an alarm on any of their circuits.

所以,我得到了一个设备名称和一个端口.我需要将其与单个客户相关联,然后将该客户与交付方式相关联.使用关系数据库,它看起来可能是这样的:

So, I get a device name and a port. I need to associate that with a single customer, and then associate that customer to a delivery method. With a relational db, it would look probably look something like this:

Device name: Los_Angeles
Port: 11

SELECT Customer_ID, Customer_name from device_info where device_port = 'Los_Angeles:11'
SELECT Customer_protocol, SNMP_destination, Syslog_destination from CUSTOMER 
    where Customer_ID = <customer_id from above>

(大大简化的例子).

我可以看到如何使用列表散列或散列散列以编程方式执行此操作.但我想我在 Redis 中遇到的问题是那些更复杂的数据结构对我来说不可用(据我所知).那么,如何将多条信息与一个键相关联呢?我可以想到几种方法,但它们似乎都涉及多个步骤,我希望当前 Redis 程序员提供一些关于什么是最佳"方法的意见.

I can see how to do this programatically with a hash of lists or hash of hashes. But I guess what I'm having trouble with in Redis is that those more complex data structures aren't available to me (as far as I know). So, how do I associate multiple pieces of information with a single key? I can think of a few ways I can do it, but they all seem to involve multiple steps, and I'd like some input from current Redis programmers about what the "best" way to do this.

推荐答案

您说得对,Redis 只有简单的数据结构可用,并且它们不能由值组成(就像您可以使用面向文档的数据库,例如 CouchDB)或 MongoDB).但是,可以通过引用来组合数据结构,这是一种非常常见的模式.

You are correct that only simple data structures are available with Redis, and they cannot be composed by value (like you could do with a document oriented database such as CouchDB or MongoDB). However, it is possible to compose data structures by reference, and this is a very common pattern.

例如,集合中包含的项目可以是其他对象(列表、哈希表、其他集合等)的键.让我们尝试将其应用到您的示例中.

For instance, the items contained in a set can be the keys for other objects (lists, hash tables, other sets, etc ...). Let's try to apply this to your example.

要对客户和设备+端口之间的关系建模,您可以使用包含客户 ID 的集合.为了存储有关客户的信息,每个客户一个哈希表就可以了.

To model a relationship between customers and device+port, you can use sets containing customer IDs. To store information about the customers, one hash table per customer is fine.

这里是客户:

hmset c:1 name Smith protocol tcp snmp_dest 127.0.0.1 syslog_dest 127.0.0.2
hmset c:2 name Jackson protocol udp snmp_dest 127.0.0.1 syslog_dest 127.0.0.2
hmset c:3 name Davis protocol tcp snmp_dest 127.0.0.3 syslog_dest 127.0.0.4

这些记录的key是c:ID

The keys of these records are c:ID

让我们将其中两个与设备和端口相关联:

Let's associate two of them to a device and port:

sadd d:Los_Angeles:11 2 3

这个集合的key是d:device:port.c: 和 d: 前缀只是一种约定.应该为每个设备/端口创建一组.一个给定的客户可能属于多个集合(因此与多个设备/端口相关联).

The key of this set is d:device:port. The c: and d: prefixes are just a convention. One set per device/port should be created. A given customer could belong to several sets (and therefore associated to several device/port).

现在要找到附加到此设备/端口的交付方式的客户,我们只需检索集合的内容.

Now to find the customers with delivery methods attached to this device/port, we just have to retrieve the content of the set.

smembers d:Los_Angeles:11
1) "2"
2) "3"

然后可以通过管道化多个hgetall命令来检索相应的客户信息:

then the corresponding customer information can be retrieved by pipelining a number of hgetall commands:

hgetall c:2
hgetall c:3
1) "name"
2) "Jackson"
3) "protocol"
4) "udp"
5) "snmp_dest"
6) "127.0.0.1"
7) "syslog_dest"
8) "127.0.0.2"
1) "name"
2) "Davis"
3) "protocol"
4) "tcp"
5) "snmp_dest"
6) "127.0.0.3"
7) "syslog_dest"
8) "127.0.0.4"

不要害怕命令的数量.它们非常快,并且大多数 Redis 客户端都具有管道查询的能力,因此只需要最少的往返次数.只需使用一个smembers和几个hgetall,只需两次往返即可解决问题.

Don't be afraid of the number of commands. They are very fast, and most Redis clients have the capability to pipeline the queries so that only a minimum number of roundtrips are needed. By just using one smembers and several hgetall, the problem can be solved with just two roundtrips.

现在,由于无处不在的 SORT 命令,可以进一步优化.这可能是Redis中最复杂的命令了,这里可以用它来节省一个往返.

Now, it is possible to optimize a bit further, thanks to the ubiquitous SORT command. This is probably the most complex command in Redis, and it can be used to save a roundtrip here.

sort d:Los_Angeles:11 by nosort get c:*->name get c:*->protocol get c:*->snmp_dest get c:*->syslog_dest
1) "Jackson"
2) "udp"
3) "127.0.0.1"
4) "127.0.0.2"
5) "Davis"
6) "tcp"
7) "127.0.0.3"
8) "127.0.0.4"

在一个命令中,它检索设备/端口集的内容并获取相应的客户信息.

In one command, it retrieves the content of a device/port set and fetches the corresponding customer information.

这个例子很简单,但更一般地说,虽然你可以用 Redis 表示复杂的数据结构,但它不是直接的.您需要在结构和数据访问方面仔细考虑模型(即在设计时,坚持使用您的数据您的用例).

This example was trivial, but more generally, while you can represent complex data structures with Redis, it is not immediate. You need to carefully think about the model both in term of structure and of data access (i.e. at design time, stick to your data AND your use cases).

这篇关于需要帮助在 Redis/NoSQL 中进行概念化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆