数据库已经成为不可或缺的一部分 。NET 应用程序,因为您可以有效地获取和操作大量数据。 但是,在处理高事务数据时,数据库会导致 .NET 应用程序的性能下降。 这是因为数据库无法扩展到多台机器上——您只能拥有一台服务器机器专用于数据库层并且不能添加更多。 数据库因此成为性能瓶颈。 为了解决这个问题,我们使用了分布式缓存的方案,比如 NCache 以减少不必要的和昂贵的数据库访问。
如何缓存数据库?
缓存数据库比听起来要简单得多。 您需要将缓存层与缓存相结合,例如 NCache 在您的应用程序和数据库层之间,以便从缓存中提供数据库数据。 为方便起见,我们总结了四种最常见的缓存使用模式。 他们简要介绍如下:
1.对象缓存
该策略建议,如果缓存中不存在你的数据,则从数据库中取出数据,然后将其插入缓存中,例如 NCache. 之后从缓存中处理连续的调用。 对于有关过时数据的问题,您可以添加 呼气 到 缓存项 以便可以从数据库中刷新它。
以下代码从缓存中获取 Customer 的实例(如果存在)。 否则,它从数据库中获取它并将其添加到缓存中,以便在连续调用中缓存命中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
var key = "Customer:1001"; // Get Customer from cache if it exists var customer = cache.Get<Customer>(key); // If customer does not exist in cache if (customer == null) { // Fetch from database customer = GetCustomerFromDB(1001); // Create sliding expiration of 15 seconds. Cache removes item after this time var expiration = new Expiration (ExpirationType.Sliding, TimeSpan.FromSeconds(15.0)); var cacheItem = new CacheItem(customer) { Expiration = expiration }; // Insert the item with expiration into cache cache.Insert(cacheKey, cacheItem); } |
NCache 更多信息 数据缓存文档 NCache 程序员指南
2.缓存参考数据并使用SQL查询来搜索它
仅读取且不经常更改的数据称为参考数据。 .NET 应用程序重复读取数据而很少将数据写入数据库是很常见的。 缓存(如 NCache) 在用于参考数据时更强大,因为它对此类数据的工作速度最快。
强烈建议缓存整个参考数据,然后使用 用于搜索缓存的 SQL 查询 为它而不是去数据库。 请注意,如果您不缓存整个参考数据集(例如所有客户),那么您针对缓存的 SQL 查询将返回无效结果,因为某些数据仅在数据库中。
如果你已经 预加载缓存 使用所有参考数据,以下示例说明了如何搜索它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// Pre-Requisite: All customer instances have already been added into cache var customerName = "John Smith"; // Write SQL query for cache var query = "SELECT $Value$ FROM Northwind.Model.Customer WHERE Name = ?"; // Create the query command that cache understands from the query var queryCommand = new QueryCommand(query); // Provide the parameters for the query queryCommand.Parameters.Add("Name", customerName); // Execute the query on cache var reader = cache.SearchService.ExecuteReader(queryCommand, true); var customer; // If a valid projection was made in the query if (reader.FieldCount > 0) { while (reader.Read()) { customer = reader.GetValue<Customer>(1); // Perform operation according to business logic } } |
3. 处理缓存中的一对多关系
大多数情况下,我们的数据包含其中的关系。 例如,在 Northwind 数据库(由 Microsoft 使用)的上下文中,“Orders”表与“Customers”表相关。 这些实体被认为是 .NET 应用程序域中的相关实体。 使用缓存,例如 NCache,您也可以在缓存中关联这些实体。
这是通过 将所有相关实体与标签标识符相关联 因此,您可以通过标签标识符搜索缓存,在一次调用中获取客户的所有订单,而不是单独获取客户的每个订单。 给定的示例代码说明了我们如何实现这种行为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
var cacheKey = "Customer:1001"; var tagName = "Customer:1001_Orders"; // Check if customer exists in cache var cachedCustomer = cache.Get<Customer>(cacheKey); // If customer does not exist in cache if (cachedCustomer == null) { // Fetch from database var customer = GetCustomerFromDb(1001); // Insert customer into cache cache.Insert(cacheKey, customer); // Fetch orders of the customer from database var relatedOrders = GetRelatedOrdersFromDb(customer); // Create a tag for all orders of the customer var tag = new Tag(tagName); foreach (Order order in relatedOrders) { var orderCacheKey = $"Customer:1001_Order:{order.OrderID}"; // Create a cache item and set the tag identifier var orderCacheItem = new CacheItem(order) { Tags = new[] { tag } }; // Insert the tagged cache item into cache cache.Insert(orderCacheKey, orderCacheItem); } } else { // Item exists in the cache // Create a tag to fetch the related orders var tagIdentifier = new Tag(relatedEntityIdentifier); // Fetch the related orders based on the tag identifier var cachedOrders = cache.SearchService.GetByTag<Order>(tagIdentifier); } |
4.缓存数据库查询结果(事务数据)
大多数时候,数据库中的数据以查询结果集的形式返回。 此策略建议您将整个结果集插入缓存,以便从缓存中提供连续查询。 具有相同条件的查询将始终引用相同的结果集。 因此,我们可以将查询命令本身视为结果集的唯一标识符,并将其用作缓存中的键。
以下代码显示了如何将查询结果集缓存为集合:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// Query to select East Coast Customers var query = "SELECT * FROM Northwind.Model.Customer WHERE Region = ‘EastCoast’"; // Create cache key based on the query var key = query; // Fetch the entities based on query var resultSet = cache.Get<IList<Customer>>(key); // If data against query not found in cache if (resultSet == null) { // Fetch the result set from database var customers = GetCustomersFromDb(query); // Convert the result set into a collection var cacheReadyCustomers = customers.ToList(); // Add result set to cache against query cache.Insert(cacheKey, cacheReadyCustomers); } |
结论
如您所见,在 .NET 应用程序中使用类似缓存的缓存来缓存数据库 NCache 很容易。 根据应用程序中的使用模式,您可以缓存数据并通过查询获取数据,就像对数据库进行操作一样。
此外, NCache 是一种内存分布式缓存解决方案。 使用数据库时遇到的所有问题都在其中处理,并且它具有具有标准要求的缓存的所有实现等等。