你能在Memcache中存储PHP数组吗?

20

你能在Memcache中存储一个数组吗?

我想要存储:

  1. 用户ID号码
  2. 用户的照片URL
  3. 用户的名字

作为一个数组一起存储,有人告诉我可以,但也有人告诉我不行,究竟是哪个呢?

4个回答

25
是的。
Memcache::set('someKey', array(
    'user_id' => 1,
    'url' => 'http://',
    'name' => 'Dave'
));

请查看文档以获取非常详细的示例。

非常感谢。在我的情况下,用户ID、网址和名称都将是一个包含最多5,000个用户的数组内部的数组,这样做是否不好? - JasonDavis
4
你有必要将5K条记录存储在memcache中吗?我认为你可能没有理解缓存的作用。 - doomspork
这要看情况。以我的简单示例为例,那个数组大约需要500字节。将其乘以5,000,你就得到了2.5 MB。这是一个相当大的对象,放入memcached中可能会有些困难。 - hobodave
目前每次加载页面时,我都必须查询mysql以仅获取用户好友列表中的发布博客,这是一个大查询,需要几个连接,因为它必须返回博客主题和发布者图片url和用户名。因此,目标是缓存friendlist部分,并定期更新它。我不想缓存匹配的博客id结果,因为随着新项目的添加,这些结果每隔几分钟就会更改。我没有太多选择。 - JasonDavis
当用户从我的网站注销时,是否有可能清除他们的缓存? - JasonDavis
显示剩余2条评论

9

在Memcache中,一项的最大存储大小为1,048,576字节(1MB),将数组序列化会占用一定的空间。

如果您将数组结构简单化,例如:

array(
    [0] => 1,
    [1] => 2,
    [2] => 3
)

键自动生成,值为用户ID。

使用此结构对5000个编号为1-5000的用户进行序列化数组,字符串长度为67792个字符,50000个用户产生777794个字符的数组。

对100000到150000进行编号,产生一个序列化字符串,长度为838917个字符。

因此,在50k个用户(如您先前提到的)时,您很可能不会超过1MB的限制。但是,如果您有本地缓存(例如APC等),请使用它,或者如果出于任何原因您不需要一次获取所有ID,则强烈建议拆分结果或仅使用数据库。

还要考虑您在memcached中存储的数据结构。如果您只是使用缓存来提供要查找的主键列表,那么是否需要其他数据?


我想要实现的是类似于朋友动态的功能,我需要所有用户ID的原因是因为我只能在动态中显示来自用户好友的操作。我正在研究最佳方法来实现这一点,但似乎每次页面加载都要进行多个连接以获取这些数据,所以我希望使用memcache来加速并减轻mysql的负担。目前我只是在研究一个好的方法,所以我对所有建议都持开放态度。 - JasonDavis
如果我能够存储用户的好友列表、照片URL和用户名,那么就可以消除从用户表中获取图片和名称的2个连接,然后再连接到好友表。不好的是,一个有5k好友的用户,即使我在内存中有他们的好友列表,我仍然需要使用IN(1,2,3,4)来查找他们的好友动态以显示,但我认为这比使用mysql查找所有东西要快,而且这个feed经常出现在用户主页上,我不认为我可以缓存好友feed,因为它会不断更新。 - JasonDavis
用户的好友列表经常更新,但我认为当他们添加新用户时,我可以重新缓存它。我不应该让5k位好友成为最大限制,我将限制账户仅添加那么多,并且许多账户不会拥有全部朋友数量,一些用户可能只有几百个。 - JasonDavis
你是否已经有一个正在使用的MySQL查询示例?我最近遇到了类似的问题(用户活动流),并发现我能够大大优化MySQL查询本身。 - Jason
你对当前映射的数据库结构有更多细节吗?你使用什么基础表进行查找?基础表的查询示例是什么样子的? - Jason

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

$id = $_REQUEST['name'];
$key = md5("SELECT * FROM memc where FirstName='{$id}'");
$get_result = array();
$get_result = $memcache->get($key);

if ($get_result) {
    echo "<pre>\n";
    echo "FirstName: " . $get_result['FirstName'] . "\n";
    echo "Age: " . $get_result['Age'] . "\n";
    echo "</pre>\n";
} else {
    $query="SELECT * FROM memc where FirstName='{$id}'";
    $result = mysql_query($query);
    $row = mysql_fetch_array($result);
    echo "<pre>\n";
    echo "FirstName: " . $row[1] . "\n";
    echo "Age: " . $row[3] . "\n";
    echo "Retrieved from the Database\n";
    echo "</pre>\n";
    $memcache->set($key, $row, MEMCACHE_COMPRESSED, 60);
    mysql_free_result($result);
}

根据您的需求添加或更改数据库设置,这是已经测试过的代码,请尝试使用。

1

你可以将几乎任何想要存储的内容存储在memcached中。

请参阅memcache::set的文档,其中写道:

bool Memcache::set(string $key, mixed $var [, int $flag [, int $expire ]] )

var

The variable to store. Strings and integers are stored as is, other types

are stored serialized.

所以,是的,如果需要,你可以存储一个数组,甚至是一个对象 :-)


顺便说一下,Memcache::addMemcache::replace 的情况也是一样的


实际上,add和replace并不完全相同。如果键已经存在,add会返回false。 - Andres SK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接