База данных SQL, в которой хранятся различные типы значений (в одном поле или моделируется им) - PullRequest
4 голосов
/ 28 апреля 2011

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

Variables
    ID
    Name

VariableValuesLink
    ID
    IDVars
    IDVals

Values
    IDvals

ValuesValueLink
    ID
    IDvals
    IDval

ValuesInt
    IDval
    IntVal

ValuesFloat
    IDval
    FloatVal

ValuesDouble
    IDval
    DoubleVal

etc...
etc...
etc...
etc...

Цель для меня получить что-то вроде этого:

Variable: 
    ezas123
Values:
    1 (Int)
    2.0 (Float)
    3.0 (Double)

Variable:
    QuickFox
Values:
    The (TinyText)
    Quick (TinyText)
    Brown (TinyText)
    Fox (TinyText)
    Jumped (TinyText)
    Over (TinyText)
    The (TinyText)
    Lazy (TinyText)
    Dog (TinyText)

Variable:
    Pangrams
Values:
    The Quick Brown Fox Jumped Over The Lazy Dog (Text)
    How quickly daft jumping zebras vex (Text)

Поэтому, когда я сделаю запрос в БД, я смогу получить этот набор результатов (где значения имеют различный тип)

Variable    Value
ezas123     1
ezas123     2.0
ezas123     3.0
QuickFox    The
QuickFox    Quick
QuickFox    Brown
QuickFox    Fox
QuickFox    Jumped
QuickFox    Over
QuickFox    The
QuickFox    Lazy
QuickFox    Dog
Pangrams    The Quick Brown Fox Jumped Over The Lazy Dog
Pangrams    How quickly daft jumping zebras vex

Ответы [ 2 ]

5 голосов
/ 28 апреля 2011

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

Variable
    ID
    Name

ValuesInt
    IDvariable
    IntVal

ValuesFloat
    IDvariable
    FloatVal

ValuesDouble
    IDvariable
    DoubleVal

etc...
etc...
etc...

Насколько прост ваш sql:

select v.name as Variable,
       coalesce(cast(vi.IntVal as varchar(max)),
                cast(vf.FoatVal as varchar(max)),
                cast(vd.DoubleVal as varchar(max)),
                '') as Value
From Variable V
JOIN ValuesInt vi on V.ID = vi.IDvariable
JOIN ValuesFloat vf on V.ID = vf.IDvariable
JOIN ValuesDouble vd on V.ID = vd.IDvariable
3 голосов
/ 02 мая 2011

Пара баллов:

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

  • SQL-запрос Хогана подчеркивает, что всякий раз, когда вы перечисляете значения таким образом, как вы запрашивали (то есть для переменных с разными типами данных), вам придется приводить результат к varchar или подобному для его отображения (так как вы не можете иметь значения с разными типами данных в одном выходном столбце). Имея это в виду, вам действительно нужны разные типы данных, или тип varchar будет хорошо работать для всех данных, с которыми вы имеете дело?

Если нужны разные типы, я бы посмотрел на размещение всех разных столбцов IntVal, FloatVal, DoubleVal, ... в одной таблице. Тогда ваши определения таблиц могут выглядеть примерно так:

Variables
      ID          NOT NULL
     ,Name        NOT NULL
     ,DataType    NOT NULL CHECK (DataType IN ('INT','FLOAT','DOUBLE','TEXT'))  
   ,CONSTRAINT PK_Variables PRIMARY KEY (ID)
   ,CONSTRAINT UQ_Variables_1 UNIQUE (Name)
   ,CONSTRAINT UQ_Variables_2 UNIQUE  (ID,DataType)

    Values
      IDvals      NOT NULL
     ,ID          NOT NULL
     ,DataType    NOT NULL CHECK (DataType IN ('INT','FLOAT','DOUBLE','TEXT'))
     ,IntVal      NULL
     ,FloatVal    NULL
     ,DoubleVal   NULL
     ,TextVal     NULL
   ,CONSTRAINT PK_Values PRIMARY KEY (IDvals)
   ,CONSTRAINT FK_Values_Variable FOREIGN KEY (ID,DataType) REFERENCES Variables(ID,DataType)
   ,CONSTRAINT CH_Values CHECK ( NOT(DataType <> 'INT'    AND IntVal     IS NOT NULL)  AND
                                 NOT(DataType <> 'FLOAT'  AND FloatVal   IS NOT NULL)  AND
                                 NOT(DataType <> 'DOUBLE' AND DoubleVal  IS NOT NULL)  AND
                                 NOT(DataType <> 'TEXT'   AND TextVal    IS NOT NULL)
                                )
  • Возможно, потребуется ограничение UNIQUE для переменных (ID, DataType) (СУБД?), Чтобы сделать его объектом FK;
  • Ограничения CHECK обеспечивают использование только допустимых типов данных и заполнение только правильных столбцов значений;
  • Наличие DataType в значениях, а также в переменных означает, что комбинация FK и CHECK может использоваться для обеспечения того, чтобы все значения для данной переменной имели одинаковый тип данных, вместо того, чтобы использовать триггеры или логику приложения.

Запрос к таблицам выглядит примерно так:

SELECT v.name as Variable,
       COALESCE(cast(a.IntVal       as varchar(max)),
                cast(a.FloatVal     as varchar(max)),
                cast(a.DoubleVal    as varchar(max)),
                cast(a.TextVal      as varchar(max)),
                '') as Value
FROM 
Variables V
JOIN Values a on V.ID = a.ID AND v.DataType = a.DataType

Это также можно записать (возможно, более правильно), используя CASE на основе Variable.DataType, используемый для выбора соответствующего столбца.

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

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