Сайт - его контент, админка и что делать

Я давно думаю о том, что хранение контента сайта в реляционных базах данных не всегда удобно. Также я думаю о том, что NOSQL имеет огромный ряд недостатоков, например, один из которых - организация связи многие ко многим. Это порождает большие накладные расходы и требует уделять подобным мелочам достаточно много внимания, а мы ведь хотим сосредоточиться на том, что по настоящему важно для нас. Я попробую для начала разложить всё по полочкам в первую очередь для себя.

На самом деле это всего лишь мысли том, как правильно нужно хранить контент, что такое билдеры сайтов, и почему билдеры всегда будут уступать ручному кодированию.

Мне кажется стоит начать рассматривать этот вопрос с самого частого частного случая - лендинга. Очень часто компании ограничиваются лендингами, вместо полноценного сайта. Или например они делают какой-то продукт и пользователей нужно приземлить на "посадочную" страницу, где будет описаны услуги, или товары.

Предположим мы имеет баннер, в котором есть заголовок, подзаголовок. Баннер имеет фоновую картинку, которую мы хотим например менять в админке. Ну вот условия такие. А ещё справа в квадратике у нас перечислены преимущества в виде простого списка строк.

Если мы рассматриваем сайт в контексте секций (горизонтально разделённые блоки сайта, например, меню навигации, баннер, секция "о нас", секция "цены"), то мы сможешь записать следующие поля для нашей секции.

  • Заголовок
  • Подзаголовок
  • Некий коротки текст или слоган
  • Изображение
  • Список преимуществ

Впринципе всё понятно. Мы имеет для нашей секции подробную структуру данных. Структура данных в данном случае представляет собой поля, которые имеют определённый тип.

  • строки
  • числа
  • длинные строки (много текста) 
  • длинные строки с html кодом
  • файлы (на самом деле не сами файлы, а путь к файлу),
  • иконки (возможно это файл, или некий SVG, хранящийся в строке)
  • списки (или массив, кому как больше нравится)

Вообще все предельно просто. Мы тут описали как бы любую реляционку. Можно предположить, у нас есть таблица, а её поля могут быть разных типов и тд. Последний  тип меня интересует больше всего. Это список строк. На самом деле список может быть не только строк. Список может быть "объектов", чисел и тд. Это немного усложняет Нашу модель.

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

На самом деле тут можно было бы сказать, а давайте использовать NOSQL, и Вы несомненно были бы правы. Они могут хранить иерархические данные, но это нужно подключать NOSQL. А если реляционка уже есть, придётся всё это интегрировать. Давайте пока остановимся на реляционке.

Есть и альтернативное решение. Почему бы наши секции нам не хранить скажем в JSON? Тогда мы можем хранить наш json в текстовом поле и выглядеть это будет примерно так.

{
	"title": "Hello, site",
	"subtitle": "I am very smart website",
	"description": "How are you? I am find. I am still smart site",
	"advantages": [
		"advantage 1",
		"advantage 2",
		"and one"
	]
}

Ну вроде тут всё хорошо. Это удобно. Пихаем всё это в таблицу и нам остаётся только сделать интерфейс для изменения подобных данных. Но как же поиск по полю? А вот с поиском могут быть уже проблемы. 

Как решить проблему поиска, если информация храниться в JSON в реляционной базе данных.

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

Вроде мы решили нашу проблему. Мы храним данные в базе, мы можем даже искать по ним. Но возникает другой вопрос. На этапе разработки мы должны определить все структуры данных для секции. То есть мы уже должны иметь json, с некими тестовыми или изначальными данными. Это всё нужно где-то хранить. Что нужно хранить:

  1. Структуру данных секции
  2. Изначальные данные (данные в качестве примера, возможно, тестовые данные)
  3. Как этот этот JSON будет выводиться то? Или мы просто так отдадим клиенту JSON и пусть сам фантазирует как это должно выглядеть?

Ну впринципе здесь уже напрашиваются архитектурные вопросы. Можно создать несколько классов, которые будут отвечать за всё это. Допустим у нас есть класс секция. Тогда какие бы методы и проперти мог бы иметь этот класс?

  1. Темлейт для вывода, может какая-то view. Это может быть метод render.
  2. Какая структура данных соответствует текущему виджету? Структуру данных можно хранить в коде, или же динамически менять в базе данных
  3. Где взять изначальные данные? Возможно JSON файл (ведь мы можем сериализовать любую структуру данных)

И какие проблемы ещё нужнго будет решить? Я попробую просто предположить эти проблемы

  1. Структура виджета изменилась, а данные в базе остались прежними - что будет делать виджет? Нужна какая-то безопасная система извлечения данных для виджета из данных
  2. Могут ли виджеты с теми же данными выводиться по разному? Может быть вывод или темплейт этих виджетов зависит от контекста?ъ
  3. Продолжение следует...