关于数据结构:需要帮助在Redis / NoSQL中进行概念化

Need help conceptualizing in Redis/NoSQL

我认为我对使用Redis的所有命令都有很好的了解,但是我很难确定使用它的最佳方法。我正在设计一个客户通知系统,当他们的任何电路出现警报时,都会通过他们的首选方法(电子邮件,SNMP,Syslog)通知他们。

因此,我得到了一个设备名称和一个端口。我需要将其与一个客户相关联,然后将该客户与一种交付方式相关联。使用关系数据库时,它看起来可能像这样:

1
2
3
4
5
6
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程序员提供一些有关"最佳"方法的信息。


您是正确的,Redis仅提供简单的数据结构,并且它们不能由值组成(就像您可以使用面向文档的数据库(例如CouchDB或MongoDB)那样。但是,可以通过引用来构成数据结构,这是一种非常常见的模式。

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

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

以下是客户:

1
2
3
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

这些记录的键是c:ID

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

1
sadd d:Los_Angeles:11 2 3

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

现在要查找具有与此设备/端口相连的交付方式的客户,我们只需要检索设备的内容。

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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客户端都具有对查询进行管线化的功能,因此仅需要最少的往返次数。通过仅使用一个成员和几个hgetall,只需两次往返即可解决此问题。

现在,由于普遍存在的SORT命令,可以进一步优化。这可能是Redis中最复杂的命令,可用于在此处保存往返。

1
2
3
4
5
6
7
8
9
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"

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

这个例子很简单,但是更普遍的是,尽管您可以使用Redis表示复杂的数据结构,但这并不是立即的。您需要在结构和数据访问方面仔细考虑模型(即在设计时,坚持数据和用例)。