Встраиваю поддержку бд в посты. Неожиданно вытанцовывается три таблицы для постов: собственно классическая таблица с простынкой полей, таблица со страницами - если пост из нескольких страниц, то страницы будут хранится в отдельной таблице, и таблица для сырого контента - rawcontent. Сырой контент используется для получения фильтрованного контента, который непосредственно выводится. Сырой же контент мало используется и я его храню на всякий случай, ну например для случая изменения фильтра контента, или еще для чего нибудь. Поскольку сырой контент принимает участие в круговороте веществ только во время создания/редактирования поста, то его можно смело вынести в отдельное место, где бы он никому не мешал. А мешать он может в случае если находился в классической таблице, например запрос select * каждый раз дергал бы сырой контент, что увеличило бы потребление памяти, особенно в случае если контент разбит на страницы, и страницы большого объема. Поэтому и для страниц придумана таблица, по тем же самым соображениям.

Далее я отказался от буферной таблицы - между постами и рубриками/метками. Классическое решение через таблицу пар пост-тег, которую бы использовали сразу две стороны - посты и рубрики/метки (точнее даже три стороны). Кажется мне, что делать дополнительные выборки на промежуточной таблице только терять время. Сделаю я текстовые поля в обоих таблицах с контентом в виде "2, 5, 10, 43" - то бишь id постов/рубрик/тегов в виде текста через запятую. Для sql будет работать конструкция вида select * from tags where id in tags где tags - это как раз и есть текстовая строка с id. Если в php охота поиметь массив то поможет explode(', ', $tags); Единственное узкое место - удаление одного из участников, придется делать примерно следующее:


$res = $db->query("select id, items from tagstable where id in tags");
foreach ($res as $row) {
$items = explode(', ', $row['items']);
if (is_int($i = array_search($postid, $items))) {
        array_splice($items, $i, 1);
$s = implode(', ', $items);
$sql .= "update tagstable set items = '$s' where id =  {$row['id']};\n";
}
}
$db->exec($sql);

Предположу, что подобный алгоритм будет работать значительно быстрее чем промежуточная таблица. К тому же мой опыт говорит, что операции удаления редки и не критичны по времени. Более того, мой алгоритм будет ненамного медленнее удаления через промежуточную таблицу, но зато намного быстрее при выборке постов для отображения, так как полностью исключает целую таблицу и запросы к ней. Далее соображение - текстовая строка с id будет реально короткой, так как в реальности не случаются посты даже с десятками тегами/рубриками. Таблица имела бы смысл если постов мульон и два мульона тегов, и каждый пост имеет полмульона этих тегов. В реальности такого нет и текстовая строка с id перекроет все потребности.