【问题标题】:Need help conceptualizing in Redis/NoSQL需要帮助在 Redis/NoSQL 中进行概念化
【发布时间】:2012-02-25 04:14:34
【问题描述】:

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

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

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 Hash 吗?例如,hmset / hmget 允许您关联一个键和多个可以代表您的身份的“字段”。 openmymind.net/2012/1/23/The-Little-Redis-Book - Redis Book 有一些很好的例子。
  • 我实际上没有看到 HMSET/HMGET。在我完成教程之后,它必须是一个新的补充。我会玩的。

标签: data-structures nosql redis


【解决方案1】:

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

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

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

这里是客户:

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

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

sadd d:Los_Angeles:11 2 3

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

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

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

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

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,两个往返就可以解决问题。

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

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 表示复杂的数据结构,但它不是直接的。您需要在结构和数据访问方面仔细考虑模型(即在设计时,坚持您的数据您的用例)。

【讨论】:

  • 谢谢!这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-26
相关资源
最近更新 更多