Основы использования реляционных данных в WordPress

В первой статье из цикла «Данные в WordPress» я привела обзорные сведения об использовании реляционных баз данных в WordPress: какие таблицы используются, и какие данные они хранят. В этой статье я подробнее расскажу о том, как WordPress управляет отношениями между таблицами.

В соответствии с теорией реляционных баз данных, WordPress использует три вида отношений: «один к одному», «один ко многим» и «многие ко многим». Я покажу каждый вид отношения на примере его использования в реальном WordPress-сайте.

Один к одному

Отношение «один к одному» – самый простой вид отношений. Он означает, что данное поле соответствует какому-либо другому единственному полю. Обычно данные, соотносящиеся таким образом, хранятся в одной таблице (хотя бывают и исключения, о которых мы поговорим позже).

Примеры отношений «один к одному»:

  • идентификатор публикации и содержимое поста;
  • заголовок и текст публикации;
  • идентификатор публикации и его слаг;
  • идентификатор комментария и содержимое комментария;
  • идентификатор пользователя и его имя…

Этот список можно продолжать и дальше, но суть этих примеров, я думаю, уже понятна: отношение любых данных, находящихся в разных полях одной строки таблицы, является отношением «один к одному».

Отношение «один к одному» – наименее интересный вид отношений данных, поэтому давайте рассмотрим следующий тип отношений, который интенсивно используется в архитектуре данных WordPress – «один ко многим».

Один ко многим

Отношение «один ко многим» очень часто используется в реальных базах данных. В конце концов, это именно то, что делает RDBMS полезнее, чем «плоские» электронные таблицы. Такое отношение возникает, когда одной записи соответствует несколько других.

В базе данных WordPress отношения «один ко многим» реализуются в виде связи между двумя таблицами с использованием специального уникального идентификатора.

Например, поле post_id является уникальным идентификатором публикации в таблице wp_posts, но оно также используется в таблице wp_comments, чтобы определить, к какой публикации относятся комментарии.

Это означает, что если данное значение поля post_id встречается в wp_posts только однажды, то в wp_comments оно может встретиться несколько раз или не встретиться вообще.

Другие примеры отношения «один ко многим» в WordPress:

  • публикация и метаданные публикации;
  • публикация и пользователь;
  • пользователь и метаданные пользователя;
  • таксономия и терм таксономии…

… и так далее. Поскольку отношения «один ко многим» очень важны для функционирования сайта, рассмотрим их немного подробнее.

Отношения «один ко многим», включающие публикации

Таблица wp_posts связана с наибольшим количеством других таблиц, и большинство этих связей являются отношениями типа «один ко многим».

На приведённой ниже диаграмме вы можете видеть, что таблица wp_posts непосредственно связана с четырьмя другими таблицами:

диаграмма

Кроме того, публикации могут быть связаны отношениями «один ко многим» с другими публикациями в форме родительских-дочерних связей либо как вложения.

Рассмотрим эти отношения ещё ближе.

Отношения «публикация-публикация»

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

Вложение, хранящееся в таблице wp_posts, имеет поле post_parent, в котором хранится идентификатор публикации, в которую вложено это вложение. (Простите за тавтологию).

Это типичный пример отношений «один ко многим», потому что вложение может быть вложено только в один пост, в то время как пост может иметь сколько угодно вложений.

Это относится и к тому случаю, когда вы используете медиа-менеджер, чтобы добавить медиафайл к публикации: поле post_parent будет ссылаться на тот пост, в который этот файл был вложен впервые.

Те же отношения возникают между публикациями, представляющими собой страницы сайта. В этом случае в поле post_parent данной страницы так же хранится post_id той страницы, которая на неё ссылается.

Это тоже типичный случай отношений «один ко многим», так как одна страница может иметь сколько угодно дочерних страниц, но страница верхнего уровня для данной страницы может быть только одна.

Говоря об отношениях между публикациями, важно помнить, что публикация – это не только то, что выглядит для посетителя сайта как публикация. Публикациями являются также страницы, вложения и другие типы данных, хранящихся в таблице wp_posts.

«Публикация-метаданные публикации»

Метаданные публикаций хранятся в специальной таблице wp_postmeta. Эта таблица имеет всего 4 колонки: идентификатор публикации (post_id), идентификатор элемента метаданных (meta_id), ключ и значение.

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

«Публикация-комментарии»

Комментарии также хранятся в отдельной таблице под названием wp_comments. Каждый комментарий относится к определённому посту, в то время как пост может иметь любое количество комментариев. Таблица комментариев имеет поле, хранящее идентификатор публикации. Это поле называется comment_post_id и связано с полем post_id таблицы wp_posts.

Таблица комментариев довольно обширна: она имеет по умолчанию 15 полей и хранит данные об авторе комментария, способе связи с ним, текст комментария и статус одобрения комментария автором поста. Также записи в таблице комментариев могут быть связаны с записями в таблице пользователей – wp_users. Мы ещё вспомним об этом в следующей части нашей статьи.

Комментарии также имеют свои метаданные, хранящиеся в отдельной таблице, и о них мы также вскоре поговорим.

«Публикации-пользователь»

Каждая публикация привязана к таблице wp_users посредством поля post_author в таблице wp_posts. Это отношение типа «один к нескольким»: у публикации может быть только один автор, а вот пользователь может быть автором любого числа публикаций.

