Реализация объединения стилей c / c ++ в виде столбца в MySQL - PullRequest
6 голосов
/ 16 марта 2010

Друзья

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

Что я хочу сделать, это хранить данные нескольких типов в одном столбце в MySQL.

Это база данных, эквивалентная C union (и если вы ищете MySQL и Union, вы, очевидно, получите целую кучу вещей по ключевому слову UNION в SQL).

[Следует придуманный и упрощенный случай] Итак, допустим, у нас есть люди - у которых есть имена - и STORMTROOPERS - с номерами ТЗ. Вы не можете иметь ОБА ИМЯ и номер ТК. Вы либо BOB SMITH -или- TK409.

В C я мог бы выразить это как объединение, вот так:

union {
        char * name;
        int tkNo;
      } EmperialPersonnelRecord;

Это позволяет хранить указатель на массив символов или идентификатор в типе EmperialPersonnelRecord, но не в обоих.

Я ищу эквивалент MySQL для столбца. В моем столбце будет храниться либо int, double, либо varchar (255) (или любая другая комбинация). Но занимал бы только пространство самого большого элемента.

Возможно ли это?

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

Ответы [ 4 ]

4 голосов
/ 17 марта 2010

Как сказал a1ex07, вы МОЖЕТЕ сделать это, сохранив строковое представление. Но если вас беспокоит пространство, хранение реальных значений в нескольких пустых столбцах, вероятно, сэкономит больше места.

Альтернативно, создайте вспомогательные таблицы и нормализуйте, например,

Ваше желание:

TABLE1
|id|name_or_TK#|

Вы можете сделать:

TABLE1
|id|name|TK|

или вы можете сделать

TABLE1
|id|ST_or_human_flag|other columns common to humans and stormtroopers

TABLE2 - Names_of_humans
|id|name|

TABLE3 - TKs_of_STs
|id|TK|
1 голос
/ 17 марта 2010

C профсоюзы - довольно сложный способ решения этой проблемы.

У вас есть полиморфный тип данных. Таким образом, один из способов решения этой проблемы состоит в том, чтобы переключиться на объектно-ориентированную БД или ту, которая динамически типизируется, как некоторые из «NoSQL».

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

table Employee
    field id int
    field emp_type enum('human', 'stormtrooper')
    field salary int
    field division_id int
    field manager_id int

table HumanEmployee
    field emp_id int
    field name string

table StormtrooperEmployee
    field emp_id int
    field tk_number int

То есть таблицы * Employee привязаны к базовой таблице Employee по идентификатору сотрудника.

1 голос
/ 16 марта 2010

Нет, тип столбца 'union' отсутствует. Но вы можете создать столбец, достаточно большой, чтобы вместить самый большой элемент, и другой столбец, который работает как индикатор типа. * 1001 Т.е. *

... data VARCHAR(15), data_type enum('int','double','char')...
0 голосов
/ 17 марта 2010

Я думаю, у вас должно быть 2 разных столбца и соответственно хранить данные, при извлечении вы можете привести и сложить их вместе, например, col1 + col2 как full_name

...