Каков наилучший способ определения столбца в SQL-сервере, который может содержать целое число или строку?

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

TypeA a1, a2;
TypeB b;
TypeC c;
a1.Parent = b;
a2.Parent = c;

Чтобы еще больше усложнить ситуацию, TypeB и TypeC могут иметь первичные ключи разных типов, например, может быть верно следующее утверждение:

Assert(b.Id is string && c.Id is int);

Мой вопрос заключается в том, каков наилучший способ определения этих родительско-дочерних отношений в SQL Server? Единственное решение, которое я могу придумать, состоит в том, чтобы определить, что таблица TypeA имеет два столбца - ParentId и ParentType, где:

  • ParentId is sql_variant - чтобы иметь возможность хранить как числа, так и строки
  • ParentType является строкой - чтобы сохранить полное имя сборки родительского типа.

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

Должен быть лучший способ. Кто-нибудь? Благодарю.

5 ответов

Решение

Если НИКОГДА столбец НИКОГДА не будет участвовать в каких-либо математических операциях, сделайте их CHAR() или VARCHAR(), так как вы будете иметь дело с последовательностью символов, а не чисел. "1" в этом случае так же верно, как и "А".

Одно слово: НЕ

Это очень плохая практика - столбцы имеют ОДИН ОДИН ДАННЫЙ ДАТАЙТ по причине. Не злоупотребляйте этим и превращайте все в варианты.......

Марк

Я не уверен, что полностью понял ваш случай, но в аналогичных обстоятельствах я создал ДВА столбца в Таблице A, один для хранения строкового ключа и один для хранения ключа int; в конечном итоге они могут быть как NULLable (но не в одной записи).

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

Ну, есть две проблемы. Во-первых, это ОО-дизайн, в вашей модели у TypeA могут быть родители разных типов, а у этих типов (TypeB и TypeC) нет общих родителей. Безусловно, я не верю, что это может быть так на самом деле. Но я не знаю значения этих типов... Эта проблема может быть решена, если вы наследуете TypeB и TypeC от некоторого TypeX, в этом случае я буду ссылаться на TypeX в TypeA.

Второй - это дизайн БД. Из-за ошибки в дизайне OO у вас есть проблемы на стороне БД. Решение одно и то же - создайте отдельную таблицу для TypeX и поместите туда все общие атрибуты между TypeA и TypeB, создайте отдельные таблицы для TypeA и TypeB. TypeX будет относиться к TypeA как 1:1, а также к TypeB. В этом случае создание TypeA выглядит следующим образом - вставьте новую строку в TypeX, получите ID, вставьте строку в TypeA. В этом решении у вас будут соответствующие строки в TypeX и TypeA или TypeX и TypeB.

TypeX (TypexID int не нулевой первичный ключ (1,1), SomeCommonColumn int) TypeA(TypexID int ненулевой первичный ключ, TypeASpecific int) TypeB(TypexID int не нулевой первичный ключ, TypeBSpecific varchar)

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

Спасибо Александр

Другие вопросы по тегам