缓存复杂数据类型 [英] Cache complex datatype

查看:75
本文介绍了缓存复杂数据类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个应用程序,我打算加载请求的数据并缓存项目,以便后续请求同一项目。



如果项目不是在缓存中,我打算进行数据库调用并将所需的项目缓存到一个集合中供以后使用。



这是产品实体:

ProductID

ProductName

ProductType

ProductPrice






我正在使用ODP.NET和C#来加载记录。



目前我可以通过调用加载所有产品:

I am working on an application where i intend to load requested data and cache the items for subsequent requests to the same item.

If the item isn't in the cache i intend to make a database call and cache the desired items into a collection for later use.

This is the Product entity:
ProductID
ProductName
ProductType
ProductPrice



I am using ODP.NET and C# to load the records.

Currently i can load all the products by invoking:

dbProvider.GetAllProducts();





但是这对于过滤产品显然不是一个好主意,所以我创建了一种方法来以一种或多种方式加载产品:通过ProductID列表,ProductName列表和/或ProductTypes列表。



这是因为最终用户将提供一个List,可以是

Li产品ID和/或ProductNames列表和/或ProductTypes列表。



我想使用产品ID列表和/或产品名称列表过滤缓存/或产品类型列表。



我尝试过:



当我使用存储库模式时,我扩展了我的ProductsRepository以加载过滤后的产品:





But this is obviously not a good idea for filtering the products so i have created a method to load the products in one or more ways: By List of ProductID, List of ProductName and/or List of ProductTypes.

This is because the end user will be providing a List which can be either be
List of ProductIDs And/Or List of ProductNames And/Or List of ProductTypes.

I want to filter the cache using the List of ProductsIDs and/Or List of ProductNames and/or List of ProductTypes.

What I have tried:

As i am using the repository pattern i extended my ProductsRepository to load the filtered products:

IEnumerable<productdao> loadedProducts = dbProvider.GetFilteredProducts(List<int>ProductIDs, 
                               List<string>ProductNames, 
                               List<string>ProductTypes);







i已经开始编写代码进行缓存,但我遇到了实现我想要实现的问题。






i have started to write the code to cache but i am having issues with implementing what i want to achieve.

//Get the default MemoryCache to cache objects in memory
  ObjectCache cache = MemoryCache.Default;
 
  CacheItemPolicy policy = new CacheItemPolicy();
  policy.AbsoluteExpiration = DateTimeOffset.Now.AddMinute(120.0);
 
   //check if data exists in cache
   //Get data from the database and cache them
   IEnumerable<product> loadedProducts  dbProvider.GetFilteredProducts(List<int>ProductIDs, 
                               List<string>ProductNames, 
                               List<string>ProductTypes);
           ...
   //loop through them all and add to cache so user can access them in 3 ways
   //cache.Add("Product" + id, result, policy);





一旦我缓存了我希望在我的ProductBusinessLogic类中使用它的项目,就可以使用用户提供的参数列表。这可能吗?



我如何根据用户提供的例如ProductIds列表或ProductTypes列表或ProductNames列表来检查缓存。



我如何正确地将已加载的产品从数据库存储到缓存中,知道用户可以根据3种特定方式请求访问数据?



Once i have cached the items I want to use it in my ProductBusinessLogic class to filter the cache using the List of parameters the user has provided. Is this possible?

How would i check the cache based on what the user has provided e.gList of ProductIds or List of ProductTypes or List of ProductNames.

How would i store the loaded Products from the database into the cache correctly, knowing that the user can request to access the data based on 3 particular ways?

推荐答案

您可以采取两种方法。一个是您只是缓存所有产品,每次有人调用GetFilteredProducts时,您都会从缓存中获取所有产品的列表,然后执行Where on it。这样你只需要担心缓存所有产品,但缺点是每次有人提出请求时都会进行过滤。如果产品不多,这可能是更好的方法,因为它很简单,产品的检索可能比过滤需要更多的CPU时间。



第二种方法是缓存查询结果,以便当另一个具有相同参数的查询进入时,您只需从缓存中获取它。为此,您需要生成一个聪明的密钥以用作缓存密钥。所以,假设有人搜索产品ID 100,107,102,106 ......从该订单生成密钥ID;



100,102,106,107



然后把它变成一个像
的字符串


100_102_106_107



这是你的缓存密钥。因此,当有人搜索产品ID 100,101时,其缓存密钥为100_101。当其他人搜索107,106,100,102时,其缓存密钥为100_102_106_107,与第一次搜索匹配,因此从缓存中获取结果。您需要为所有参数扩展此概念,因此对于名称,键将类似于ProductA_ProductB等。如果你可以搜索ID和名称,那么键将是100_101_ProductA_ProductB等。



如果你正在搜索很多东西,那么关键会变得非常大,所以一旦你有你的字符串,使用GetHashCode()获取它的哈希值.ToString()(我认为这就是它所谓的)并使用哈希作为缓存键。



这种方法的好处在于,如果在获得即时结果之前已完成搜索,则表现最佳。缺点是如果查询是多种多样的。如果人们总是在寻找不同的东西,那么你最终会得到大量的缓存数据,并且很少有成功的点击缓存。使用这种技术,你最好使用滑动过期,因此不需要的查询会丢弃缓存。



您也可以结合使用这两种技术。总是缓存产品,这样如果你没有点击参数缓存,你必须生成一个新的查询,你在产品的缓存版本上运行该查询。



因此,根据您的数据大小以及您认为人们将要执行的查询类型,您可以自行决定最佳策略。
There are two approaches you could take. One is that you simply cache all products and every time someone calls GetFilteredProducts you get the list of all products from the cache then do the Where on it. That way you only need to worry about caching all the products, but the downsides are that the filtering happens every time someone does a request. If there aren't many products this is probably the better way to go as it is simple and chances are the retrieval of the products takes more CPU time than the filtering.

The second approach is to cache the results of their query so that when another query with the same params come in you simply get it from the cache. To do this you need to generate a clever key to use as the cache key. So let’s say someone searches for product IDs 100, 107, 102, 106…to generate a key from that order the IDs;

100, 102, 106, 107

Then turn that into a string like

"100_102_106_107"

And that is your cache key. So when someone searches for product IDs 100, 101 the cache key for that is "100_101". When someone else searches for 107, 106, 100, 102 then the cache key for that is "100_102_106_107" which matches the first search so the results are got from the cache. You’ll need to extend this concept for all of your params so for names the key would be something like "ProductA_ProductB" and so on. If you can search for IDs and names then the key will be "100_101_ProductA_ProductB" etc.

If you are searching on a lot of things the key will get very large, so once you have your string, get the hash value of it using GetHashCode().ToString() (I think that’s what it’s called) and use the hash as the cache key instead.

The good thing about this approach is that it is the best performing, if a search has been done before you get instant results. The downsides are if the queries are varied and many. If people are always searching for different things then you’ll end up with a lot of cached data and very few successful hits on the cache. Using this technique you’re best to use a sliding expiration so un-wanted queries drop out the cache.

You can also combine both techniques. Always cache the products so if you get no hit on the parameter caching and you have to generate a new query you run that query on the cached version of the products.

So it’s up to you to decide what strategy is best given your data size and the types of queries you think people are going to do.


这篇关于缓存复杂数据类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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