Отношение «публикации-пользователь» отличается от отношений, связывающих публикации с метаданными или комментариями. Поэтому для связи используются разные поля: user_id вместо post_id в предыдущих случаях.

Отношения «один ко многим», не включающие публикации

Есть также три важных связи, организованные по принципу «один ко многим», но не касающиеся таблицы публикаций. Две из них имеют отношение к метаданным.

«Пользователь-метаданные пользователя»

WordPress хранит дополнительные данные (данные о данных, или метаданные), касающиеся пользователей, в таблице wp_usermeta. Там хранится, например, информация о супер администраторах в мультисайтовых инсталляциях WordPress, о пользовательском цветовом оформлении и т. д.

Основой хранения данных о пользователях является таблица wp_users. Две таблицы связаны между собой полями user_id. С пользователем может быть ассоциировано сколько угодно строк в таблице метаданных, в то время как каждый элемент метаданных принадлежит только одному пользователю.

«Комментарий-метаданные комментария»

Повторюсь: много информации касательно комментариев хранятся в одной таблице – wp_comments. Но есть также и метаданные, которые хранятся отдельно – в таблице wp_commentmeta. В ней, например, хранит свои данные популярный антиспам плагин Akismet. Отношение между этими таблицами такое же, что и в предыдущем примере.

«Комментарии-пользователь»

Последнее, о чём мы хотим здесь поговорить – отношение между комментариями и пользователями. Таблица wp_comments имеет поле user_id, которое хранит идентификатор пользователя в том случае, если комментарий оставил пользователь, авторизовавшийся на сайте через систему безопасности WordPress.

Учтите, что это поле не является обязательным, так как на сайтах может использоваться анонимное комментирование или иные механизмы авторизации.

Отношения «многие ко многим»

Этот тип отношений представляет собой вариант отношений «один ко многим», когда связь может быть повёрнута в обе стороны. Такое отношение используется в WordPress лишь единожды, для работы таксономии (категории и тэги также являются термами таксономии). Одна публикация может иметь несколько термов, равно как и один терм может быть использован в нескольких публикациях.

Как и многие другие приложения, WordPress реализует данное отношение через дополнительную, внутреннюю таблицу, связывающую ключевым полем две другие таблицы. Эта внутренняя таблица называется wp_term_relationships, и она связывает таблицу wp_posts с таблицей wp_term_taxonomy.

(Также эта таблица используется для связи wp_links с wp_term_taxonomy, так как в этом плане ссылки ведут себя так же, как посты. О ссылках будет рассказано чуть позже).

Отношение «многие ко многим» проще всего понять, взглянув на структуру таблиц, о которых мы говорим. Таблица wp_posts хранит публикации, а wp_term_taxonomy – отдельные термы, включая идентификатор терма и информацию о том, в какой справочник он входит.

Чтобы связать эти таблицы, WordPress создаёт запись в таблице wp_term_relationships. Эта запись содержит две ссылки: на идентификатор поста (post_id) в поле object_id и идентификатор терма (term_id) в поле term_taxonomy_id.

Таблица может содержать множество записей, относящихся к одной публикации, и множество записей, относящихся к одному терму, следовательно, она реализует отношение «многие ко многим».

Следующая диаграмма наглядно показывает описанный механизм:

диаграмма наглядно показывает описанный механизм

Содержание примера следующее:

  • пост 1 содержит термы 1 и 3;
  • пост 2 содержит терм 2;
  • пост 3 содержит терм 4;
  • пост 4 содержит термы 1 и 3.

Разумеется, эти отношения можно описывать и в обратном порядке, например: терм 3 относится к постам 1 и 4, и т. д.

Но соотношения между данными на этом не кончаются. Есть и четвёртая таблица, wp_terms. Она содержит такие сведения о термах, как имя, слаг и описание. Каждому терму соответствует лишь одна запись в wp_terms, так что таблицы wp_term_taxonomy и wp_terms соотносятся как «один к одному».

Теоретически, нет причин держать все эти данные в разных таблицах, но на практике на проектирование базы данных влияют также соображения быстродействия.

Замечание о ссылках

«Ссылки» (blogroll) – функция WordPress, которая сейчас далеко не так востребована, как раньше. Фактически, начиная с версии WordPress 3.5, эта функция по умолчанию отключена. Тем не менее, отдельная таблица ссылок, wp_links, ещё присутствует в базе данных WordPress.

Таблица ссылок похожа на таблицу постов wp_posts, что вполне естественно, так как посты и ссылки – контент одного порядка. Ссылки имеют те же отношения «многие к многим» с термами таксономии.

Выводы

Как вы могли убедиться, WordPress использует различные типы отношений между данными в 10 из 11 таблиц своей базы данных. Одиннадцатая таблица – wp_options – до сих пор не была мной упомянута, так как данные в ней не связаны ни с какими другими. Эта таблица хранит данные о сайте, а не его контент. В другой раз вы узнаете о ней больше.

Понимание соотношений между данными в WordPress поможет вам эффективно использовать базу данных и создавать собственные запросы к ней при разработке тем и плагинов.

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

Перевод статьи «Understanding and Working with Relationships Between Data in WordPress» был подготовлен дружной командой проекта Сайтостроение от А до Я.