Продумывание архитектуры блога на своем самописном сайте.

Технологии и тематика
- Сферы деятельности: Архитектура сайта, Архитектура базы данных

Введение

Есть самописный сайт на котором хочется создать подобие блога и надо определиться с тем, как на нем будут выглядеть посты, как будет осуществляться навигация, поиск и связи между постами.

Поиск решения

1. Определиться с местом и видом вывода.
Хочется, чтобы на главной сайта отображались новейшие посты, это наверняка будут блоки состоящие из заголовка, даты и краткого описания, скорее всего краткое писание надо хранить отдельно, так как обрезать программно текст не очень хочется и не всегда возможно.
Так же нужен краткий перечень тегов, а возможно и перечень технологий и сфер, счетчик просмотров/комментариев и думаю рейтинга, почему бы нет.
В принципе внутри разделов возможен такой же вывод, так что либо главной страницей сайта станет раздел нового в блогах, либо должен быть некий виджет который можно будет запрашивать из других модулей сайта и который будет использоваться самим модулем блога.

2. Способы классификации материала.
Наверняка будут стандартные разделы для материалов блога, другой вопрос, что один материал может относиться сразу к нескольким сферам или темам. Есть ли признак, по которому один материал можно четко отнести к одной категории? После первых размышлений в голову приходят только виды деятельности. Разработка, изучение, обзоры и т.д. Но все это может быть подразделами в категориях по сферам применения. Веб разработка, системное программирование и т.д. На самом деле оба направления могут быть вложены друг в друга и получится дублирование подразделов в разных разделах. Значит надо определиться, что является первоочередным при выборе тематики постов, с чего чаще хотелось бы начать выбирать материалы? Видимо со сферы применения все же. Веб разработка это или может микрокомпьютеры. Тогда деятельность здесь может выступать в роли тега. Но остается проблема того, что сферы применения могут пересекаться. Тут в голову приходит такое. Для основной внутренней классификации, использовать тип статьи. Обучающий материал, рецензия, решение задачи и т.д. А для навигации создать отдельную сущность рубрика, тогда нам останется классифицировать материал, задав ему четкую позицию в классификаторе и привязать к нему рубрики, что позволит разместить его в нескольких тематических разделах на сайте.

3. Структура категорий
У категорий будет возможность задать родителя, что позволит создавать простое дерево материалов. Категории не должны будут повторяться в разных разделах. Если по логике охота запихать разделы с одинаковыми названия в разные категории, значит мы неверно выбрали свойство материала для его каталогизации, либо то что мы пытаемся запихать в разные разделы, должно стать тегом или рубрикой.

4. Тегирование и рубрицирование
На первый взгляд теги и рубрики имеют одно и тоже предназначение.
Но при мысли о тегах, это не систематизированные закладки о объектах которые упомянуты в материале. Php, mysql, webstorm. netbeans, windows и т.д.
А рубрики это систематизированное описание того, к чему относится материал. Веб разработка, проектирование базы и т.д.
С другой стороны теги тоже можно поделить на категории, например на языки программирование или среды разработки.
Выходит у нас есть тематики, каждая со своей иерархией, возможно даже цикличными связями. так может стоит добавить единственное поле теги, а собственно сами теги уже между собой классифицировать,
объединять в рубрики и тд? звучит вполне логично и открывает много возможностей для создания рубрикаторов.
Так как однажды созданные связи у материала с внешним миром, можно в последствии как угодно использовать.

5. Хранение тегов, навигация по ним
сами теги могут делиться на категории с подкатегориями. Это термины, сферы деятельности, сферы применения и т.д.
Выходит нам надо создать категории для тегов и впоследствии выводить теги из категорий для фильтрации по ним внутри основных разделов статей. Звучит убедительно и удобно.

5. Хранение материала
У материала исходя из всего этого и типичных вещей присущих материалу, должна быть такая информация:
Заголовок, категория, краткое описание, сам материал, теги, количество пометивших как полезное, комментарии, кол-во просмотров, дата создания, дата публикации.

я отбросил из этого списка рейтинг и заменил его отметкой полезное, так как рейтинг имеет больше смысла в ситуации с открытой площадкой, где любой желающий может размещать материалы и рейтинг нужен для ранжирования. в ситуации одного автора, отрицательный рейтинг скажет ровно столько же, сколько и низкое количество людей для которых это было полезно, здесь даже более важно получить отклик в комментариях, нежели оценку от 1 до 5 или простое указание, понравилось или нет. что не понравилось? почему? в случае с возможностью оценки, этого будет не узнать, а так, у читателя появляется необходимость выразить свое недовольство текстом, что намного полезнее, а вот у комментария уже может быть рейтинг, он позволит понять, был ли уместен комментарий с точки зрения других читателей или нет.

