Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 对实时数据表使用Memcached_Php_Mysql_Caching_Memcached - Fatal编程技术网

Php 对实时数据表使用Memcached

Php 对实时数据表使用Memcached,php,mysql,caching,memcached,Php,Mysql,Caching,Memcached,我的应用程序中有很多数据表(即,数据表可以随时更新,但大多数时候它们显示相同的数据) 其中一些表后面有相当密集的查询,因此每次用户返回页面时,即使没有新的更新,也会再次运行查询 当时我认为Memcached是提高用户性能的理想选择,但我不确定如何实现这一点,因为我对缓存的概念非常陌生 我如何让MySQL告诉Memcached某个查询的结果已经更改,下一次加载时表不应该来自缓存,而是来自数据库,从而更新缓存 此外,我认为最好只使用新行更新表的数据对象,但我不知道这将是什么过程,因此如果任何人对我的

我的应用程序中有很多数据表(即,数据表可以随时更新,但大多数时候它们显示相同的数据)

其中一些表后面有相当密集的查询,因此每次用户返回页面时,即使没有新的更新,也会再次运行查询

当时我认为Memcached是提高用户性能的理想选择,但我不确定如何实现这一点,因为我对缓存的概念非常陌生

我如何让MySQL告诉Memcached某个查询的结果已经更改,下一次加载时表不应该来自缓存,而是来自数据库,从而更新缓存


此外,我认为最好只使用新行更新表的数据对象,但我不知道这将是什么过程,因此如果任何人对我的用例有一些想法,他们将非常感激。

这只是一个想法:我认为您可以从MySQL获取数据并将其保存到文件中。然后您可以直接使用这个文件而不是数据库。要更新您的文件,您可以使用许多项目中使用的comet方法,例如facebook使用comet进行通知。

可能这是一个选项,可以在有更新时记录。因此,您可以创建一个额外的表,称为update。它应该有两列,优先级和日期时间

每次刷新页面时,您都会通过mysql检查特定优先级的日期时间是否已更改。如果是这样,您知道需要更新该页面上的数据。如果没有,您可以使用当前数据


要使其正常工作,您当然必须在每次数据库更改时更新更新表。这可以手动完成,也可以通过mysql触发器完成。

这里有一个通用的答案,可以帮助您完成您想要做的事情:

假设您有
mainpage.php
,其中包含您担心的密集查询。这是假设您已经有一个Memcached对象singleton:

$m = new Memcached();
$m->addServer('localhost', 11211);
mainpage.php
的某个地方,您可以根据
$user\u id
检查缓存结果集:

$data = null;

if($cachedResultSet = $m->get('resultSet'.$user_id)) 
{
    $data = $cachedResultSet;
} 
else 
{
    $data = run_intensive_query($user_id);

    $m->set('resultSet'.$user_id, $data);
} 

// Then you use $data as long as it's not null
然后,每当作为上述结果集一部分的MySQL表被更新时,您都希望使相关用户的特定缓存记录无效:

$m->delete('resultSet'.$user_id);
这将确保下次加载
mainpage.php
时,“过时”结果集将不再存在于缓存中,因此它将检索新结果并适当缓存它们。

对于您的问题:

$m->delete('resultSet'.$user_id);
如何让MySQL告诉Memcached某个查询的结果 已更改,并且下次删除时不应从缓存中获取表 是加载的,而不是来自数据库,因此更新 缓存

您需要在数据更新时清除缓存(或等到数据过期)

Memcache是一个密钥存储。。。因此,您需要一个表示要检索的数据的唯一键

例如,假设您有与博客帖子相关的查询。唯一的ID将是您的帖子ID或其页面url/slug

因此,您通常要做的是在数据库中执行查询之前,检查缓存中是否有存储的版本

$memcache = new Memcache();
$memcache->connect('localhost', 11211) or die ("Could not connect");

$postId = 1234; // this would vary between each posts.
$commentsKey = 'comments_'. $postId;


$result = $memcache->get($commentsKey);

if ($result === false) { // key not found

   // only fetch when result are NOT in cache
   $pdo = new PDO();
   $stmt = $pdo->query("SELECT * FROM comments WHERE postId=". $pdo->quote($postId));
   $result = $pdo->fetchAll();

   // store it for next time
   $memcache->set($commentsKey, $result);

} //if

// use result either from cache or database
foreach ($result as $comment) {
    // do something with data
} 
此外,要重置缓存(或使其无效),您可以在有人发布新注释时清除注释键

$memcache = new Memcache();
$memcache->connect('localhost', 11211) or die ("Could not connect");

$postId = 1234; // this would vary between each posts.
$commentsKey = 'comments_'. $postId;

$memcache->delete($commentsKey); 

// OR

$memcache->set($commentsKey, false); 

这样,下次用户检索评论时,它将不得不从数据库而不是缓存中提取评论,因为$result将为false。

这是个好主意,但可能会变得复杂,因为我有许多用户在使用我的系统。因此,我只想在“属于”用户的行发生更改时发出更新。您可以使用用户ID而不是类别。所以每个用户都有自己的更新时间。不久前,我在NodeJS中尝试了同样的方法。MySQL查询缓存已经可以缓存查询的结果集了。但是,只要更新表,缓存的结果集就会失效。所以,我想使用Memcached缓存特定的结果集仍然有一个很好的用例。您是否使用了一个可能有用于Memcached的API的框架?如果您使用的是Laravel框架,那么这个问题将很容易解决。不过,为了一般地回答您的问题,您需要使用每个用户的唯一密钥(可能是与user_id连接的某个值)缓存特定的结果集。如果存在特定用户的缓存记录,则将从缓存加载。否则,您将运行查询并缓存结果集。然后,对于负责更新主查询中使用的任何表的任何页面,您将使用基于用户id的唯一键使缓存记录无效。