web-dev-qa-db-ja.com

SQL_Variantデータ型を使用する必要がありますか?

sQL Server 2005 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文字の文字列、整数値または10進数値を保持できます。値は「ProfilerValueType」、または12.52または20などです(小数点以下2桁以下、整数値は100未満)。

Sql_variantまたはvarchar(30)...を使用する必要がありますか?私は以前にsql_variantを使用したことがなく、データベース設計の観点から使用しないことの影響は不明です。

.netコードでsql_variant ...を使用する場合の落とし穴

25
SQL Learner

SQL Serverデータ型を明示的に変換する10の理由

原則として、SQL Serverのsql_variantデータ型は使用しないでください。メモリーを独占することに加えて、sql_variantには制限があります。

  • バリアントを主キーまたは外部キーの一部にすることはできません。 (これはSQL Server 2005以降では保持されません。以下の更新を参照してください)
  • バリアントを計算列の一部にすることはできません。
  • バリアントはWHERE句でLIKEを使用できません。
  • OLE DBおよびODBCプロバイダーは、バリアントをnvarchar(4000)に自動的に変換します—痛いです!

問題を回避するには、sql_variantデータ型を使用するときに常に明示的に変換します。変換しないsql_variantデータ型を操作しないでください。

使用していませんsql_variant以前は、これらの制限とパフォーマンスへの影響を考慮して、最初に代替案を検討しました。

以下は、私の最も好ましい方法から最も好ましくない方法です

  • 3つの異なる列を作成するだけです。 3つの異なるデータ型は、クライアント側とサーバー側の両方でそれを解釈する3つの異なる方法を意味します(推奨)。
  • それがオプションでない場合は、VARCHAR列を使用して、少なくともLIKEステートメントを使用できるようにします。
  • 使用 sql_variant データ・タイプ。

Editcudo's to ta.speot.is

バリアントcancan be primary of primary of foreign key

一意キー、主キー、または外部キーには、sql_variant型の列を含めることができますが、特定の行のキーを構成するデータ値の全長は、インデックスの最大長を超えてはなりません。これは900バイトです

20

私の答えは少し遅いことはわかっていますが、ここで作成されるテーブルは、アプリケーション構成テーブルのように見えます。指定された提案の代わりに、30文字または8000文字に制限しないことを考えてみましょう。また、もう少し自己完結型でユーザーが定義できるようにします。

これらのことを念頭に置いて、「プロファイル」情報を、複数レベルの設定さえ可能にするXMLデータ型として保存してみませんか?おそらく、ProfilerOptionIDなどの列はもう必要なく、これを1つの単純なコントロールテーブルにまとめることができるでしょう。

6
Jeff Moden

Sql_variant列を暗黙的にコピーすることはできないことに注意してください。

例えばCPSync4D.ProjectProfilerOption_bkpという名前のCPSync4D.ProjectProfilerOptionのバックアップスキーマを作成します。

その後

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

バックアップテーブルのProfilerOptionValueのすべての値はvarcharになります

注:SQL_Variantはレプリケーションでは使用できないと言われましたが、これは正しくありませんです。確かにそれはSQL 2008 R2(私が使用している)で実行できますが、これは実行したばかりですが、これは以前のバージョンではtrueでした(確認する古いバージョンはありません)これを確認または拒否することはできません)。

ただし、SQLバリアントを含むテーブルを複製して大量のデータがあり、何かがうまくいかず、データを手動で修正する必要がある場合、SQLの厄介な部分が記述される可能性があります。 。これは、データをコピーするときに、同じcopyステートメントで複数の基本型を使用してコピーできないためです。レプリケーションでは複数の行がコピーされないため、この問題は発生しないと思います(スナップショットは明らかに例外ですが、bcpを使用しています)。

ps。私はこれが古い投稿であることを理解していますが、同じ質問を持つ他の将来の訪問者のためにこれをここに置いてください。

3
David Bridge