Eagle32 Ответов: 1

Кэширование сложного типа данных


Я работаю над приложением, в котором намереваюсь загрузить запрошенные данные и кэшировать элементы для последующих запросов к тому же элементу.

Если элемента нет в кэше, я намерен сделать вызов базы данных и кэшировать нужные элементы в коллекцию для последующего использования.

Это Продукт сущность:
ProductID
значение ProductName
Тип продукта
Параметр



Я использую ODP.NET и C# для загрузки записей.

В настоящее время я могу загрузить все продукты, вызвав:
dbProvider.GetAllProducts();


Но это, очевидно, не очень хорошая идея для фильтрации продуктов, поэтому я создал метод для загрузки продуктов одним или несколькими способами: по списку ProductID, списку ProductName и/или Списку ProductTypes.

Это происходит потому, что конечный пользователь будет предоставлять список, который может быть либо
Список ProductIDs и/или список ProductNames и / или список ProductTypes.

Я хочу отфильтровать кэш, используя список ProductsIDs и/или список ProductNames и / или список ProductTypes.

Что я уже пробовал:

Поскольку я использую шаблон репозитория я расширил свой ProductsRepository для загрузки отфильтрованных продуктов:

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



я начал писать код для кэширования, но у меня возникли проблемы с реализацией того, чего я хочу достичь.

//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 для фильтрации кэша с использованием списка параметров, предоставленных Пользователем. Возможно ли это?

Как бы я проверил кэш на основе того, что предоставил пользователь, например, gList of ProductIds или List of ProductTypes или List of ProductNames.

Как бы я правильно хранил загруженные продукты из базы данных в кэш, зная, что пользователь может запросить доступ к данным на основе 3 конкретных способов?

1 Ответов

Рейтинг:
0

F-ES Sitecore

Есть два подхода, которые вы могли бы принять. Один из них заключается в том, что вы просто кэшируете все продукты, и каждый раз, когда кто-то звонит GetFilteredProducts, вы получаете Список всех продуктов из кэша, а затем делаете на нем Where. Таким образом, вам нужно только беспокоиться о кэшировании всех продуктов, но недостатками является то, что фильтрация происходит каждый раз, когда кто-то делает запрос. Если продуктов не так много, то это, вероятно, лучший способ, так как он прост и, скорее всего, поиск продуктов занимает больше процессорного времени, чем фильтрация.

Второй подход состоит в том, чтобы кэшировать результаты их запроса так, чтобы при поступлении другого запроса с теми же параметрами вы просто получали его из кэша. Для этого вам нужно сгенерировать умный ключ, который будет использоваться в качестве ключа кэша. Итак, допустим, кто-то ищет идентификаторы продуктов 100, 107, 102, 106...to сгенерируйте ключ из этого порядка идентификаторов;

100, 102, 106, 107

Затем превратите это в строку типа

“100_102_106_107”

И это ваш ключ кэша. Поэтому, когда кто-то ищет идентификаторы продуктов 100, 101, ключ кэша для этого - “100_101”. Когда кто-то другой ищет 107, 106, 100, 102, то ключ кэша для этого - “100_102_106_107”, который соответствует первому поиску, поэтому результаты получаются из кэша. Вам нужно будет расширить эту концепцию для всех ваших параметров, чтобы для имен ключом было что-то вроде “ProductA_ProductB” и так далее. Если вы можете искать идентификаторы и имена, то ключ будет "100_101_ProductA_ProductB" и т. д.

Если вы ищете много вещей, ключ будет очень большим, поэтому, как только у вас будет ваша строка, получите ее хэш-значение с помощью GetHashCode().ToString () (я думаю, что это так называется) и использовать хэш в качестве ключа кэша вместо этого.

Хорошая вещь в этом подходе заключается в том, что он является наиболее эффективным, если поиск был сделан до того, как вы получили мгновенные результаты. Минусы заключаются в том, что запросы разнообразны и многочисленны. Если люди всегда ищут разные вещи, то вы получите много кэшированных данных и очень мало успешных попаданий в кэш. Используя эту технику, вам лучше всего использовать скользящий срок действия, чтобы ненужные запросы выпадали из кэша.

Вы также можете комбинировать обе техники. Всегда кэшируйте продукты, поэтому, если вы не попадаете в кэширование параметров и вам нужно сгенерировать новый запрос, вы запускаете этот запрос на кэшированной версии продуктов.

Поэтому вам решать, какая стратегия лучше всего подходит, учитывая размер ваших данных и типы запросов, которые, по вашему мнению, будут делать люди.


Eagle32

Спасибо за ответ. Да, я понимаю, что вы имеете в виду, конечные пользователи могут предоставлять различные комбинации, поэтому мне нужно будет глубже изучить ваши предложения и т. д.