из всех полей, поля в которых предполагается хранение нескольких значений, лучше вынести в отдельную таблицу, если мы конечно говорим о реляционных таблицах вроде mysql, а не mongodb. Значит нам будет нужна таблица для хранения связей между тегами и материалами, таблица для комментариев к статьям, а также таблица хранящая какие пользователи пометили статью полезной, в самой статье мы будем хранить их количество, чтобы не делать лишних запросов, а обновлять мы его будем при добавлении и удалении из полезного соответственно.

6. Хранение связанных с материалом данных
у меня давно ходили мысли о том, чтобы иметь в системе отдельный компонент для хранения различных справочников, чтобы не требовалось создавать для каждого модуля свои компоненты по хранению различных справочников.
Но являются ли теги справочником? С одной стороны да, мы ведь можем в компоненте справочников создать собственно категории и по ним распихивать какие угодно списки чего либо, но как затем устанавливать, что конкретные справочники надо использовать в качестве тегов?
В принципе самим справочникам можно прилепить теги, что вроде логично, но вызывает рекурсии и усложнённость модуля который должен быть простым. да и зачем справочникам теги? у них должны быть конкретные идентификаторы, по которым ими могли бы пользоваться другие модули и они должны быть более того заранее известны.
Например города, страны, языки программирования и т.д. Если говорить о применимости тегов, то они могут быть у разных модулей разные, так что создавать справочник общих тегов тоже нет смысла, значит черт с ним с модулем справочников, создаем в модуле блога собственно модель категории тегов и модель тега.

С комментариями уже интересней, в данном случае требуется функционал комментирования и от модуля к модулю он будет отличаться разве что объектом, к которому он привязывается, вот здесь есть смысл задумать об отдельном модуле комментирования, который мы потом могли бы цеплять куда угодно и когда угодно без особых трудозатрат, так собственно и стоит сделать.

С пометками полезное тоже интересно, по сути это закладка для пользователя и чисто теоретически в эти закладки он может добавлять все что он посчитает нужным на сайте, а не только материалы. так что есть смысл реализовать функционал закладок в модуле пользователя и добавлять туда что-либо через методы этого модуля или даже модель самого пользователя. Здесь так же появляется необходимость в обратной связи для закладок, чтобы в случае удаления пользователем чего-либо из закладок, об этом сообщалось модулю, объект которого был удален. Тут либо система эвентов, либо колбеков. у меня в самописе есть система эвентов, так что я привяжусь к ней, но другим решением было бы хранить в записи о избранном объекте, модуль и метод, который следует вызвать в случае удаления из избранного. Хранить ссылку на объект в записи о избранном не всегда хорошо, так как ссылки могут меняться по тем или иным причинам, так что я создам в модели объекта, который будет добавляться в избранное метод getHref, который будет генерить ссылку на объект и собственно запрашивать его.

Решение

В итоге было принято решение создать модуль комментариев, добавить раздел избранное для пользователя и расширить модуль материалов.

Таблицы для материалов
materials_material
- name
- material_category_id
- short_description
- text
- user_favorite_count
- date_publish
- date_create

materials_material_category
- name
- parent_id

materials_tag
- name
- tag_category_id

materials_tag_category
- name
- parent_id

materials_material_tag
- material_id
- tag_id

Таблица для избранного
users_user_favorite
- object_model
- object_id
- date_create

Таблица для комментариев
comments_comment
- object_code
- object_href
- user_id
- text
- vote_up
- vote_down
- moderate_status
- date_publish
- date_create

Вывод

Попытки излишне группировать информацию либо объединять, зачастую будут провальные, невозможно предположить все разнообразие вариантов в которых она будет использоваться. Если списки заранее должны быть известны, да общие справочники — это наше решение, но если справочник будет наполняться по ходу наполнения контентом, то лучше сделать его персональным для модуля и больше нигде за пределами не задействовать.

Что касается описания своих действий в материале.
Вообще подобный способ описание хода своих мыслей позволяет лучше собрать их вместе и посмотреть на все со стороны, перечитать все что приходило в голову, отбросить бред и выделить ценные мысли. Особенно подведение итога даёт четко понять полученные результаты мозгового штурма и смотря на них уже внести корректировки в готовое решение, а не пытаться держать в голове все что надо сделать.