构建一个可伸缩的WordPress收藏夹插件--一个序列化的元值数组或多个元记录

时间:2016-04-03 作者:Alex

我正在尝试构建一个简单的Wordpress收藏夹帖子插件,该插件可扩展,可以处理1000或100000或更多用户。

我在其他插件中看到了几种不同的方法,我想知道从可伸缩性的角度来看,哪种方法是最佳实践,这意味着记录的大小或记录的数量可能是一个问题。

问题:基本的想法是,在帖子上有一个按钮,登录用户可以单击该按钮来喜爱帖子。然后必须将其存储在数据库中,这样当用户转到该帖子时,他们就不能再喜欢它,也可以查看他们喜欢的帖子列表。

Option 1: Store in both user meta and post meta tables with serialised arrays

这就是Wordpress Post的系统(https://hofmannsven.com/2013/laboratory/wordpress-post-like-system/) 做单击后,代码从用户元表中检索\\u liked\\u posts元键,该表在数组中存储用户喜欢的帖子的帖子ID,并从post元表中检索\\u user\\u likes元键,该表在数组中存储喜欢帖子的用户的用户ID。

然后,代码将当前帖子id附加到\\u liked\\u帖子,并将当前用户id附加到\\u user\\u likes。它还增加了另外两个元记录:类post计数和类用户计数。

我喜欢这个系统的地方是它看起来相当简单,只有一条记录在用户元中,一条记录在后元存储中,谁喜欢什么。我不喜欢的是,如果有很多用户喜欢这篇文章,或者有一个用户喜欢很多文章,那么这些元值数组可能会很长,我想这可能会导致问题?

$meta_POSTS = get_user_meta( $user_id, "_liked_posts" ); // post ids from user meta
$meta_USERS = get_post_meta( $post_id, "_user_liked" ); // user ids from post meta
$meta_POSTS[\'post-\'.$post_id] = $post_id; // Add post id to user meta array
$meta_USERS[\'user-\'.$user_id] = $user_id; // add user id to post meta array
update_post_meta( $post_id, "_user_liked", $meta_USERS ); // Add user ID to post meta
update_user_meta( $user_id, "_liked_posts", $meta_POSTS ); // Add post ID to user meta

Option 2: Add a record to user meta for each liked post

单击之后,代码检查记录是否已插入到用户元中。如果没有,它会添加最喜爱的新记录。如果有,它什么也不做。

我喜欢这个系统的地方是,它很容易查询和生成统计数据,因为它不被串行数组所束缚。我不喜欢的是,如果你让用户喜欢很多帖子,你可以大大增加用户元表中的记录数。

// Check if already favourited the post in User Meta
// Not sure how you would do this with WP_Query or WP_User_Query, any suggestions?

$favourited = WP_Query($args)

if ($favourited->post_count == 0) {
  // Add user meta with favourite
  add_user_meta($userid, \'_favourite_episode\', $postid);
}
最后,我想问的是,这里的最佳实践是什么。是不是:

在一个元键值对中有一个大型串行数组,在元键值对中有许多元键值对和一个整数,还有其他选项我没有考虑吗EDIT: 根据给出的答案,我决定创建自定义表是最好的方法。我发现这篇教程做了我想做的事情,并且以一种更具扩展性的方式,这样我就可以添加其他操作以及“收藏”。

http://code.tutsplus.com/series/custom-database-tables--wp-33839

2 个回复
最合适的回答,由SO网友:Mark Kaplun 整理而成

您忘记了选项3-添加一个特殊的表,其中该对(用户,帖子id)将作为索引。好吧,我不是MySQL用户,所以可能这太极端了,但也许有两个表,一个是用户索引表,另一个是帖子表会更好。

性能方面的问题是,在任何时候都很少有针对每个人的绝对解决方案,而“最佳”取决于您的实际使用模式,而不是理论模式。或者换句话说,您正在这里进行早期优化。

虽然选项2对于这个特定的信息似乎更快,但它会使元表更大,因此可能会变慢all 对这些表的请求(因此,对选项3的建议非常相似,但不影响其他查询)。

这里您忽略的另一个问题是数据插入/更新的成本。此操作比读取慢得多,并且无法缓存。如果您要同时拥有许多喜欢的内容,那么使用选项2,您将锁定表,请求将需要等待其他人完成,并且每个插入都会变慢,而选项1在天真的实现下很可能会导致数据损坏(同时进行两次更改,最多只有一次会产生影响)。

然后,您应该考虑您将使用何种缓存。使用良好的缓存方案,读取时间不是问题。

最后,我希望您会发现这是一个需要解决的实际问题,在此之前,只需编写适当的api来访问/更改该数据,以隐藏实现细节,这样,如果它将成为一个问题,您就可以更改实现,而不会影响代码的其余部分。

SO网友:Marttin Notta

选项1不是最佳选择,因为序列化数据意味着您必须解析SQL结果以使其可读,因此您无法利用SQL查询的任何优势。

选项2是最简单的方法,但如果有很多用户喜欢很多帖子,那么它就会开始污染用户元表。

选项3我要做的是在帖子和用户之间创建关系表。使用关系表将是最简单的,因为这样您就可以使用SQL为您执行大量逻辑。例如,您不需要计算一篇文章在PHP中有多少个like,而是对SQL运行一个查询,为您执行此操作并返回结果。这意味着这将有助于提高性能,如果卸载插件,那么您所要做的就是删除表,简单而干净。

相关推荐

致命错误:未捕获错误:无法将WP_ERROR类型的对象用作/../plugins/rm-payment.php中的数组

我使用2个WordPress站点、1个WordPress站点到2个WordPress站点的远程支付系统。第一个是主网站;第二个网站的工作方式类似于处理贝宝支付的商户网站。我们将第一个网站的用户订单详细信息提取到第二个网站,以处理贝宝付款。但在获取第二个网站的网页时出现错误,但请记住,如果重新加载它一次,问题就解决了致命错误:未捕获错误:无法将WP\\u error类型的对象用作/中的数组/插件/rm支付。php:第231行 $response = wp_remote_post( $remote_url,