我的应用程序中有许多数据表(即可随时更新的数据表,但大多数时候它们显示相同的数据)。
其中一些表背后有相当密集的查询,因此每次用户返回页面时,即使没有新的更新,它也会再次运行查询。
当我认为Memcached是理想的加速我的用户的性能但我不确定如何实现这一点,因为我对缓存的想法很新。
如何让MySQL告诉Memcached某个查询的结果已经改变,并且下次加载时表不应来自缓存,而是来自数据库并因此更新缓存?
另外,我认为最好只使用新行来更新表的数据对象,但我不知道这个过程会是什么,所以如果有人有一些想法,他们可以分享我的用例非常感谢。
答案 0 :(得分:1)
也许这是一个选项,可以在有更新时进行记录。所以你可以制作一个额外的表,称为更新。它应该有两列,优先级和日期时间。
每次刷新页面时,都会通过mysql检查是否具有特定优先级,日期时间已更改。如果是这样,您知道您需要更新该页面上的数据。如果没有,你可以使用当前数据。
为了实现这一点,您当然必须更新更新表,每次更改数据库。这可以手动完成或通过mysql触发器完成。
答案 1 :(得分:0)
这只是一个想法:我认为你可以从MySQL获取数据并将其保存到文件中。然后你可以直接使用这个文件而不是数据库。要更新文件,您可以使用在许多项目中使用的彗星方法,例如Facebook使用彗星进行通知。
答案 2 :(得分:0)
这是一个通用的答案,可以帮助您完成您尝试做的事情:
我们假设您有mainpage.php
,其中包含您担心的密集查询。假设您已经有一个Memcached对象单例:
$m = new Memcached();
$m->addServer('localhost', 11211);
mainpage.php
中的某处,您将根据$user_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
时,"陈旧" resultSet将不再存在于缓存中,因此它将检索新结果并适当地缓存它们。
答案 3 :(得分:0)
对于你的问题:
如何让MySQL告诉Memcached某个查询的结果 已经改变了,下一次表不应该来自缓存 加载,而是来自数据库,然后更新 缓存?
您需要在数据更新时清除缓存(或等到它过期)。
Memcache是一个密钥存储...因此您需要一个唯一的密钥来表示您要检索的数据。
例如,假设您有与博客帖子相关的查询。唯一的ID将是您的帖子ID或它的页面url / slug。
所以你通常做的是在数据库中进行查询之前检查Cache中是否存在存储的版本。
$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。