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

12

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

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

В прошлом я пробовал много других проектов, таких как включение нескольких строк в таблицу домашней страницы и выбор одного из них наугад. Я попытался добавить логическое поле с именем «active» и выбрать одну из активных домашних страниц наугад. Я попытался заставить только одну строку быть активной в любой момент времени в логике приложения. Я даже не пытался создать таблицу домашней страницы и иметь все другие элементы, например статьи, чтобы иметь логические поля с именами, такими как featured_on_homepage.

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

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

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

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

Ответы:

10

Один из простых подходов - сохранить свойства домашней страницы в таблице свойств (или назвать ее как-нибудь еще), которая состоит из столбцов «имя и значение».

HomePageProperty1 - UserValue1

HomePageProperty2 - UserValue2

Возможно, это не идеальное решение, но оно простое и гибкое. Это также устраняет таблицу с одной строкой сценария.

Вальтер
источник
1
Этот подход работает для нескольких целей. Например, я буду хранить информацию о версии схемы, указатели поворота для вещей, которые нужно циклически повторять ежедневно, и т. Д. Информация о версии схемы важна при диагностике неисправности. Это разумный способ обеспечить применение патча для исправления только для базы данных.
Берин Лорич
2
+1 - это точный макет таблицы, который наш Data Architect дал мне для аналогичной цели.
Али
3
Проблема этого подхода заключается в том, что вам нужно представлять разные типы переменных как разные столбцы и иметь логику, чтобы указать, какой столбец использовать, а какой - обязательный. Вы не можете определить, что логическое значение является логическим, или что дата является датой, или что конкретный атрибут не может быть нулевым, или должен попадать в определенный диапазон или соответствовать условию - все вещи, которые являются тривиально простыми с одной строкой таблицы.
Дэвид Олдридж
3

Мне не ясно, что у вас есть проблема, которую вам нужно решить.

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

Я не уверен, что вы пытаетесь решить реальную проблему, если честно.

Дэвид Олдридж
источник
2

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

Ваше описание напоминает мне много вики-страниц, где пользователи могут редактировать контент. В вики или, по крайней мере, в тех реализациях, которые я видел, страницы сохраняются в виде файлов.

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

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

MichelHenrich
источник
2

В таблице с одной строкой нет ничего плохого.

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

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

Да, я не только говорю, что таблица с одной строкой в ​​порядке, но я полагаю, что вам может потребоваться более одной из них.

Джон Ву
источник
1

Вы можете создать таблицу с именем STATIC_CONTENT и иметь столбцы для ключа, а также контент, активные / неактивные трекеры и т. Д. Затем создайте строку с ключом «HomePage» и на своей домашней странице загрузите статический контент для этого ключа. и отобразить это. Таким образом, когда у вас есть другой статический контент (о странице, странице контактов и т. Д.), Вы можете добавить строки в эту таблицу.

RationalGeek
источник
1

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

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

JacquesB
источник
0

Просто чтобы добавить к Уолтеру ..

Структура таблицы свойств должна разрешать несколько типов данных.

Fileds:
PropertyName
PropertyTextValue
PropertyDateValue
PropertyNumericValue
PropertyBoolValue
Идиоты
источник
При этом, как вы можете гарантировать, что в строке указывается только одно значение свойства? Внедрить его в приложение достаточно просто, но что если кто-то обновит базу данных вручную и вставит туда некоторые данные?
Apreche
0

Мне кажется, вы могли бы абстрагироваться еще на один уровень. В конце концов, «Домашняя страница» - это «Страница». Вы можете иметь разные типы страниц с нужными вам свойствами. Если у вас есть разделы на вашем сайте, вам, вероятно, понадобится «SectionHomePage», который может очень хорошо работать так же, как «Домашняя страница».

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

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

PAGES
Id
Title
Description

HOMEPAGES
PageId (FK)
PhotoListLimit
ArticleListLimit
TextBlockListLimit

ARTICLEPAGE
PageId (FK)
ArticleMainQuote
ArticleMainBody
ArticlePhoto1
ArticlePhoto2

Это будет хорошо работать для меня, даже отлично подойдет для большого сайта.

Хуан Карлос Эдуардо Ромайна Ас
источник