【问题标题】:Caching MySQL results with Memcache and sorting/filtering cached results使用 Memcache 缓存 MySQL 结果并对缓存结果进行排序/过滤
【发布时间】:2014-05-09 15:20:54
【问题描述】:

为了帮助大家理解我的要求,我提出了一个场景:

我的网络应用中有用户 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;

现在的挑战是以某种方式将来自我的 users 表的 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();

我的问题是什么是过滤和排序 memcache 数据的好方法,就好像它是一个 SQL 查询一样?还是 memcache 已经内置了一些东西?

【问题讨论】:

    标签: php mysql kendo-ui memcached kendo-grid


    【解决方案1】:

    Memcache 不能做到这一点 - 你不能用 memcache 替换你的数据库(这不是它的用途),你只能存储 key => value 对。

    我认为更好的方法是将每个用户的每个数据存储在特定的内存缓存键中。

    例如,如果用户 A 使用 $user_id = 123 访问该页面:

    $data = $MC->get('customers_for_'.$user_id);
    

    这样您只能获得用户 123 的客户。

    一种更通用的方法是为每个带有参数的 sql 查询生成一个哈希(但在大多数情况下这可能是多余的)。例如,如果您有一个带有变量 $a$b 的查询 select ... from ... where a = @a and b = @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);
    

    要排除(不太可能)不同用户的哈希冲突,您也可以在密钥中混合用户 ID:

    $data = $MC->get("customers_for_".$user_id."_".$sql_crc);
    

    但是:如果您开始在您的应用程序中到处执行此操作,否则它会太慢,那么问题可能在于您的数据库(缺少/错误的索引、错误的列定义、复杂的关系等)和时间应该更好地投资于修复数据库而不是解决这样的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-17
      • 2012-07-29
      • 2015-07-20
      • 2012-06-22
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      相关资源
      最近更新 更多