15

現在、データベーステーブルを次のように設定しています(EAV-ビジネス上の理由は有効です)。

  • Id-int(PK)
  • キー-一意、varchar(15)
  • 値-varchar(1000)

これにより、キーと値のペアとして混合値をデータベースに追加できます。例えば:

1   | 'Some Text'      | 'Hello World'
2   | 'Some Number'    | '123456'
etc.

私のC#コードでは、ADO.Netを使用して値を文字列として取得し、コードで必要に応じて変換します。reader.GetString(2);たとえば、...。Int32.ParseInt(myObj.Value);値の列をデータ型に変更することでテーブルを拡張することを検討していますがsql_variant、これがどのようなメリットがあるのか​​わかりません。基本的に、私のの列をsql_variantvsにすることに利点はありますvarchar(1000)か?


より明確にするために、私はどこかでsql_variantがnvarchar(4000)として呼び出されたクライアントに返されることを読みました(痛い)!しかし、それを返す前に、そのタイプにキャストすることはできませんでしたか?明らかに、私のコードは、値を文字列値ではなくオブジェクトとして格納するように調整する必要があります。sql_variant私の現在の状況で他のタイプと比較して使用することの長所/短所は何だと思いますか?ああ、そして私が保存しようとしているのは、値の列に日時、文字列、および数値型(int、decimalなど)だけであることに言及する価値があります。ブロブや画像などを保存する予定はありません。

4

4 に答える 4

10

SQLバリアントの良いところは、列に複数の型を格納でき、型情報を保持できることです。

MySettings値('Name'、'MyName');に挿入します。MySettings値に挿入します('ShouesNumber'、45); MySettings値に挿入します('MyDouble'、31.32);

タイプを取得する場合:

select SQL_VARIANT_PROPERTY ( value , 'BaseType' ) as DataType,* from mysettings

そしてあなたは持っています:

Datatype Name          Value
-----------------------------
varchar  Name          MyName
int      ShoesNumber   45
numeric  MyDouble      31.32

残念ながら、これにはいくつかの欠点があります。

  1. あまり速くない
  2. ORMフレームワークでは十分にサポートされていません
于 2013-01-17T16:25:59.463 に答える
8

タイプを に変更する場合は、 IDataRecord.GetValuesql_variantメソッドを使用する必要があります。ずっと型を保持します。

したがって、.NET では、次のようなコードを使用できます。

// read an object of SQL underlying data type 'int' stored in an sql_variant column
object o = myReader.GetValue(); // o.GetType() will be System.Int32

// read an object of SQL underlying data type '(n)varchar' or '(n)char' stored in an sql_variant column
object o = myReader.GetValue(); // o.GetType() will be System.String

// read an object of SQL underlying data type 'datetime' stored in an sql_variant column
object o = myReader.GetValue(); // o.GetType() will be System.DateTime

etc...

もちろん、保存するときも同じことを想定しています。SqlParameter.Value を不透明な値に設定するだけで、DbType は使用しないでください。

個人的に面白いと思うのsql_variantは、様々な(標準)型を値とするEAVです。

もちろん、「SQLServerに焦点を当てた人」(読み取り:DBA)はまったく好きではありません:-) SQL Server側でsql_variantは、(コメントに記載されているように)使用するのはあまり実用的ではありませんが、不透明な「もの」であり、SQL プロシージャ コードで使用する必要はありません。問題ないと思います。したがって、.NET/OO プログラミング側ではより有利です。

于 2013-01-15T10:49:21.127 に答える
0

sql_variant型には、Zarathosによって十分に説明されている制限があります。

私が紛らわしいと思うのは、varchar(1000)に言及してから、変換されたnvarchar(4000)を返すことについて「痛い」ということです。

まず、全世界が最終的にローカルで制限された文字セットの使用をやめ、UnicodeとUTF-8をすべて使用することにしたのは良いことです。したがって、varcharよりもnvarcharを、テキストよりもntextを優先する必要があります。

そして、戻り値はnvarchar(4000)であり、nchar(4000)ではありません。違いは、varcharはサイズが可変であるのに対し、プレーンタイプのcharはサイズが固定されていることです。char(4000)のタプルを返すと、多くの空の廃棄物が送信されますが、varcharではこれは問題になりません。

わかった。しかし、あなたにとって適切なデータ型は何でしょうか?ntextをお勧めします。今日は1000でしたが、明日は10,000になる可能性があります。インデックスを作成していない「大量のテキスト」がある場合は、おそらくデータベースが制限を決定するべきではありません。ただのテキストです。

ntextは、文字列が常にUnicodeであるため、.NETにもよく適合します。文字列からintへの変換も、SQLServerよりも.NETの方が高速です。

お役に立てれば

于 2013-01-17T14:58:56.377 に答える
0

まだ言及されていないので、この問題へのかなり一般的なアプローチは次のような表であることを言及します。

  • ID - 整数 (PK)
  • キー - 一意、varchar(15)
  • ValueType - 整数 (0 - 文字列、1 - 整数、3 - 浮動小数点数) (オプション)
  • 文字列値 - varchar(1000)
  • IntValue - 整数
  • FloatValue - 倍精度

利点:

  • データは適切な形式で保存されます (文字列として int を保存すると、多くのビットが無駄になります)
  • WHERE left(key,5) = 'SHOES' や IntValue>5 のような高度なクエリを実行できます。
  • ValueType 列は、(キーのセットを取得するために) キーにプレフィックス/サフィックスを使用している場合にのみ有用であり、セットは混合型である可能性があります。つまり、WHERE left(key,4) = 'Size' および ValueType = 1

短所:

  • このテーブルを使用するすべての場所で、正しい値列を取得/設定する必要があります
  • ValueType 列が必要/必要であると判断した場合は、正しく取得/設定する必要があります。
于 2013-01-18T19:18:40.490 に答える