【发布时间】:2013-01-29 20:07:35
【问题描述】:
我在文件(serialize/unserialise vs json_encode/decode、var_export、igbonary)和 mysql 查询(优化、stored procedures、query cache)中进行了很多关于缓存数据的搜索,但此刻,我想知道优化如下具体案例的更好方法是什么。
提前抱歉:我猜这是一个很长的话题,但有必要了解这个项目。请原谅我糟糕的英语,这不是我的第一语言。
让我们假设我们有这个数据库关系。
数据库描述(括号中的估计记录数):
- MODULE (10) : 是Item的类型,可以是文章、论坛主题、广告、新闻...
- ITEM(百万):带有标题和一些文字的任何类型
- CATEGORY (50) :物品类别(动物、政治、汽车、计算机...)
- TAG(数十万):类别的标签(例如政治:国际、法国、巴拉克奥巴马......)
- ITEM_TAG(outch):项目和标签关联
所以我们有几个关系,每个都是 ITEM 创建/更新时的记录器。
我已经通过以下示例将 ITEM 数据缓存在文件夹和文件中:
public function cacheItem()
{
$req=mysql_query("SELECT id, title, content, id_mod, id_cat
FROM ITEM
WHERE ITEM.id='".$this->id."'")or die(mysql_error());
if(mysql_num_rows($req)==1)
{
$this->itemData=mysql_fetch_array($req);
$this->folder=floor($this->id/1000);//1000 items max per folder
$this->itemUrl=$this->folder."/".$this->id.".txt";
if(!file_exists($this->itemUrl))
{
touch($this->itemUrl);
}
file_put_contents($this->itemUrl,serialize($this->itemData),LOCK_EX);
}
}
我通过unserialize(file_get_contents($url)) 得到它们,这部分就像一个魅力!
现在我希望优化 ITEM 列表以通过多个选项显示它们(例如),foreach 显示每个分页限制为 100:
- 所有项目
- 模块的项目
- 类别的项目
- 类别和模块的项目
- 标签的项目
- TAG 和 CATEGORY 的项目
- TAG 和 CATEGORY 和 MODULE 的项目
我已经知道如何在 SQL 中执行此操作并将结果放入缓存树中。
对于这些缓存文件,我的问题是,当创建/更新新项目时,可能必须非常严格地刷新列表。
第一个问题:
如果同时创建/更新 ITEM(这些列表也是如此)会发生什么?
file_put_contents(); 的LOCK_EX 是否会在从file_get_contents(); 获取文件时完成他的工作?
第二个问题
我知道更多的 PHP 会起作用,更少的 mySQL 会起作用(否则),但是用分页来做这些列表更好(显示更快)的方法是什么,它将每秒或更长时间显示一次,并且只修改通过添加/更新新项目?
- 我的缓存系统(我不这么认为...)
- mySQL 中的存储过程
- 多个数据库服务器和/或多个文件服务器
- 其他
非常感谢任何想法、示例、链接。
附: : 只是为了好玩,我可能会问“Facebook 怎么样”和“stackoverflow 怎么样”?
【问题讨论】:
-
没有什么可以帮助您的,但非常感谢您提供有关基于行 ID
floor($this->id/1000);的文件夹文件限制的提示。好主意! -
RDBMS 在优化其结构方面付出了很多努力,因此您自己的缓存将很难战胜它。为每个项目打开一个文件将花费您。我会说使用MySQL。如果(且仅当)性能不够,请考虑使用多个负载平衡服务器和/或其他(可能是商业的)数据库服务器。不过,暂时不要看到这种情况发生。也没有看到任何对存储过程的调用。使用pagination,您可以尝试变得聪明,但在此有单独的问题。
-
好的,让我们先看看mySQL...在PHP中mysqli查询会更好吗(我现在不使用它)?
-
使用 mysqli,不推荐使用 mysql_query。其次,使用memcached或Redis进行缓存。
-
好的,谢谢。 Mysqli 还是 PDO ?我从来没有用过它们。