为了帮助大家理解我在问什么,我提出了一个场景:
我的网络应用程序上有用户 A。
有一个特定的页面有一个表,其中包含该用户独有的信息。假设它是一个仅向用户 A 显示的客户列表,因为用户 A 和这些客户位于区域 5。
其他用户被分配到不同的区域并看到不同的客户列表。
我想做的是缓存每个用户列表的所有结果。这不是问题,因为我可以使用:
$MC = new Memcache;
$MC->addserver('localhost');
$data = $MC->get('customers');
if($data)
{
} else {
$data = $this->model->customersGrid($take, $skip, $page, $pageSize, $sortColumn, $sortDirection, $filterSQL, $PDOFilterParams);
$MC->set('customers', $data);
}
header('Content-Type: application/json');
return $data;
现在的挑战是以某种方式将来 self 的用户表的 SQL 过滤器语法转换成一个可以过滤和排序数组的函数($data 是一个 JSON 字符串,如果这是正确的方法,我会把它转换成一个数组)去)。
仅供引用,这是我在语句中构建 WHERE 子句时使用的别名数组:
$KF = new KendoFilter;
$KF->columnAliases = array(
'theName' => 'name',
'dimensions' => 'COALESCE((SELECT CONCAT_WS(" x ", height, width, CONCAT(length, unit)) FROM products_dimensions,
system_prefs, units_measurement
WHERE products_dimensions.productId = product.id
AND units_measurement.id = system_prefs.defaultMeasurementId), "-")',
'gridSearch' => array('theName', 'basePrice')
);
$filterSQL = $KF->buildFilter();
我的问题是什么是像 SQL 查询一样过滤和排序内存缓存数据的好方法?还是 memcache 已经内置了一些东西?
最佳答案
Memcache 无法做到这一点——您不能用 Memcache 替换您的数据库(这不是它的用途),您只能存储键 => 值对。
我认为更好的方法是将每个用户的每个数据存储在特定的内存缓存键中。
例如,如果 $user_id = 123
的用户 A 访问该页面:
$data = $MC->get('customers_for_'.$user_id);
这样您只能获得用户 123 的客户。
一种更通用的方法是为每个带有参数的 sql 查询生成一个散列(但在大多数情况下这可能有点矫枉过正)。例如,如果您有一个查询 select ... from ... where a = @a and b = @b
with variables $a
and $b
您可以执行以下操作(当然,您必须为剑道调整它,但要理解这个想法):
$query = "select ... from ... where a = @a and b = @b";
# crc32 because it is fast and the mem key does not get too long
$sql_crc = crc32($query.$a.$b);
$data = $MC->get("customers_".$sql_crc);
要排除(不太可能)不同用户的哈希冲突,您也可以在 key 中混合用户 ID:
$data = $MC->get("customers_for_".$user_id."_".$sql_crc);
但是:如果您开始在您的应用程序的各个地方执行此操作,否则它会太慢,那么问题可能出在您的数据库(缺少/错误的索引、错误的列定义、复杂的关系等)和时间应该更好地投资于修复数据库而不是像这样解决问题。
关于php - 使用 Memcache 缓存 MySQL 结果并排序/过滤缓存结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23568303/