Каков наилучший способ определения столбца в 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)
Это единственный способ реализовать такую ситуацию в теории - понятный и не лишний способ. Это выглядит не очень просто, но обычно эти таблицы покрываются представлением и хранимыми процедурами, поэтому эти таблицы могут использоваться приложением как одна (виртуальная) таблица.
Спасибо Александр