Как правильно хранить контент поста?

Суть следующая - необходимо хранить контент поста в бд (используется laravel)
Посты будут создаваться в админ панели через динамичный генератор. Необходимо учитывать порядок содержимого (заголовки, оглавление, изображение и т.д), так как нек-ые из элементов могут отсутствовать или иметь разный порядок.
Хранить html код в столбце поста кажется нецелесообразным по ряду причин:

  • Лишняя трата памяти на хранение html тегов
  • Уменьшение производительности (?)
  • Стили/компоненты могут изменяться, а код останется прежним

Придумано два варианта решения:

  • Использовать собственные минифицированные теги, благодаря которым определенный парсер будет воссоздавать нужные блоки с помощью компонентов (возможно динамичесих)
  • Хранить каждый элемент поста отдельно в бд со следующим содержанием (element_name, position, content, post_id), используя отношения к родительскому посту, соответственно сохранится структура и рендериться пост будет через соответствующие компоненты в нужном порядке (однако как будет именно рендериться в шаблоне поста пока неизвестно)

Вопрос следующий: насколько второй подход имеет место быть, и если нет, то какие есть best practices для подобных случаев (как это реализуется в крупных проектах?)

Дополнительно:

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

  • Неизвестный Пользователь, нормальный подход. Сборная страница из небольших блоков.
    Тут сложнее удобную админку для конструктора страницы сделать.
  • Контент удобно хранить в чем-то вроде BBкодов. Соответственно, парсер HTML в коды и парсер в обратную сторону для отображения. В реальности, это означает, что в табличке хранятся BB "исходники" и html контент, который отрендерен в текущих стилях, для быстроты отображения. Сам принцип удобен тем, что коды ничем не ограничены, если что-т не хватает - можно придумать еще один код, многие wysiwyg редакторы сами могут выдавать код с BB и билдер в html делается регулярками на коленке. Это про контент поста. Сулужебную обертку уже можно хранить как будет удобнее.

    Что такое пост? Отдельная страница сайта или отдельный пост, типа новости, или сообщения, которую можно влепить куда угодно?

  • ksnk, отдельная динамическая страница статьи. у самого поста хранится название, краткое описание, которые можно дернуть и вставить в любое место, это без проблем, а вот с динамической генерацией отдельной страницы возник такой вопрос, ибо нужно учитывать порядок, плюс связать все это с компонентами
  • Экономия на спичках. Я бы тупо хранил html в бд. Это посты, там не должно быть сложных конструкций. Видосы, картинки и так далее хранить в файлах, а в постах тупо тэги вставок со ссылками в нужных местах. Посмотри как в популярных CMS сделано, например, WordPress. Он хранит так как я предложил, тупо html.
    Скрин wordpress

    Как правильно хранить контент поста?

  • irishmann, как раз по идее реализация первого подхода
  • irishmann, Ну, я бы посмотрел, как неочищенный html из ворда, к примеру, будет отображаться при смене стилей сайта. Прелесть независимого формата в независимости.
  • Согласен с пользователем выше, требуется универсальный подход, без строгих зависимостей между собой
  • Давно уже придумали блочные редакторы типа Sir Trevor.
  • JhaoDa, вопрос насчет проектирования, а не конкретной реализации
  • Неизвестный Пользователь, что ты хочешь проектировать? Конент хранится как json, ты его потом рендеришь. Первый вариант, только без каких-то «минифицированных тэгов».
  • делал подобный конструктор постов
    по кнопкам добавлял нужные блоки
    при сохранении собирал инфу по блокам в json (тип блока, его текст, картинка и т.п)
    json сохраннялся в базу
    на стороне клиента json парсился в блоки и можно было задать любую структуру для блока
    в админке для редактирования в конструктор тоже загружался json и строились блоки
  • ksnk, это уже другая задача. Ее можно решить через wysiwyg редактор, преобразовав или вырезав ненужные тэги до того как запись попадет в БД. Как я уже выше писал, это посты, в них не должно быть сложных конструкций, тем более атрибутов style.
  • JhaoDa, с json проблема остается той же - память, лишняя зависимость, парсинг json занимает лишнее время, излишняя абстракция.
    упоминал выше - отдельные элементы должны рендериьтся через компоненты, sir trevor (глянул в докум.) - хранит в json и html, что уже намекает о противоречии. помимо того тащить еще один редактор в проект не вижу смысла. вам советую отвечать более сдержанно, однако насчет sir trevor спасибо, возможно пригодится в других проектах.
  • Неизвестный Пользователь, не совсем понятно как хранение в json выиграет у минифицированных тегов. Я как то не уверен что парсер json будет справляться с задачей хуже чем ваш парсер минифицированных тегов. Да и что с памятью? Абстракция - а минифицированные теги не абстракция? При этом выгрыши понятны - json это стандарт с поддержкой везде где только можно.
  • Неизвестный Пользователь, не понятно почему блоки контента у вас "двигаются"? Что за контент такой?
  • ksnk, ну зачем рассматривать терминальные стадии. То что word делает из связки css+html что то неудобоваримое - не говорит о том что при нормальном использовании менять кардинально менять вывод у одного и того же html кода - не проблема. https://www.csszengarden.com/ тому пример. Хоть ему уже и 100 лет в обед
  • Дмитрий, выиграет, ибо любое сжатие данных до более примитивных, даст результат.
    но, имеет ли это смысл, в этом то вопрос.
  • Неизвестный Пользователь, [h]Header[/h] выиграет у {"h":"Header"}? Ага один байт. А если у вас в БД какой нибудь постгресс то как только строка вывалится за размер дата блока - а это скорее всего произойдет - если у вас там посты, она улетит в Toast и будет хранится в сжатом виде. И экономию вы разглядите только в микроскопе.
  • Дмитрий, Абстрактная разметка лучше чем очищенный html тем, что для html появляется желание сэкономить на парсинге исходников при смене стилей. К примеру у нас есть набор страниц. На каком то этапе жизни сайта поступило предложение выводить контента поменьше и влепить кнопку "читать дальше". Решением будет довольно тупо посчитать текстовую длину контента и примерно посчитав, воткнуть кнопку в подходящее место. Для клинически непросчитываемых случаев - явно указать место расположения кнопки. Для ББ кода - это еще один код, вставленный в текст. Для html появится желание обойтись без дополнительного парсинга исходников и вставить кнопку как есть, со стилями и скриптом, или хотя бы с классами. Собственно, cама возможность вставки элементов с непредсказуемыми зависимостями и будет "хуже".
  • ksnk,

    Для ББ кода - это еще один код, вставленный в текст. Для html появится желание обойтись без дополнительного парсинга исходников и вставить кнопку как есть, со стилями и скриптом, или хотя бы с классами.

    Открою мааааленький секрет: Практически все тексты обрабатываются перед выводом. Некоторые для той же вставки рекламы, некоторые для обработки какого-то функционала, который никак кроме обработки метаинформации по другому не вставишь, некоторые именно для парсинга чего-то типа ббкодов(например если это непремодерированные данные от пользователей). Просто если данные введены из надежного источника и содержит готовый отформатированный хтмл, обработка становится в разы проще, например не нужны регулярки на каждый чих, можно просто найти нужный тег и заменить его на что-то другое стр_реплейсом... По этому никто не будет соблазняться вставкой кнопки в текст.

  • ksnk, Хоть я и не фронт ни разу - но решить эту проблему вставки кнопки и ограничения видимости через средства css мне кажется не сложным. От желания сэкономить на спичках и влепить какую нибудь фигню - не спасет ничего. и уж абстрактная разметка точно. А псевдокод так и усугубит - сначала у вас вместо button появится redButton и bluButton потом кто нибудь родит гениальную мысль а пусть кнопки будут с классами [redButton class="with-border"] регулярку по обработке этого заменят на какой нибудь конечный автомат, и ой у нас вообщем то парсер браузера уже получается. Разница только что все это дерьмо будет лежать на плечах разработчиков - и при смене команды разработка превратится в набор шаманских практик - ибо хрен там кто знает чего и как. А вот с html, c xml, с json будет вагон инструментов - которые умеют с этим стандартами работать и внезапно любой взятый с улицы будет иметь какое то представление о html, css и прочем
  • Ответы:

    Хранить html код в столбце поста кажется нецелесообразным по ряду причин:

    Угу, ага...

    Лишняя трата памяти на хранение html тегов

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

    Уменьшение производительности (?)

    Производительности чего?

    Стили/компоненты могут изменяться, а код останется прежним

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

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

    Ага, переизобретаем BBCode, найс... Для понимания проблемы - такие коды придуманы для форумов, с целью ограничить использование хтмл в пользовательском вводе. При этом подходе он худо-бедно оправдан, хотя и требует постобработки при каждом выводе, а это использование регулярок, что как бы совсем не бесплатно. В вашем же случае, источник текста более-менее доверенный, и ограничение в тегах больше мешает чем помогает.
    Что касается экономии на "минифицированных" тегах, ну допустим сэкономите вы 100 байт на тегах, то есть на 1000 постов экономия будет.... ТА-ДАААМ! 0,1 мегабайта! А если экономия 1000 байт на пост, то целый МЕГАБАЙТ можно сэкономить! Похвальная рачительность.

    Хранить каждый элемент поста отдельно в бд со следующим содержанием (element_name, position, content, post_id), используя отношения к родительскому посту, соответственно сохранится структура и рендериться пост будет через соответствующие компоненты в нужном порядке (однако как будет именно рендериться в шаблоне поста пока неизвестно)

    Базовые элементы и так должны храниться отдельно, другой вопрос почему они у вас рендерятся в одном порядке, а в другом месте в другом порядке? Заголовок, короткое описание, текст, главное изображение - отдельные поля, оглавление по сути часть текста, зачем его выносить отдельно - загадка, это же такой же текст, котрый автор волен располагать . Вариант с внешней таблицей по сути приводит нас к выносу части данных в EAV(отличный пример универсализации в ущерб производительности), что как раз будет серьезно напрягать выборки бд, если понадобится делать какие-либо поисково-выборочные манипуляции по этим данным.

    • не до конца корректно составлен мной вопрос из-за чего есть недопонимания, но насчет последнего вы правы. именно универсализация и планировалась.
      насчет лишних выборок тоже понимаю.
      если речь о порядке, то разные посты могут содержать разное количество тех же самых заголовков (именно заголовки части контента, подзаголовки, подпункты, etc), которые могут находиться в произвольных местах. естественное дело, учитывать структуру необходимо.
      видел также пост на хабре, где человек ровным счетом также хранил html код, перешел на подход похожий на второй, количество хранимой информации уменьшилось в 4 раза (имхо, разница отличная).
      главная суть - не хранить html в бд, для описания структуры использовать отдельную таблицу с описанием расположения конкретного элемента в порядковом номере. рендер - на отдельном самописном сервисе.
      вроде бы повторил тоже самое, но что ДЕЙСТВИТЕЛЬНО хотелось бы узнать - стоит ли это применять или нет. если нет - узнать почему нет (а если речь о памяти/производительности, то речь о цифрах), и, понятное дело предложить другой подход.
      надеюсь описал более менее понятно, спасибо
    • Неизвестный Пользователь,

      насчет лишних выборок тоже понимаю.

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

      если речь о порядке, то разные посты могут содержать разное количество тех же самых заголовков (именно заголовки части контента, подзаголовки, подпункты, etc), которые могут находиться в произвольных местах. естественное дело, учитывать структуру необходимо.

      То есть "заголовки" не будут плавать и прочие блоки не будут плавать внутри контента выше-ниже, а просто будут иметь другой вид? Условно у вас есть название статьи, главная картинка, шорт дескрипшн, и неизменный текст статьи, элементы внутри которого просто стилизованы по разному? Не находите что проще задать им 8 тегов и забыть про какие-то там разбиения? Тем более что и семантически это положительно отразится на контенте, и краткость по сравнению с вашими шорттегами не ухудшится (например что вы там насокращаете в тегах <h1>,<h2>,<h3>?.. Ну или сократите <span> до [sp]?..).

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

      Во первых накладные расходы на создание дополнительных записей и индексов сожрет сильно больше места, во вторых уверен что подход был похожий, но не такой, и в третьих - возможно что хтмл у товарища занимал СИЛЬНО больше места чем требовалось для обычного поста, то есть это были скорее всего совершенно другие данные. В вашем случае я привел экономию, если у вас тегов ОЧЕНЬ много, возможно вы выгадаете НЕМНОГО больше места чем описано у меня(вам все равно придется как-то обозначать все теги которые вы меняете, и это не сократит ВЕСЬ текст в 4 раза никак), но СИЛЬНО потеряете в производительности.

    • ThunderCat,

      То есть "заголовки" не будут плавать и прочие блоки не будут плавать внутри контента выше-ниже, а просто будут иметь другой вид? Условно у вас есть название статьи, главная картинка, шорт дескрипшн, и неизменный текст статьи, элементы внутри которого просто стилизованы по разному?

      не до конца понимаю, что вы имеете в виду под "плавать".
      речь только о структуре. допустим на странице одного поста:

      На странице другого поста:

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

    • Неизвестный Пользователь, то есть все сводится к иному хранению структуры, последовательности, чтобы и не хранить html лишний, и чтобы рендером занимался отдельный компонент, который можно будет всегда изменить, и соответственно блоки не будут зависеть от html, изменил компонент - изменился вывод всех зависимых элементов. с обычным html так не выйдет - в бд уже будет храниться строгий html, соответственно для изменений придется вносить изменения в КАЖДЫЙ пост (и речь не о стилях, а о разметке)
    • Неизвестный Пользователь,

      Отдельные элементы одинаковые, соответственно можно использовать компоненты для того чтобы избежать дублирования кода.

      И какие элементы у вас тут одинаковые? И где вы увидели дублирование кода???

      Ваша ошибка в том, что вы воспринимаете форматированный текст как нечто программное, хотя это абсолютно не так. ВАЖНО отделять данные от кода и поручать СТИЛИЗАЦИИ работу по визуальному оформлению. А вы взялись за непонятную борьбу против мнимого дублирования.

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

      То есть для какого-то блока у вас будет допустим выравнивание вправо, и вы будете создавать элемент с типом алигн_райт, прописывать его в новом ббкоде, а потом заменять его регулярками на элемент с классом алигн_райт? Не кажется проще сразу задать разметку с нужным стилем? Все современные wysiwyg редакторы поддерживают такое форматирование в один клик.

      И тут либо bb коды, либо использовать совершенную другую логику.

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

    • блоки не будут зависеть от html, изменил компонент - изменился вывод всех зависимых элементов. с обычным html так не выйдет - в бд уже будет храниться строгий html, соответственно для изменений придется вносить изменения в КАЖДЫЙ пост (и речь не о стилях, а о разметке)

      Пример плс, а то что-то я не догоняю, как может поменяться "компонент" настолько, что поможет только его переписывание??? И чем поможет в этом случае ббкод?

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

    20 лет назад этот вопрос был полнонстью решен с помощью технологий XML/XSLT/XPath.
    Языки C#/dotNet, Java поддерживают этот стек. И много других языков и библиотек.

    Потом еще создавали более простые вещи. Шаблонизаторы. Velocity, FreeMarker. Они немножко
    переворачивают постановку. Но их тоже можно рассмотреть.

    Хранить html код в столбце поста кажется нецелесообразным.

    С точки зрения суммарной стоимости владения (TCO) база данных всегда будет дороже
    чем файловая система. А самым дешевым будут хранилища типа Amazon S3, MS Blob, G-Drive.
    Ну если пересчитать удельно сколько стоит гигабайт.

    Хранить каждый элемент поста отдельно в бд со следующим содержанием (element_name, position, content, post_id),

    Тут - непонятно. Но есть такое эвристическое правило дизайна
    хороших NoSQL систем. Все данные для запроса должны лежать физически рядышком
    и не требовать дополнительных действий
    . В идеале - для отдачи поста вы должны сделать
    один единсвтвенный SELECT без joins и без подзапросов и агрегаций и без CONNECT-BY.

    • С точки зрения суммарной стоимости владения (TCO) база данных всегда будет дороже чем файловая система. А самым дешевым будут хранилища типа Amazon S3, MS Blob, G-Drive. Ну если пересчитать удельно сколько стоит гигабайт.

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

    • благодарю

     

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

     

      • Как правильно хранить контент поста?Есть ответ
      • 07.04.2024
      Ответить

      Для хранения контента поста на сайте можно использовать различные подходы, в зависимости от особенностей проекта и требований к хранению данных. Ниже приведу несколько основных способов хранения контента поста:

      1. Хранение в базе данных:
      Один из наиболее распространенных способов хранения контента поста - это хранение его в базе данных. Для этого можно создать таблицу, в которой будут храниться все данные поста, такие как заголовок, текст, автор, дата создания и другие метаданные. При этом важно правильно спроектировать структуру базы данных, чтобы обеспечить эффективное хранение и быстрый доступ к данным.

      Пример хранения контента поста в базе данных с использованием языка PHP:

      2. Хранение в файловой системе:
      Другим способом хранения контента поста может быть сохранение его в файловой системе сервера. В этом случае каждый пост может быть представлен отдельным файлом, в котором будет содержаться весь контент поста. Этот способ удобен для небольших проектов или при необходимости быстрого доступа к контенту.

      Пример хранения контента поста в файловой системе с использованием языка PHP:

      3. Хранение в облачном хранилище:
      Также можно использовать облачные хранилища для хранения контента постов. Этот способ удобен для масштабируемых проектов и обеспечивает высокую доступность данных. Для работы с облачными хранилищами можно использовать API соответствующего провайдера.

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

    Оставить комментарий