缓存数据库查询的最佳方法是什么

本文关键字:方法 是什么 最佳 数据库 查询 缓存 | 更新日期: 2023-09-27 18:21:03

我正在编写一个管理智能应用程序,它需要大量复杂的数据库查询,有些查询非常昂贵。为了提高性能,我大量使用Memcached来尽可能多地存储在内存中。

这导致了我的代码中有很多重复,我渴望摆脱这些重复,并构建一个更干净的数据访问解决方案。我的很多数据访问功能最终都是这样的。。

public int NumberOfTimeouts(DateTime date, int? applicationId)
{
    var functionCacheKey = "NumberOfTimeouts";
    var cacheKey = string.Format("{0}-{1}-{2}-{3}", RepositoryCacheKey, functionCacheKey, date, applicationId);
    var cachedNumberTimeouts = _cache.Retrieve(cacheKey);
    if (cachedNumberTimeouts != null)
    {
        return (int)cachedNumberTimeouts;
    }
    //query logic here, calculates numberOfTimeouts
    UpdateCache(date, cacheKey, numberOfTimeouts);
    return numberOfTimeouts;
}

我只是不太确定这方面的标准方法是什么,它会涉及使用自定义属性类或类似的东西吗?

缓存数据库查询的最佳方法是什么

这是一个跨领域的问题。CCD_ 1模式可以在这里适用。我可能对此模式缺乏经验,但我会尝试

// model
public class CustomObject
{
    public int Id { get; set; }
}
// interface
public interface IRepository<T>
{
    IEnumerable<T> Find(Expression<Func<T, bool>> expression);
}
public interface ICacheableRepository<T>
{
    IEnumerable<T> Find(Expression<Func<T, bool>> expression, Func<int> cacheKey);
}
public interface IRepositoryCacheManager<T>
{
    IEnumerable<T> Get(int key);
    bool Any(int key);
    void Add(int key, IEnumerable<T> result);
}
// cache manager
public class RepositoryCacheManager<T> : IRepositoryCacheManager<T>
{
    private Dictionary<int, IEnumerable<T>> cache = new Dictionary<int,IEnumerable<T>>();
    #region IRepositoryCache<T> Members
    public IEnumerable<T> Get(int key)
    {
        return cache[key];
    }
    public bool Any(int key)
    {
        IEnumerable<T> result = null;
        return cache.TryGetValue(key, out result);
    }
    public void Add(int key, IEnumerable<T> result)
    {
        cache.Add(key, result);
    }
    #endregion
}
// cache repository decorator
public class CachedRepositoryDecorator<T> : IRepository<T>, ICacheableRepository<T>
{
    public CachedRepositoryDecorator(IRepositoryCacheManager<T> cache
        , IRepository<T> member)
    {
        this.member = member;
        this.cache = cache;
    }
    private IRepository<T> member;
    private IRepositoryCacheManager<T> cache;
    #region IRepository<T> Members
    // this is not caching
    public IEnumerable<T> Find(Expression<Func<T, bool>> expression)
    {
        return member.Find(expression);
    }
    #endregion
    #region ICacheableRepository<T> Members
    public IEnumerable<T> Find(Expression<Func<T, bool>> expression, Func<int> cacheKey)
    {
        if (cache.Any(cacheKey()))
        {
            return cache.Get(cacheKey());
        }
        else
        {
            IEnumerable<T> result = member.Find(expression);
            cache.Add(cacheKey(), result);
            return result;
        }
    }
    #endregion
}
// object repository
public class CustomObjectRepository : IRepository<CustomObject>
{
    #region IRepository<CustomObject> Members
    public IEnumerable<CustomObject> Find(Expression<Func<CustomObject, bool>> expression)
    {
        List<CustomObject> cust = new List<CustomObject>();
        // retrieve data here
        return cust;
    }
    #endregion
}
// example
public class Consumer
{
    // this cache manager should be persistent, maybe can be used in static, etc
    IRepositoryCacheManager<CustomObject> cache = new RepositoryCacheManager<CustomObject>();
    public Consumer()
    {
        int id = 25;
        ICacheableRepository<CustomObject> customObjectRepository =
            new CachedRepositoryDecorator<CustomObject>(
                cache
                , new CustomObjectRepository()
                );
        customObjectRepository.Find(k => k.Id == id, () => { return id; });
    }
}

请注意:

  • 我还没有测试过这个代码,不知道它是否功能齐全。我只是描述一下插图
  • 是的,这有代码气味,因为FindICacheableRepository重载,但是我不能在Dictionary中使用Expression作为Key

优点:

  • 此CachedRepositoryDecorator可用于任何通用存储库(可重复使用)
  • 选择过程中没有缓存逻辑,强调SRP

缺点:

  • 没有ORM很难实现,也许你需要对反射进行一些调整,使其在没有ORM的情况下工作
  • 刚开始很难理解
  • 没有DI容器时难以接线

本文来源:)

我认为工作单元模式正是您所需要的。更多信息:

  • http://martinfowler.com/eaaCatalog/unitOfWork.html
  • http://www.codeproject.com/Articles/581487/Unit-of-Work-Design-Pattern
  • http://msdn.microsoft.com/en-us/magazine/dd882510.aspx

或者包含UoW模式的框架:https://github.com/riteshrao/ncommon