а студент-двоечник.
Категории и тэги лежат в одной таблице. Зачем — непонятно, но это ещё фигня. Таблица выглядит так:
CREATE TABLE `wp_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`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
Что такое term_group — загадка природы, там у всех записей 0.
slug — это URL-encoded name. Им лень было при обработке запросов в /tag/ и /category/ сделать url-decode и поискать по имени, лучше сделать лишнее поле. Причём поле это такой же длины, как и name, а один неанглоязычный символ из name в url-encoded виде занимает 6 байт, например буква “л” выглядит в slug как %d0%bb . А вот почему slug сделан уникальным ключом, а name неуникальным — загадка природы.
А тип записей в wp_terms вообще отсутствует. Он ВНЕЗАПНО лежит в другой таблице:
CREATE TABLE `wp_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`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
Вот в ней в поле taxonomy хранит тип записи. В текстовом виде: “category”, “post_tag” или “link_category”. И в сочетании с term_id оно составляет уникальный ключ. То есть, если попытаться создать и категорию, и тэг с одинаковым именем, то в wp_terms будет только одна запись, а в wp_term_taxonomy – две, с одинаковым term_id. Но это такая редкость, что экономить единичные записи в таблице, существенно усложняя при этом поиск по имени (join двух таблиц вместо простого поиска в одной) — это идиотизм.
Что есть parent — я вообще не понял, там всегда 0. А count (руки оторвать за использование названий стандартных функций в качестве имён полей) по идее должен хранить количество постов, привязанных к данной категории или тэгу. И для большинства записей это действительно так. Но иногда..
mysql> select term_taxonomy_id, count from wp_term_taxonomy where term_taxonomy_id = 1; +------------------+-------+ | term_taxonomy_id | count | +------------------+-------+ | 1 | 1933 | +------------------+-------+ mysql> select count(*) from wp_term_relationships where term_taxonomy_id = 1; +----------+ | count(*) | +----------+ | 3708 | +----------+
Ничего общего.. И даже если посчитать только опубликованные посты (исключить черновики и старые версии), всё равно не совпадает:
mysql> select count(*) from wp_term_relationships r join wp_posts p on r.object_id=p.ID where r.term_taxonomy_id = 1 and p.post_status='publish'; +----------+ | count(*) | +----------+ | 1936 | +----------+
Оригинал этой записи в личном блоге.
no subject
Parent у тебя всегда равен нулю потому что ты не делал иерархических разделов. Это возможно, типа: articles -> yachts, articles -> locations, articles -> people и т.д. Можно выбрать все articles с подразделами, а можно только people.
term_group служит для создания адиасов к тэгам.
no subject
И наоборот, если в wp_terms создать записи с разными именами для тэга и категории, то приделать к ним одинаковый slug не получится, потому что он уникальный ключ.
Короче, склеить эти две таблицы в одну, с отдельными записями для одноимённых тэгов и категорий, если таковые вдруг случатся, было бы гораздо логичнее. Или вообще сложить тэги в одну таблицу, а категории в другую.
Что есть "адиасы к тэгам"? Алиасы что ли? А нафига они нужны? И как они работают в группе?
А ещё, например, в таблице с постами wp_posts есть поле post_category int(4) , и оно всегда 0. Нафига оно нужно, если категорий у поста может быть несколько, и привязка поста к категориям хранится в отдельной таблице wpd_term_relationships?
no subject
Алиасы работают только программно: можно создать тэг при помощи функции wp_insert_term и указать в доп. параметрах alias_of со значением slug тэга, к которому новый тэг должен быть алиасом. Зачем это надо - я сам не очень понимаю, см. пассаж про 10 лет.
no subject
Угу. Проблема только в том, что латиноиды часто традиционно забивают на другие языки, и им в голову не приходит, что 1 буква != 1 байту :)
Впрочем, да, когда оно делалось, кроме однобайтовости толком ничего и не было...