November 2019

S M T W T F S
      12
34 5 678 9
10111213141516
17181920212223
24252627282930

Style Credit

Expand Cut Tags

No cut tags
Saturday, August 23rd, 2014 12:51 pm

а студент-двоечник.

Категории и тэги лежат в одной таблице. Зачем — непонятно, но это ещё фигня. Таблица выглядит так:

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 |
+----------+

Оригинал этой записи в личном блоге.

Saturday, August 23rd, 2014 06:46 pm (UTC)
Slug не всегда равен urlencoded name, это просто url-friendly текстовый идентификатор, может быть любой. Есть, например, плагины, которые из русского тэга "сиськи" делают slug "sisky" или даже "tits" с подключением Google Translate API.

Parent у тебя всегда равен нулю потому что ты не делал иерархических разделов. Это возможно, типа: articles -> yachts, articles -> locations, articles -> people и т.д. Можно выбрать все articles с подразделами, а можно только people.

term_group служит для создания адиасов к тэгам.
Saturday, August 23rd, 2014 08:55 pm (UTC)
Слушай, платформа живёт и развивается уже больше 10 лет. Есть какие-то вещи, которые тянутся с первых релизов, с которыми имеет смысл обращаться по принципу "работает - не трожь". post_category - из них.

Алиасы работают только программно: можно создать тэг при помощи функции wp_insert_term и указать в доп. параметрах alias_of со значением slug тэга, к которому новый тэг должен быть алиасом. Зачем это надо - я сам не очень понимаю, см. пассаж про 10 лет.
Thursday, August 28th, 2014 02:29 pm (UTC)
>Slug не всегда равен urlencoded name, это просто url-friendly текстовый идентификатор

Угу. Проблема только в том, что латиноиды часто традиционно забивают на другие языки, и им в голову не приходит, что 1 буква != 1 байту :)

Впрочем, да, когда оно делалось, кроме однобайтовости толком ничего и не было...