Лучший способ хранить данные в базе данных, когда вы не знаете тип - PullRequest
1 голос
/ 20 мая 2010

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

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

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

FieldValue
----------
Id
DataFieldId
IntValue
DoubleValue
BoolValue
DataValue
..

Другая возможность - просто хранить все как String и приводить это в запросах. Я использую .Net с NHibernate, и я вижу, что по крайней мере здесь есть Projection.Cast, которое можно использовать, например, для приведения. строка в int в запросе.

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

Во всяком случае; Я не думаю, что какое-либо из этих решений звучит хорошо. Они? Или есть лучший способ?

Ответы [ 4 ]

1 голос
/ 20 мая 2010

3-й «магический» вариант отсутствует: ваша конкретная ситуация определяет, как вы хотите действовать.

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

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

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

1 голос
/ 20 мая 2010

Извлекая идею из мультитенантного хранилища данных, вы можете использовать идею значений 'Name-Pair', как описано в MSDN . Я почему-то думаю, что эта статья будет более полезной, кроме отмеченного конкретного раздела.

Фактически, чтобы сделать это масштабируемым решением, вам нужно будет определить типы данных для вашей пользовательской формы, используя таблицу метаданных, в которой вы определяете фактический тип данных, которые вы хотите сохранить (например, bool, text, int). Дата и время). Вы можете также рассмотреть вопрос о сохранении типа .Net, так как это может помочь вам, когда дело доходит до проверки ввода и т. Д. Другие данные, которые также могут быть сохранены, - это названия полей, как вы ожидаете, что они появятся на Ваша пользовательская форма. Используя этот подход, вы создаете пользовательскую форму на основе сохраненных метаданных.

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

0 голосов
/ 10 июня 2010

Перед тем, как предложить мой взгляд .. Я бы сказал, что вам, возможно, придется вернуться к доске ER. Я предполагаю, что CustomForm имеет много полей и что эти поля имеют различные виды (текст, данные, возможно, даже поведение и стиль), а не обобщают концепцию Поле Вместо этого стоит подумать о создании одной таблицы для каждого типа поля. Например. DateField, UserNameField и т. Д. Это сделает тип значения ровно одним ненулевым столбцом с правильным типом. Я бы также поспорил, что это упростит ваш код (меньше условий для проверки, БД дает вам всю информацию.)

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

Плюсы

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

Минусы

  • БД не может принудительно указать, что указано не более одного значения (дополнительный код для проверки исключений)
  • DB не может принудительно установить, что хотя бы один из них не равен NULL (дополнительный код для проверки значений FieldValues ​​без каких-либо значений)
  • добавление поддержки нового типа данных требует изменения всех существующих данных (добавление значения NULL в столбцах).

Если вы застряли с CustomForm > Field -> FieldValue Я бы предложил создать одну таблицу на FieldValue . например,

IntFieldValue
-------------
Id
DataFieldId
Value

DecimalFieldValue
-------------
Id
DataFieldId
Decimal


DateFieldValue
-------------
Id
DataFieldId
Date

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

0 голосов
/ 20 мая 2010

Если у вас есть только 2 текстовых поля, в которые пользователь может вводить значения, и это будет либо строка, либо число, вам действительно нужно уметь различать int и double, вы не можете просто сохранить его все как подходящий числовой тип (в зависимости от БД). Это приведет вас к двум различным типам, а затем возможное решение будет иметь 2 таблицы, по одной для каждого из двух типов.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...