Использование таблицы конфигурации с одной строкой в ​​базе данных SQL Server. Плохая идея? - PullRequest
137 голосов
/ 20 февраля 2010

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

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

Как правильно хранить эту информацию?

Примечание: моя СУБД - это SQL Server 2008, а уровень программирования реализован на ASP.NET (в C #).

Ответы [ 12 ]

176 голосов
/ 20 февраля 2010

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

Одиночная строка

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

Пара ключ / значение

  • положительно: добавление новых настроек не требует изменения схемы
  • положительный: схема таблицы узкая, с дополнительными строками для новых настроек
  • минус: каждая настройка имеет одно и то же значение по умолчанию (ноль / пусто?)
  • отрицательно: все должно храниться в виде строк (т.е. nvarchar)
  • отрицательно: при работе с настройками в коде вы должны знать, какой тип является настройкой, и приводить ее

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

Единственное, что меня беспокоило при использовании этого подхода, - это наличие нескольких строк в «специальной» таблице настроек для одной строки. Я преодолел это (в SQL Server):

  • добавление нового битового столбца со значением по умолчанию 0
  • создание проверочного ограничения, чтобы этот столбец имел значение 0
  • создание уникального ограничения для битового столбца

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

10 голосов
/ 20 февраля 2010

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

6 голосов
/ 20 февраля 2010

Один ряд будет работать нормально; у него даже будут сильные типы:

show_borders    bit
admin_name      varchar(50)
max_users       int

Один недостаток заключается в том, что для добавления нового параметра требуется изменение схемы (alter table). Один из вариантов - нормализация, в результате чего вы получите таблицу типа:

pref_name       varchar(50) primary key
pref_value      varchar(50) 

Это имеет слабые типы (все это varchar), но добавление нового параметра - это просто добавление строки, то, что вы можете сделать с помощью только доступа к записи в базу данных.

4 голосов
/ 20 февраля 2010

Лично я бы сохранил это в одной строке, если это то, что работает. Чрезмерно хранить его в таблице SQL? возможно, но в этом нет никакого реального вреда.

3 голосов
/ 22 марта 2011

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

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

3 голосов
/ 20 февраля 2010

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

Удобный способ хранения информации о конфигурации и / или предпочтениях пользователя - в XML . Многие СУБД поддерживают тип данных XML. Синтаксис XML позволяет вам использовать «язык» и структуру, описывающую конфигурацию по мере ее развития. Одним из преимуществ XML является его неявная поддержка иерархической структуры, позволяющая, например, хранить небольшие списки параметров конфигурации, не называя их суффиксами с номерами. Возможный недостаток формата XML заключается в том, что поиск и, как правило, изменение этих данных не так просты, как другие подходы (ничего сложного, но не столь простого / естественного)

Если вы хотите остаться ближе к реляционной модели , модель Entity-Attribute-Value , вероятно, то, что вам нужно, при этом отдельные значения сохраняются в таблице, которая обычно выглядит следующим образом:

EntityId     (foreign key to the "owner" of this attribute)
AttributeId  (foreign key to the "metadata" table where the attribute is defined)
StringValue  (it is often convenient to have different columns of different types
IntValue      allowing to store the various attributes in a format that befits 
              them)

При этом AttributeId является внешним ключом для таблицы, где каждый возможный атрибут («параметр конфигурации» в вашем случае) определен, скажем,

AttributeId  (Primary Key)
Name
AttributeType     (some code  S = string, I = Int etc.)
Required          (some boolean indicating that this is required)
Some_other_fields   (for example to define in which order these attributes get displayed etc...)

Наконец, EntityId позволяет вам идентифицировать некоторую сущность, которая «владеет» этими различными атрибутами. В вашем случае это может быть UserId или даже неявный, если у вас есть только одна конфигурация для управления.

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

2 голосов
/ 03 мая 2011

Пара ключей и значений аналогична .Net App.Config, в которой могут храниться параметры конфигурации.

Итак, когда вы хотите получить значение, которое вы можете сделать:

SELECT value FROM configurationTable
WHERE ApplicationGroup = 'myappgroup'
AND keyDescription = 'myKey';
1 голос
/ 20 февраля 2010

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

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

property_entry_table

[id, scope, refId, propertyName, propertyValue, propertyType] 
1, 0, 1, "COMPANY_INFO", "Acme Tools", "ADMIN"  
2, 0, 1, "SHIPPING_ID", "12333484", "ADMIN"  
3, 0, 1, "PAYPAL_KEY", "2143123412341", "ADMIN"   
4, 0, 1, "PAYPAL_KEY", "123412341234123", "ADMIN"  
5, 0, 1, "NOTIF_PREF", "ON", "ADMIN"  
6, 0, 2, "NOTIF_PREF", "OFF", "ADMIN"   

Таким образом, вы можете хранить данные, которые у вас есть, и данные, о которых вы будете знать в следующем году и о которых пока не знаете :).

В этом примере ваши область действия и refId могут быть использованы для всего, что вы хотите на серверной части. Поэтому, если propertyType "ADMIN" имеет область видимости 0 refId 2, вы знаете, что это за предпочтение.

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

Обратите внимание, что вы не должны хранить данные корзины таким образом, или поиск по этому вопросу. Однако, если данные * Системные специфические, то вы, безусловно, можете использовать этот метод.

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

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

0 голосов
/ 11 апреля 2016

Имейте ключевой столбец как varchar и столбец значения как JSON. 1 является числовым, тогда как "1" является строкой. true и false оба являются логическими значениями. Вы также можете иметь объекты.

0 голосов
/ 01 февраля 2016

Извините, я пришел, да, позже. Но в любом случае, то, что я делаю, просто и эффективно. Я просто создаю таблицу с тремя () столбцами:

ID - int (11)

name - varchar (64)

значение - текст

Что я делаю перед созданием нового столбца конфигурации, его обновлением или чтением, это сериализацией «значения»! Таким образом, я уверен, что типа (ну, php есть :))

Например:

б: 0; для B OOLEAN ( false )

* * Б тысяча двадцать-три: 1; предназначен для
B OOLEAN ( true )

я: 1988; для I NT

s: 5: "Кадер"; для S TRING длиной 5 символов

Надеюсь, это поможет:)

...