Найкращий спосіб моделювати синглтон у реляційній базі даних


12

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

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

Раніше я пробував багато інших конструкцій, таких як допуск декількох рядків у таблиці домашньої сторінки та вибір навмання. Я спробував додати булеве поле з назвою "активний" і вибрав одну з активних домашніх сторінок навмання. Я намагався змусити лише один рядок бути активним в будь-який момент часу в логіці програми. Я намагався навіть не робити таблицю домашньої сторінки та мати всі інші елементи, такі як статті, щоб бути булевими полями з іменами типу Featured_on_homepage.

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

На багатьох сайтах у мене немає цієї проблеми, оскільки я можу будувати такі речі, як домашня сторінка, із запитом, таким як вибір п'яти найновіших статей. Але коли у мене є сторінки, які вручну підготовлені із суворими вимогами, стає складно моделювати її в базі даних. Але уявіть, у вас є таблиця фотографій та таблиця статей. Вимога полягає в тому, що на домашній сторінці відображатиметься рівно п’ять фотографій, рівно три статті та два блоки довільного тексту, керованого користувачем вручну. Як ви моделюєте це в базі даних правильним способом?

Крім того, у мене є проблема моделювання в багатьох інших випадках, окрім лише домашніх сторінок. Це просто найпростіший і загальноприйнятний приклад, який я міг придумати.


Зовсім не зрозуміло, яку проблему представляє вам таблиця з одним рядком, окрім того, що вона певним чином являє собою марнотратство таблиці. Ви впевнені, що намагаєтесь вирішити проблему, від якої насправді страждаєте?
Девід Олдрідж

Відповіді:


10

Одним із простих підходів було б збереження властивостей домашньої сторінки в таблиці властивостей (або називати її чимось іншим), що складається з стовпців Ім'я та значення.

HomePageProperty1 - UserValue1

HomePageProperty2 - UserValue2

Це може бути не ідеальним рішенням, але воно є простим і гнучким. Він також виключає таблицю з одним сценарієм рядків.


1
Цей підхід працює в декількох цілях. Наприклад, я зберігатиму інформацію про версію схеми, покажчики повороту на речі, які потрібно щодня переключати тощо. Інформація про версію схеми важлива при діагностиці того, що пішло не так. Це розумний спосіб забезпечити застосування патча для виправлення лише для бази даних.
Берін Лорич

2
+1 - Це точний макет таблиці, який дав мені наш архітектор даних для подібної мети.
Алі

3
Проблема такого підходу полягає в тому, що вам потрібно представляти різні типи змінних як різні стовпці і мати логіку, щоб повідомити, який стовпець використовувати, а який обов'язковий. Ви не можете визначити, що булеве значення булеве або що дата є датою, чи певний атрибут не може бути недійсним, або повинен потрапляти в певний діапазон або відповідати умові - всі речі, які тривіально прості з єдиною таблицею рядків
Девід Олдрідж

3

Мені не ясно, що у вас є проблема, яку потрібно вирішити.

Однорядкова таблиця жодним чином не є проблемою для самої бази даних і дозволяє застосовувати типи даних і обмеження до даних.

Я не впевнений, що ви намагаєтесь вирішити справжню проблему, чесно кажучи.


2

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

Ваш опис мені нагадує багато сторінок Вікі, де користувачі можуть редагувати вміст. У Вікісховищі або, принаймні, у реалізаціях, які я бачив, сторінки зберігаються як файли.

Це допомагає вам з іншими деталями веб-сторінок, наприклад, дозволяючи вашим користувачам кешувати вашу домашню сторінку, що виходить практично безкоштовно, якщо ви зберігаєте сторінки як файли, але вам доведеться вручну реалізувати логіку недійсного кешу, якщо ви будуєте Сторінка кожного запиту на основі вмісту, що зберігається в базі даних.

У будь-якому випадку, я просто хочу дати зрозуміти, що хоча більшість постійних даних програми зберігаються в базі даних, це не означає, що ми повинні зберігати все там. Бази даних - лише один із інструментів нашої торгівлі. Ми повинні навчитися добре використовувати якомога більше різних інструментів.


2

Немає нічого поганого в таблиці з одним рядом.

Якщо це частина вашої конструкції, вам слід її виконати. Надайте таблиці стовпець ідентичності, надайте йому обмеження унікальності, а потім додайте обмеження стовпця, щоб дозволити лише одне значення. Це забезпечить, що ніхто не зможе додати другий рядок, що може бути катастрофічно, якщо у операторах SQL, які читають таблицю (зрозуміло), немає пункту де.

Якщо ви почнете отримувати велику кількість стовпців, ви можете спокусити звузити таблицю і натомість мати один рядок на елемент конфігурації. Це не найкраща ідея, оскільки ви втрачаєте безпеку та перевірку типу. Крім того, ви втратите вперед сумісність із багатостороннім життям , що може бути для вас важливим. Кращим рішенням буде переосмислити, якими є насправді ваші сутності, і створити окремі однорядкові таблиці для різних об'єктів.

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


1

Ви можете створити таблицю під назвою STATIC_CONTENT і мати стовпчики для ключа, а також вміст, активні / неактивні відстежувачі тощо. і відобразити його. Таким чином, коли у вас є інший статичний вміст (про сторінку, сторінку контактів тощо), ви можете додавати рядки до цієї таблиці.


1

Сам по собі немає нічого поганого в тому, щоб мати таблицю з лише одним рядком. Якщо у вас є лише один примірник певної сутності, то це, можливо, буде найбільш природним способом представити це.

Але вибрати рядок випадковим чином - неправильно і погано. Якщо ваша доменна логіка очікує лише одного рядка, очевидно, помилка в даних, якщо насправді їх більше. Тож вам слід з’ясувати, хто чи що записує неправдиві дані в базу даних і не допускати їх до цього! Залежно від бази даних, ви, ймовірно, можете додати обмеження в таблицю, щоб уникнути цього в першу чергу, наприклад, дозволяючи лише певне значення в якості основного ключа.


0

Просто додати до Вальтера ..

Структура таблиці властивостей повинна містити кілька типів даних.

Fileds:
PropertyName
PropertyTextValue
PropertyDateValue
PropertyNumericValue
PropertyBoolValue

З цим, як ви гарантуєте, що в одному рядку встановлено лише одне значення властивості? Це досить просто застосувати це в додатку, але що робити, якщо хтось потім оновлює базу даних вручну і вставляє там деякі дані?
квітня

0

Мені здається, що ти міг би абстрагуватися ще на один рівень. Зрештою, "Домашня сторінка" - це "Сторінка". Ви можете мати різні типи сторінок із потрібними вам властивостями. Якщо у вас були розділи на вашому веб-сайті, можливо, вам знадобиться "SectionHomePage", який може дуже добре працювати як "Домашня сторінка".

Вимога полягає в тому, що на домашній сторінці відображатиметься рівно п’ять фотографій, рівно три статті та два блоки довільного тексту, керованого користувачем вручну. Як ви моделюєте це в базі даних правильним способом?

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

PAGES
Id
Title
Description

HOMEPAGES
PageId (FK)
PhotoListLimit
ArticleListLimit
TextBlockListLimit

ARTICLEPAGE
PageId (FK)
ArticleMainQuote
ArticleMainBody
ArticlePhoto1
ArticlePhoto2

Це було б добре для мене, навіть було б чудово для великого сайту.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.