Таблицы постов в версии с бд
03.10.2009Встраиваю поддержку бд в посты. Неожиданно вытанцовывается три таблицы для постов: собственно классическая таблица с простынкой полей, таблица со страницами - если пост из нескольких страниц, то страницы будут хранится в отдельной таблице, и таблица для сырого контента - 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 перекроет все потребности.
Комментарии (10) на запись “Таблицы постов в версии с бд”
Оставить комментарий
Устанавливаю второй блог на тот же аккаунт хостинга, ставится нормально, но внизу страницы с паролем:
Warning: file_put_contents(/home//public_html/site.ru/data/cronchain.php) [function.file-put-contents]: failed to open stream: No such file or directory in /home//public_html/lib/filerclass.php on line 71
cronchain.php находится в /home/*/public_html/data/
Каждый раз прописывать пути было лень:
$paths['engine'] = '/home/*/public_html/';
$paths['lib'] = $paths['engine'] . 'lib' . DIRECTORY_SEPARATOR;
$paths['libinclude'] = $paths['lib'] . 'include'. DIRECTORY_SEPARATOR;
$paths['languages'] = $paths['lib'] . 'languages'. DIRECTORY_SEPARATOR;
$paths['plugins'] = $paths['engine'] . 'plugins' . DIRECTORY_SEPARATOR;
$paths['themes'] = $paths['home'] . 'themes'. DIRECTORY_SEPARATOR;
$paths['data'] = $paths['engine'] . 'data'. DIRECTORY_SEPARATOR . $domain . DIRECTORY_SEPARATOR;
$paths['cache'] = $paths['engine'] . 'cache'. DIRECTORY_SEPARATOR . $domain . DIRECTORY_SEPARATOR;
$paths['files'] = $paths['home'] . 'files' . DIRECTORY_SEPARATOR;
$paths['backup'] = $paths['home'] . 'backup' . DIRECTORY_SEPARATOR;
В cronclass.php;
$filename = $paths['home']. 'data' . DIRECTORY_SEPARATOR.'cronchain.php';
правильно:
$filename = $paths['data'] . DIRECTORY_SEPARATOR.'cronchain.php';
или может для каждого домена свой крон нужен?
Сделал бэкап блога, в постах поменял оформление ссылок, закачиваю обратно на сервер:
Fatal error: Unsupported operand types in /lib/kernel.php on line 156
на всех страницах.
Восстановился из бэкапа на сервере.