P.P.S. Статья была написана для вордпресса версии 2.5.х. Впоследствии структура базы изменилась, хотя и незначительно.
P.S. Как оказалось, полную документацию по строению базы данных движка можно подчерпнуть здесь: http://codex.wordpress.org/Database_Description, но она на английском. С другой стороны, «ручной» разбор базы принёс бесценный опыт, плюс ко всему, моя схема мне нравится больше и вмещается на экран :)
Все данные блога WordPress хранятся всего в десяти таблицах.

На схеме показаны не все связи, а только важнейшие из них. Например, польза от таблицы links очень сомнительна, поэтому её взаимодействие с другими объектами даже не рассматривалось.
Имя таблицы | Описание |
---|---|
posts | Основная таблица в базе. Здесь хранятся все статьи (заголовок, содержимое) и их служебная информация (дата создания, автор, тип и т.д.). |
postmeta | Дополнительные данные к статье, которые не попадают в стандартные поля таблицы posts. |
users | Данные о пользователях: как об авторах статей, так и о пользователях с возможностью их комментирования |
usermeta | Дополнительные поля для описания пользователей, дополнение к таблице users. |
comments | Здесь хранятся все комментарии для всех статей. |
terms | Простой список рубрик, к которым статья может относиться. Немного служебной информации о рубриках. |
term_taxonomy | В этой таблице рубрики систематизируются, то есть она служит для создания дерева рубрик. |
term_relationships | Здесь задаётся соответствие статьи и рубрики (вернее, элементу дерева рубрик из таблицы term_taxonomy), к которой статья относится. |
links | Ссылки и вся по ним информация. |
options | Общие настройки движка WordPress. |
Остановимся на каждой из таблиц подробнее. Для того, чтобы анализировать содержимое таблиц - подключимся к нужной базе:
если нужно - выберем кодировку для содержимого (у меня это UTF-8):
после чего просматривать таблицы можно будет с помощью простых запросов, наподобие:
posts
Таблица для хранения записей, черновиков и библиотеки медиафайлов (!), включая изображения.
Код для создания таблицы в MySQL:
CREATE TABLE `posts` ( `ID` bigint(20) unsigned NOT NULL auto_increment, `post_author` bigint(20) unsigned NOT NULL default '0', `post_date` datetime NOT NULL default '0000-00-00 00:00:00', `post_date_gmt` datetime NOT NULL default '0000-00-00 00:00:00', `post_content` longtext NOT NULL, `post_title` text NOT NULL, `post_category` int(4) NOT NULL default '0', `post_excerpt` text NOT NULL, `post_status` varchar(20) NOT NULL default 'publish', `comment_status` varchar(20) NOT NULL default 'open', `ping_status` varchar(20) NOT NULL default 'open', `post_password` varchar(20) NOT NULL default '', `post_name` varchar(200) NOT NULL default '', `to_ping` text NOT NULL, `pinged` text NOT NULL, `post_modified` datetime NOT NULL default '0000-00-00 00:00:00', `post_modified_gmt` datetime NOT NULL default '0000-00-00 00:00:00', `post_content_filtered` text NOT NULL, `post_parent` bigint(20) unsigned NOT NULL default '0', `guid` varchar(255) NOT NULL default '', `menu_order` int(11) NOT NULL default '0', `post_type` varchar(20) NOT NULL default 'post', `post_mime_type` varchar(100) NOT NULL default '', `comment_count` bigint(20) NOT NULL default '0', PRIMARY KEY (`ID`), KEY `post_name` (`post_name`), KEY `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`), KEY `post_parent` (`post_parent`) )
Содержимое таблицы
Поле | Описание |
---|---|
ID | Идентификатор записи, он же первичный ключ. Значения - от 1 до 263-1. Максимальное значение ячейки записывается 20-разрядным числом. |
post_author | Автор статьи, который задаётся идентификатором ID таблицы users. |
post_date | Дата публикации, время - местное. |
post_date_gmt | Дата публикации, время - по гринвичу. |
post_content | Содержимое статьи. При сохранении и выводе на страницу это содержимое проходит через вордпрессовский фильтр замен, именно поэтому часто на экране можно увидеть совсем не то, что мы вводили. |
post_title | Заголовок статьи или имя для изображения в библиотеке медиафайлов (да-да, изображения, вернее ссылки на них, тоже хранятся в этой таблице). Интересно, хоть кто-то придумал заголовок максимальной длины, в 65535 символов? |
post_category | Всегда равен 0. |
post_excerpt | Краткая выдержка, информация о записи (цитата). Надо вводить самостоятельно, по умолчанию отсутствует. |
post_status | Статус записи. Лично я встретил такие: publish - опубликованная, draft - черновик, inherit - связанная (например, изображение или резервная копия записи). |
comment_status | Включена ли возможность комментирования. open - можно комментировать, closed - нельзя. |
ping_status | Разрешены ли обратные ссылки и уведомления. Значения - open и closed |
post_password | Пароль в явном виде, если статья запаролирована. В противном случае - нет значения. |
post_name | Имя страницы для статичной ссылки. Записи автосохранения и изменения задают это имя автоматом. |
to_ping | |
pinged | |
post_modified | Дата последнего изменения. |
post_modified_gmt | То же самое - по гринвичу. |
post_content_filtered | |
post_parent | Для резервных копий и изображений - ID родительской записи. |
guid | Полная интернет-ссылка на запись (объект). Здесь вордпресс проявляет всю свою фантазию. На «статические» страницы даёт php-запрос типа ..?page_id=N, на автосейвы - с датой в URL-е, и т.д. |
menu_order | Равен 0. |
post_type | Тип записи: post - обычная запись, page - запись с постоянной ссылкой (статичная), revision - автосохранение, attachment - медиафайл (например, изображение). |
post_mime_type | Якобы тип содержимого записи. Важен и нужен только для прикреплений (например, png-изображение проходит как image/png). |
comment_count | Количество комментов к записи. |
postmeta
Аппендикс для таблицы posts. Вдруг авторы не предусмотрели всего, что хотели в неё напихать.
Код для создания таблицы в MySQL:
CREATE TABLE `postmeta` ( `meta_id` bigint(20) unsigned NOT NULL auto_increment, `post_id` bigint(20) unsigned NOT NULL default '0', `meta_key` varchar(255) default NULL, `meta_value` longtext, PRIMARY KEY (`meta_id`), KEY `post_id` (`post_id`), KEY `meta_key` (`meta_key`) )
Содержимое таблицы
Поле | Описание |
---|---|
meta_id | Первичный ключ. |
post_id | К какой записи таблицы posts относятся наши метаданные. |
meta_key | Имя дополнительного параметра. Часто используется для прикреплений файлов и других метаданных к статье. |
meta_value | Значение дополнительного параметра. Содержимое зависит от имени параметра. |
Вордпресс достаточно яростно использует эту таблицу, так что если захотите от неё избавиться - внимательно смотрите какие функции её используют, какие параметры в ней хранятся и для чего.
users
Здесь хранятся пользователи блога: как честный автор, так и простые посетители, зарегистрировавшиеся для комментариев.
Код для создания таблицы в MySQL:
CREATE TABLE `users` ( `ID` bigint(20) unsigned NOT NULL auto_increment, `user_login` varchar(60) NOT NULL default '', `user_pass` varchar(64) NOT NULL default '', `user_nicename` varchar(50) NOT NULL default '', `user_email` varchar(100) NOT NULL default '', `user_url` varchar(100) NOT NULL default '', `user_registered` datetime NOT NULL default '0000-00-00 00:00:00', `user_activation_key` varchar(60) NOT NULL default '', `user_status` int(11) NOT NULL default '0', `display_name` varchar(250) NOT NULL default '', PRIMARY KEY (`ID`), KEY `user_login_key` (`user_login`), KEY `user_nicename` (`user_nicename`) )
Содержимое таблицы
Поле | Описание |
---|---|
ID | Идентификатор, первичный ключ. |
user_login | Имя пользователя для входа. |
user_pass | Пароль пользователя для входа, в зашифрованном виде. |
user_nicename | Как обращаться к пользователю. Как правило, совпадает с именем для входа. |
user_email | Электропочта для связи. |
user_url | Адрес сайта пользователя. Именно благодаря этому очень нужному полю, блоги на вордпрессе с настройками по умолчанию потихоньку обрастают спамом. |
user_registered | Дата регистрации пользователя. |
user_activation_key | Активационный ключ, рандомный. После активации удаляется. |
user_status | |
display_name | Имя для отображения. |
usermeta
Игнорируя существование таблицы users, все относящиеся к пользователю данные хранятся здесь.
Код для создания таблицы в MySQL:
CREATE TABLE `usermeta` ( `umeta_id` bigint(20) unsigned NOT NULL auto_increment, `user_id` bigint(20) unsigned NOT NULL default '0', `meta_key` varchar(255) default NULL, `meta_value` longtext, PRIMARY KEY (`umeta_id`), KEY `user_id` (`user_id`), KEY `meta_key` (`meta_key`) )
Содержимое таблицы
Поле | Описание |
---|---|
umeta_id | Идентификатор метазаписи, первичный ключ. |
user_id | Идентификатор пользователя, к которому имеет отношение запись. |
meta_key | Дополнительный параметр. Вот здесь - внимание! Дополнительными параметрами считаются: nickname - как пользователь отображается в системе, first_name - реальное имя пользователя, description - описание. И многое другое, что можно было бы использовать в таблице users. |
meta_value | Значение дополнительного параметра. |
comments
Код для создания таблицы в MySQL:
CREATE TABLE `comments` ( `comment_ID` bigint(20) unsigned NOT NULL auto_increment, `comment_post_ID` bigint(20) unsigned NOT NULL default '0', `comment_author` tinytext NOT NULL, `comment_author_email` varchar(100) NOT NULL default '', `comment_author_url` varchar(200) NOT NULL default '', `comment_author_IP` varchar(100) NOT NULL default '', `comment_date` datetime NOT NULL default '0000-00-00 00:00:00', `comment_date_gmt` datetime NOT NULL default '0000-00-00 00:00:00', `comment_content` text NOT NULL, `comment_karma` int(11) NOT NULL default '0', `comment_approved` varchar(20) NOT NULL default '1', `comment_agent` varchar(255) NOT NULL default '', `comment_type` varchar(20) NOT NULL default '', `comment_parent` bigint(20) unsigned NOT NULL default '0', `user_id` bigint(20) unsigned NOT NULL default '0', PRIMARY KEY (`comment_ID`), KEY `comment_approved` (`comment_approved`), KEY `comment_post_ID` (`comment_post_ID`), KEY `comment_approved_date_gmt` (`comment_approved`,`comment_date_gmt`), KEY `comment_date_gmt` (`comment_date_gmt`) )
Содержимое таблицы
Поле | Описание |
---|---|
comment_ID | Идентификатор комментария, первичный ключ. |
comment_post_ID | Идентификатор заметки, к которой относится комментарий. |
comment_author | Автор, берётся из регистрационных данных или вводится вручную, если регистрация для комментариев не требуется. |
comment_author_email | Электропочта. |
comment_author_url | Сайт автора комментария. |
comment_author_IP | IP-адрес прокомментировавшего. |
comment_date | Дата и время. |
comment_date_gmt | Дата и время - по гринвичу. |
comment_content | Сам комментарий. |
comment_karma | |
comment_approved | Одобрен ли комментарий для показа. |
comment_agent | С какого браузера и системы заходили. |
comment_type | |
comment_parent | Родительский коммент. Нужен для древовидной структуры. |
user_id | Идентификатор зарегистрированного пользователя. |
terms
Описание рубрик.
Код для создания таблицы в MySQL:
CREATE TABLE `terms` ( `term_id` bigint(20) unsigned NOT NULL auto_increment, `name` varchar(200) NOT NULL default '', `slug` varchar(200) NOT NULL default '', `term_group` bigint(10) NOT NULL default '0', PRIMARY KEY (`term_id`), UNIQUE KEY `slug` (`slug`), KEY `name` (`name`) )
Содержимое таблицы
Поле | Описание |
---|---|
term_id | Идентификатор. |
name | Название рубрики. Название используется для определения рубрики практически везде, например, под записью или в виджете рубрик. |
slug | Ярлык рубрики. «Ярлык» — это вариант названия, подходящий для URL. Обычно содержит только латинские буквы в нижнем регистре, цифры и дефисы. |
term_group |
term_taxonomy
Таблица для объединения рубрик в деревья и для описания взаимосвязей рубрик.
Код для создания таблицы в MySQL:
CREATE TABLE `term_taxonomy` ( `term_taxonomy_id` bigint(20) unsigned NOT NULL auto_increment, `term_id` bigint(20) unsigned NOT NULL default '0', `taxonomy` varchar(32) NOT NULL default '', `description` longtext NOT NULL, `parent` bigint(20) unsigned NOT NULL default '0', `count` bigint(20) NOT NULL default '0', PRIMARY KEY (`term_taxonomy_id`), UNIQUE KEY `term_id_taxonomy` (`term_id`,`taxonomy`), KEY `taxonomy` (`taxonomy`) )
Содержимое таблицы
Поле | Описание |
---|---|
term_taxonomy_id | Идентификатор, первичный ключ. |
term_id | Идентификатор рубрики. |
taxonomy | category - рубрика, link_category - рубрика ссылок. |
description | Краткое описание. |
parent | Идентификатор родительской рубрики. |
count | Количество ассоциированных записей. |
term_relationships
Таблица для связи статьи с рубриками.
Код для создания таблицы в MySQL:
CREATE TABLE `term_relationships` ( `object_id` bigint(20) unsigned NOT NULL default '0', `term_taxonomy_id` bigint(20) unsigned NOT NULL default '0', `term_order` int(11) NOT NULL default '0', PRIMARY KEY (`object_id`,`term_taxonomy_id`), KEY `term_taxonomy_id` (`term_taxonomy_id`) )
Содержимое таблицы
Поле | Описание |
---|---|
object_id | Какой объект описываем. |
term_taxonomy_id | С какой связью рубрик ассоциируем. |
term_order |
links
Таблица ссылок. Задумка неплохая, но как же похабно она реализована по умолчанию.
Код для создания таблицы в MySQL:
CREATE TABLE `links` ( `link_id` bigint(20) unsigned NOT NULL auto_increment, `link_url` varchar(255) NOT NULL default '', `link_name` varchar(255) NOT NULL default '', `link_image` varchar(255) NOT NULL default '', `link_target` varchar(25) NOT NULL default '', `link_category` bigint(20) NOT NULL default '0', `link_description` varchar(255) NOT NULL default '', `link_visible` varchar(20) NOT NULL default 'Y', `link_owner` bigint(20) unsigned NOT NULL default '1', `link_rating` int(11) NOT NULL default '0', `link_updated` datetime NOT NULL default '0000-00-00 00:00:00', `link_rel` varchar(255) NOT NULL default '', `link_notes` mediumtext NOT NULL, `link_rss` varchar(255) NOT NULL default '', PRIMARY KEY (`link_id`), KEY `link_category` (`link_category`), KEY `link_visible` (`link_visible`) )
options
Общие настройки движка WordPress
Код для создания таблицы в MySQL:
CREATE TABLE `options` ( `option_id` bigint(20) unsigned NOT NULL auto_increment, `blog_id` int(11) NOT NULL default '0', `option_name` varchar(64) NOT NULL default '', `option_value` longtext NOT NULL, `autoload` varchar(20) NOT NULL default 'yes', PRIMARY KEY (`option_id`,`blog_id`,`option_name`), KEY `option_name` (`option_name`) )
Данные в этой таблице не связаны с данными из других таблиц и служат для настройки блога в целом. Описывать столбцы подробно нет смысла.
Комментарии
#cid424
Ответить
Спамеры для своих гей-атак выбрали почему-то именно это страницу. Это странно, потому что многие другие страницы этого сайта посещаются значительно чаще.
С другой стороны, мои анти-спам фильтры улучшаются и пополняются новыми правилами.
И это хорошо.
Cerber
#cid838
Ответить
Спасибо, информация как раз для курсовой подошла ;)
waytotrueman
#cid3117
Ответить
Внимание! Предлагаю [...]
Внимание! Спамеры тут идут нахуй. Религиозные спамеры — тем более.
Модератор.
Матвей
#cid5031
Ответить
За топик спасибо!
Амину 5+ за спам тесты ;)
"Внимание! Спамеры тут идут нахуй. Религиозные спамеры — тем более."
#cid5034
Ответить
Пожалуйста )
Но надо помнить, что структура вордпресса с момента написания этой статьи серьёзно изменилась. И появилась подробная документация на русском языке. Поэтому эта запись не обновляется.
95% спама успешно отсеивается автоматикой. Остальное достаточно оперативно удаляется при модерации.
Несмотря на это, накал не снижается, а наоборот, только растёт.
Fupe
#cid17786
Ответить
Доброго времени суток! Не вижу условия использования информации. Можно ли копировать написанный вами текст на свой сайт, если ставить ссылку на эту страницу?
#cid17791
Ответить
#cid17786, Fupe
Всё в разделе WTF?&!
Можно.
Igor
#cid52210
Ответить
Самая удачная схема, которую мне удалось найти. Спасибо!
#cid52215
Ответить
#cid52210, Igor
Она уже сильно устарела.
Но — пожалуйста )
fgdf
#cid55029
Ответить
gfdgdfg
fgdf
#cid55030
Ответить
#cid55029, fgdf
Упс пардон, думал спам фильтр сработает, на аброкадабру(просто было интересно, не баньте) статья отличная мне как раз пригодилась
honk
#cid90909
Ответить
За статью спасибо!
искал в нете связь публикаций с категориями (дя переноса с вордпреса на другой движок), всё изложено понятно!
WB
#cid91655
Ответить
Спасибо за статью, хоть и не свежая, но поможет новичку разобраться что по чём.