Использование однострочной таблицы конфигурации в базе данных SQL Server. Плохая идея?


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

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

Что является подходящим способом, чтобы сохранить этот информация?

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

12 128

12 ответов:

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

Одну Строку

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

Пара Ключ / Значение

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

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

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

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

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

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

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

show_borders    bit
admin_name      varchar(50)
max_users       int

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

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

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

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

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

добавление "alter table" в ваше развертывание не кажется таким уж большим компромиссом для простоты и безопасности типов подхода с одной строкой.

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

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

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

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 позволяет идентифицировать некоторую сущность, которая" владеет " этими различными атрибутами. В вашем случае это может быть имя Пользователя или даже просто неявно, если у вас есть только одна конфигурация руководить.

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

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

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

SELECT value FROM configurationTable
WHERE ApplicationGroup = 'myappgroup'
AND keyDescription = 'myKey';

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

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

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, вы бы использовали такую таблицу. Таким образом, когда вам нужно обновить приложение, вы можете проверить свойства таблицы, чтобы узнать, какая версия программного обеспечения у клиента.

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

Я не уверен, что одна строка является лучшей реализацией для конфигурации. Возможно, вам лучше иметь строку для каждого элемента конфигурации с двумя столбцами (configName, configValue), хотя это потребует приведения всех ваших значений к строкам и обратно.

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

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

Так что ваша таблица будет выглядеть так:

id, column_num, property_name, intValue, floatValue, charValue, dateValue
1, 1, weeks, 51, , ,
2, 2, pi, , 3.14159, , 
3, 4, FiscYearEnd, , , , 1/31/2015
4, 3, CompanyName, , , ACME, 

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

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

ID-int (11)

имя-varchar (64)

value-text

то, что я делаю перед созданием нового столбца конфигурации, его обновлением или чтением, - это сериализация "значения"! Таким образом, я уверен в типе (Ну, php это :))

например:

b:0; is ибо BOOLEAN (ложные)

b:1; это для BOOLEAN (правда)

i: 1988; is for яNT

s: 5: "Kader" ; is for a SТринг длиной 5 символов

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

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