当前位置: 首页 > 面试题库 >

搜索Redis数据库的值

栾昂雄
2023-03-14
问题内容

我是使用Redis
DB的新手。在阅读了一些文档并浏览了Internet上的一些示例并扫描了stackoverflow.com之后,我可以看到Redis速度非常快,可扩展性很好,但这要付出代价,我们必须考虑一下数据的处理方式在设计时访问它们,以及它们将要执行的操作。我能理解这一点,但对于使用普通的旧SQL这么简单却又缓慢地在数据中搜索感到有些困惑。我可以用KEY命令以一种方式完成此操作,但这是O(N)操作,而不是O(log(N))。因此,我将失去Redis的优势之一。

在这里,更有经验的同事怎么说?

让我们以一个用例为例:我们需要存储大约大约200位个人数据。100.000人,这些数据需要通过姓名(电话:nr)进行搜索。

为此,我将使用以下结构:

1. SET for storing all persons' ids {id1, id2, ...} 
2. HASH for each person to store personal data and name it 
like map:<id> e.g. map:id1{name:<name>, phone:<number>, etc...}

解决方案1:

1. HASH for storing all persons' ids but the key should be the phone number
2. Then with the command KEY 123* all ids could be retrieved who have a phone number 
sarting with 123. On basis of the ids also the other personal data could be retrieved.
3. So forth for each data to be searched for a separate HASH should be created.

但是此解决方案的 主要缺点 是属性 值也必须是唯一的 ,因此HASH中电话号码和ID的分配是明确的。另一方面, O(N)
运行时并不理想。

此外 ,这将使用比必要更多的空间,并且 KEY命令会降低访问性能。
(http://redis.io/commands/keys)

应该如何以正确的方式完成?我也可以想象ids会放在ZSET中,而需要搜索的数据可能就是分数,但这只能使范围与Serache无关。

提前也谢谢你,塔马斯

答案总结: 实际上,两个响应都表明Redis并非旨在搜索键的值。如果有必要使用此用例,则 需要实施解决方法
,如我的原始解决方案或以下解决方案所示。

与我最初的 解决方案相比,Eli 的以下 解决方案具有更好的性能 ,因为对键的访问可以视为恒定的,只需要遍历id的列表,这种访问将给
O(const) 运行时。此数据模型还允许一个人可能具有与其他人相同的电话号码,等等,例如姓名等。因此, 也可以建立1-n关系
(我会说旧的ERD术语)。

该解决方案的缺点在于, 它比我的我的 电话号码 占用更多的空间 ,而仅 搜索 起始数字的 电话号码
无法搜索

感谢您的两个回复。


问题答案:

Redis适用于需要以很高的频率访问和更新数据并且可以从数据结构(哈希,集,列表,字符串或排序集)的使用中受益的用例。它可以满足非常具体的用例。如果您有一个非常灵活的搜索之类的通用用例,那么为此目的而构建的某种东西(例如elasticsearch或SOLR)会更好地为您服务。

就是说,如果您必须在Redis中执行此操作,这就是我的操作方式(假设用户可以共享姓名和电话号码):

name:some_name -> set([id1, id2, etc...])
name:some_other_name -> set([id3, id4, etc...])

phone:some_phone -> set([id1, id3, etc...])
phone:some_other_phone -> set([id2, id4, etc...])

id1 -> {'name' : 'bob', 'phone' : '123-456-7891', etc...}
id2 -> {'name' : 'alice', 'phone' : '987-456-7891', etc...}

在这种情况下,我们将为每个名称(以“ name:”为前缀)和每个电话号码(以“
phone:”为前缀)创建一个新密钥。每个键都指向一组ID,这些ID具有用户想要的所有信息。例如,在搜索电话时,您将执行以下操作:

HGETALL 'phone:123-456-7891'

然后遍历结果,并以您选择的语言返回每个信息(在本示例中为名称)的任何信息(您可以在Redis框上的服务器端Lua中完成整个操作,以更快地进行操作并避免网络往返第四,如果您愿意):

for id in results:
    HGET id 'name'

您需要付出的代价是,拥有给定电话号码的用户数量在O(m)哪里m,由于对速度的优化,这将是对Redis的非常快速的操作。在您的情况下,这可能会适得其反,因为您可能不需要这么快的时间,并且您希望进行灵活的搜索,但这就是您要这样做的方式。



 类似资料:
  • 问题内容: 我在输入时搜索用户。但是最后它返回了每个用户。我不知道为什么会这样。好像还好 问题答案: 您正在使用。从文档中: 由返回的实例 将响应节点上具有大于startValue或等于startValue且键大于或等于childKey的值的事件。 因此请记住,如果您搜索某个用户的,则会为所有名称按字母顺序大于给定名称的用户提供。您需要设置a 以限制查询范围。 Firebase旧版文档是了解Fir

  • 查看其他关于堆栈溢出的问题,有人说这可能是因为valueEventListener的位置不正确,但...不是吗?我正在钻进食物条目/营养条目,但我不知道如何钻进更深。没办法匿名给孩子打电话?我尝试调用childEventListener而不是valueEventListener,其他的都一样,但我再也没有得到那个消息,但我仍然无法检索到我想要的数据。 编辑: 谢谢你到目前为止的帮助。根据下面Has

  • 问题内容: 是否可以仅对hibernate-search的注释(bean => document / document => bean mapping)使用hibernate-search,而不使用数据库?如果是这样,是否有任何在线样本基本上显示了如何进行设置? 我发现了以下内容:http : //mojodna.net/2006/10/02/searchable-annotation-drive

  • Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 目录结构CentOS /etc/redis.conf: 配置文件,用来配置 Redis 端口、数据存储、以及优化参数 /etc/redis-sentinel.conf: 哨兵配置文件,用来

  • 通过在搜索栏输入搜索条件,您可以在匹配当前索引模式的索引中进行搜索。您可以进行简单的文本查询,或使用 Lucene 语法,或使用基于 JSON 的 Elasticsearch 查询 DSL 。 提交一次搜索请求后,直方图、文档列表、字段列表会按新的搜索结果来展示。工具栏上会展示命中的文档数量。文档列表会展示前5条命中的文档。默认情况下,文档列表会按时间倒序进行排列,最新的文档显示在最上面。您可以点

  • 问题内容: 我目前正在尝试完成一个项目,其中的规范是使用搜索表单来搜索包装数据库。该数据库具有许多变量,包括大小,名称,类型和肉类。我需要创建一个搜索表单,用户可以在其中使用多种不同的搜索进行搜索(例如搜索50厘米长的盖子托盘)。 我花了整整一天的时间来尝试创建一些PHP代码,这些代码可以在我创建的测试数据库中搜索信息。我遇到了许多错误,从mysql_fetch_array错误,布尔错误到现在,我