Должен ли я использовать тип данных SQL_Variant? - PullRequest
24 голосов
/ 28 января 2012

с использованием SQL Server 2005 с пакетом обновления 4 (SP4), и я проектирую таблицу базы данных.

Вот таблица DDL

CREATE TABLE CPSync4D.ProjectProfilerOption
(
    ProjectProfilerOptionID     INT  IDENTITY(1,1) CONSTRAINT PK_ProjectProfilerOption_ProjectProfilerOptionID PRIMARY KEY 
   ,ProjectID                   INT  CONSTRAINT FK_ProjectProfilerOption_Project_ProjectID FOREIGN KEY(ProjectID) REFERENCES CPSync4D.Project(ProjectID) ON DELETE CASCADE
   ,ProfilerOptionID            TINYINT CONSTRAINT FK_ProjectProfilerOption_ProfilerOption_ProfilerOptionID  FOREIGN KEY(ProfilerOptionID) REFERENCES CPSync4D.ProfilerOption (ProfilerOptionID) 
   ,ProfilerOptionValue         sql_variant  NOT NULL   

)
Go

В столбце profileroptionvalue может содержаться строка длиной до 30 символов, целые или десятичные значения, например, значения "ProfilerValueType", или 12,52 или 20 и т. Д.более двух десятичных и целочисленные значения меньше 100)

Стоит ли использовать sql_variant или varchar (30) ...?Я никогда раньше не использовал sql_variant и не уверен, что это может привести к неиспользованию с точки зрения дизайна базы данных.

Любые подводные камни использования sql_variant ... с кодом .net

Ответы [ 3 ]

19 голосов
/ 28 января 2012

10 причин для явного преобразования типов данных SQL Server

Как правило, следует избегать использования типа данных SQL Server sql_variant.Помимо того, что это захват памяти, sql_variant ограничен:

  • Варианты не могут быть частью первичного или внешнего ключа. (это не относится к SQL Server 2005. См. Обновление ниже)
  • Варианты не могут быть частью вычисляемого столбца.
  • Варианты не будут работатьс LIKE в предложении WHERE.
  • Поставщики OLE DB и ODBC автоматически преобразовывают варианты в nvarchar (4000) - ой!используй их.Используйте любой метод, который вам нравится, только не пытайтесь работать с неконвертированным типом данных sql_variant.

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

Следующее будет моим наиболее или менее предпочтительным решением

  • Просто создайте три разных столбца.3 Различные типы данных (должны) означают 3 разных способа интерпретации как на стороне клиента, так и на стороне сервера.
  • Если это не вариант, используйте столбец VARCHAR, чтобы вы могли по крайней мере использовать LIKE операторы.
  • Используйте тип данных sql_variant.

Редактировать Cudo's к ta.speot.is

Варианты могут быть частью первичного элемента внешнего ключа

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

6 голосов
/ 22 мая 2012

Я знаю, что мой ответ немного запоздал, но составленная здесь таблица выглядит как таблица конфигурации приложения.В качестве альтернативы приведенным предложениям давайте подумаем не ограничивать себя 30 или даже 8000 символов.Давайте также сделаем его немного более автономным и определяемым пользователем.

С учетом этих мыслей, почему бы не сохранить информацию «профиля» как тип данных XML, который позволял бы даже несколько уровней настроек?Вероятно, вам больше не понадобятся такие столбцы, как ProfilerOptionID, и вы могли бы свести это к одной простой управляющей таблице.

3 голосов
/ 27 января 2014

Стоит отметить, что невозможно неявно скопировать столбец sql_variant.

например, создать схему резервного копирования CPSync4D.ProjectProfilerOption с именем CPSync4D.ProjectProfilerOption_bkp

, а затем

Insert into CPSync4D.ProjectProfilerOption_bkp
(
    ProjectProfilerOptionID
   ,ProjectID
   ,ProfilerOptionID
   ,ProfilerOptionValue 
)
SELECT 
    ProjectProfilerOptionID
   ,ProjectID
   ,ProfilerOptionID
   ,ProfilerOptionValue 
FROM CPSync4D.ProjectProfilerOption 

Все значения для ProfilerOptionValue в таблице резервных копий будут varchar

Примечание также: мне сказали, что SQL_Variant нельзя использовать в репликации, но это не так .Конечно, это можно сделать с помощью SQL 2008 R2 (который я использую), потому что я только что сделал это, но это может быть верно для более старых версий (у меня нет более старых версий для проверки, поэтому я не могуподтвердите или опровергните это.)

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

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

...