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

StackOverflow https://stackoverflow.com/questions/2872067

Вопрос

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

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

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

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

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

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

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

Существующим, чтобы сделать это масштабируемое решение, вам нужно будет определить типы данных для вашей пользовательской формы с использованием таблицы метаданных, где вы определяете фактический тип данных, которые вы хотите хранить (например, Bool, Text, Int, DateTime) Отказ Вы также можете подумать о хранении типа .NET, так как это может помочь вам помочь вам, когда речь идет о проверке ввода и т. Д. Другие детали, которые могут быть сохранены, а также имя поля, как вы ожидаете, Ваша пользовательская форма. Используя этот подход, вы создаете пользовательскую форму на основе хранимых метаданных.

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

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

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

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

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

Плюсы

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

Минусы

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

Если вы застряли с Пользовательская форма > Поле->ПолеValue Я бы предложил создать одну таблицу для каждого ПолеValue.например

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

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


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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top