zoukankan      html  css  js  c++  java
  • Redis基础知识之————空间换时间的查询案例

    空间与时间

    空间换时间是在数据库中经常出现的术语,简单说就是把查询需要的条件进行索引的存储,然后查询时为O(1)的时间复杂度来快速获取数据,从而达到了使用空间存储来换快速的时间响应!对于redis这个k/v存储系统来说,复杂的查询不是它所建议的,它的优势在于通过key快速定位数据,它定位数据的速度与数据多少没有直接关系,无论是1万还是1亿数据,它定位的时间复杂度都是O(1),而在实际使用中,可能不简单使用key定位数据就够了,可能还需要数据里的某个属性去定位数据,这种情况第一感觉不能用redis,或者说,不能用k/v存储系统了,但这不是我们应该说的,我们要的是解决方案,换个角度去思考,我们是否可以把那个属性拿出来当新的key,把原来的key当作它的value呢,答案是肯定的,这就是用空间到换时间,只需要两个查询就可以搞定了!

    上面是一个100万的hash集合,key是用户id,value是一个用户实体,我们通过RedisClient.RedisManager.Instance.GetDatabase().HashGet("VoteList", id)很方便的可以拿到对应的用户实体!

    我希望通过用户名拿到用户实体?

    这种需求,我们不要直接解决,如果直接解决,那唯一的办法就是遍历所有数据,然后一一对比,时间复杂度就是O(N),太可怕了!

    通过添加新的k/v,解决这个问题,这类似于关系数据库里的全表扫描+索引技术!

    实现程序:先通过userName找到UserId,再通过UserId找到用户实体!

    public void FindBigData()
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                var name = RedisClient.RedisManager.Instance.GetDatabase().HashGet("VoteList_UserName", "zzl15");//找到用户ID
                if (name.HasValue)
                {
                    var val = RedisClient.RedisManager.Instance.GetDatabase().HashGet("VoteList", name);//找到用户实体
                    Console.WriteLine("name={0},value={1}", name, val);
                }
                else
                {
                    Console.WriteLine("没有发现这个Key");
                }
                sw.Stop();
                Console.WriteLine("查询需要的时间:" + sw.ElapsedMilliseconds + "ms");
            }
  • 相关阅读:
    LeetCode 382. Linked List Random Node
    LeetCode 398. Random Pick Index
    LeetCode 1002. Find Common Characters
    LeetCode 498. Diagonal Traverse
    LeetCode 825. Friends Of Appropriate Ages
    LeetCode 824. Goat Latin
    LeetCode 896. Monotonic Array
    LeetCode 987. Vertical Order Traversal of a Binary Tree
    LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays
    LeetCode 636. Exclusive Time of Functions
  • 原文地址:https://www.cnblogs.com/tinywan/p/6083620.html
Copyright © 2011-2022 走看看