Создание масштабируемого плагина для избранного Wordpress - один последовательный массив мета-значений или множество мета-записей


Я пытаюсь создать простой плагин для избранных сообщений Wordpress, который является масштабируемым и может обрабатывать 1000 или 10000 пользователей или более.

Существует несколько различных подходов, которые я видел в других плагинах, и я хотел бы знать, какой из них будет наилучшей практикой с точки зрения масштабируемости, что означает, что размер записи или количество записей может быть проблемой.

Проблема: Основная идея заключается в том, что в сообщении есть кнопка, которую зарегистрировал в пользователь может нажать, чтобы добавить сообщение в избранное. Затем это должно быть сохранено в базе данных, чтобы, когда пользователь перейдет к этому сообщению, он не мог снова добавить его в избранное, а также мог просмотреть список своих избранных сообщений.

Вариант 1: Хранить как в мета-таблицах пользователей, так и в мета-таблицах сообщений с сериализованными массивами

Это то, что система Wordpress публикует как (https://hofmannsven.com/2013/laboratory/wordpress-post-like-system /) делает. После щелчка код извлекает _liked_posts мета-ключ из мета-таблицы пользователя, в которой хранятся в массиве идентификаторы записей, которые понравились пользователю, и он извлекает мета-ключ _user_likes из мета-таблицы записей, в которой хранятся в массиве идентификаторы пользователей, которым понравилась запись.

Затем код добавляет текущий идентификатор записи в _liked_posts, а текущий идентификатор пользователя - в _user_likes. Он также увеличивает еще две мета-записи: количество сообщений, похожих на количество, и количество пользователей, похожих на количество.

Что мне в этом нравится система заключается в том, что она кажется довольно простой, с одной записью в мета-файле пользователя и одной записью в мета-файле сообщения, хранящей, кому что понравилось. Что мне не нравится, так это то, что если у вас много пользователей, которым нравится сообщение, или пользователь, которому нравится много сообщений, эти массивы мета-значений могут быть очень длинными, что, я полагаю, может вызвать проблемы?

$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

Вариант 2: Добавьте запись в мета-данные пользователя для каждого понравившегося поста

После щелчка код проверяет, была ли запись уже вставлена в мету пользователя. Если нет, он добавляет новую запись избранного. Если это так, то оно ничего не делает.

Что мне нравится в этой системе, так это то, что ее легко запрашивать и генерировать статистику в будущем, поскольку она не привязана к сериализованным массивам. Что мне не нравится, так это то, что если у вас есть пользователь, которому нравится много сообщений, вы можете значительно увеличить количество записей в мета-таблице пользователя.

// 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);
}

Итак, в заключение, я спрашиваю, по сути, о том, что здесь является наилучшей практикой. Это либо:

  • Имея один большой сериализованный массив в одной паре мета-ключ/значение
  • Наличие множества пар мета/ключевое значение с целым числом в мета-значении
  • Есть ли еще один вариант, который я не рассматривал?

РЕДАКТИРОВАТЬ: Следуя полученным ответам, я решил, что создание пользовательской таблицы - лучший путь вперед. Я нашел этот учебник, который делает в значительной степени то, что я хочу сделать, и гораздо более расширяемым способом, чтобы я мог добавлять другие действия, а также просто "избранное".

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

Author: Alex, 2016-04-03

2 answers

Вы забыли вариант 3 - Добавить специальную таблицу, в которой пара (пользователь, идентификатор записи) будет индексом. Хорошо, я не специалист по MySQL, так что, возможно, это слишком экстремально, но, возможно, иметь две таблицы, одну с пользователями в качестве индекса, а другую с сообщениями, будет еще лучше.

Дело в производительности заключается в том, что редко существуют абсолютные решения для всех в любое время, и "лучшее" зависит от вашей фактической модели использования, а не от теоретической. Или, другими словами, вы проводите раннюю оптимизацию здесь.

Хотя вариант 2, по-видимому, быстрее для этой конкретной информации, он увеличит метатаблицы, и поэтому, вероятно, замедлит все запросы к этим таблицам (поэтому предложение для варианта 3, которое очень похоже, но не влияет на другие запросы).

Еще одна проблема, которую вы здесь игнорируете, - это стоимость вставки/обновления данных. Эта операция намного медленнее, чем чтение, и не может быть кэширована. Если у вас будет много лайков одновременно, с вариантом 2 вы заблокирует таблицы, и запросы должны будут ждать завершения других, и каждая вставка будет выполняться медленнее, в то время как вариант 1, скорее всего, приведет к повреждению данных при наивной реализации (два изменения одновременно, в лучшем случае только одно из них окажет влияние).

И затем вы должны принять во внимание, какой вид кэширования вы будете выполнять. При хорошей схеме кэширования время чтения не является проблемой.

В заключение я желаю, чтобы вы обнаружили, что это реальная проблема, которую необходимо решить решено, до тех пор просто напишите соответствующий api для доступа/изменения этих данных, чтобы скрыть детали реализации, поэтому, если это станет проблемой, вы сможете изменить реализацию, не влияя на остальную часть вашего кода.

 3
Author: Mark Kaplun, 2016-04-03 16:21:37

Вариант 1 - не лучший выбор, потому что сериализация данных означает, что вы должны проанализировать результат SQL, чтобы его можно было прочитать, и, следовательно, вы не можете воспользоваться никакими преимуществами SQL-запросов.

Вариант 2 был бы самым простым способом, но если у вас много пользователей, которым нравится много сообщений, то это начинает загрязнять мета-таблицу пользователей.

Вариант 3 что бы я сделал, так это создал реляционную таблицу между сообщениями и пользователями. Использовать таблицу отношений было бы проще всего, потому что затем вы можете использовать SQL, чтобы сделать для вас много логики. Например, вам не нужно подсчитывать, сколько лайков у одного поста в PHP, а вместо этого выполнить запрос к SQL, который сделает это за вас и вернет результат. Это означает, что это будет хорошо для производительности, и если вы удалите плагин, то все, что вам нужно сделать, это удалить таблицу, просто и чисто.

 0
Author: Marttin Notta, 2016-04-03 16:02:00