Entity Framework Code Firstを使用して作成されたデータベースがいくつかあります。アプリは機能しており、一般に、Code Firstでできることにはかなり満足しています。私は必要に応じて、まずプログラマー、次にDBAです。 DataAttributesについて読んでいますが、C#でデータベースに何をしたいかをさらに説明しています。そして私の質問は次のとおりですこれらのnvarchar(max)
文字列をテーブルに含めると、どのようなペナルティが発生しますか(以下の例を参照)?
この特定のテーブルにはいくつかの列があります。 C#では、次のように定義されています。
_ [Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
public string Message { get; set; }
public string Source { get; set; }
public DateTime Generated { get; set; }
public DateTime Written { get; set; }
_
Name、Source、Generated、Writtenに基づいてクエリやソートを行うことを期待しています。名前とソースは0から50文字の長さであり、時々最大150です。このテーブルはかなり小さい(10万行未満)から始まりますが、時間の経過とともに大きくなります(100万行を超える)。明らかに、メッセージは小さい場合と大きい場合があり、おそらく照会されません。
私が知りたいのは、名前とソースの列が150文字を超えることを期待していないときに、nvarchar(max)
として定義されている私の列とソースの列にパフォーマンスヒットがあるのでしょうか。
より大きなnvarchar(最大)データ項目(8000バイト以上)はテキストストレージに溢れ、追加のI/Oが必要になります。小さいアイテムは列に格納されます。この動作を制御するオプションがあります-詳細については、この MSDNの記事 を参照してください。
行に格納されている場合、I/Oパフォーマンスのオーバーヘッドはほとんどありません。データ型の処理に追加のCPUオーバーヘッドが発生する可能性がありますが、これはわずかなものである可能性があります。
ただし、nvarchar(最大)列を必要のない場所にデータベースの周りに置いておくのは、かなり貧弱な形式です。 パフォーマンスオーバーヘッド があり、多くの場合、データサイズはデータテーブルを理解するのに非常に役立ちます。たとえば、幅50または100文字のvarchar列は、説明またはフリーテキストフィールドである可能性があります。 (たとえば)10〜20文字のコードはおそらくコードです。このような仮定からデータベースから推測しなければならないことの多い意味に驚くでしょう。
十分にサポートされていないか、文書化されているレガシーシステムではなく、データウェアハウジングで作業することは、理解しやすいデータベーススキーマを持つことは非常に価値があります。データベースをアプリケーションのレガシーと考える場合は、データベースを継承する人にとってはいいものにしてください。
これは特定の質問に答えるものではありませんが、そもそも質問をする必要がなくなる可能性があります。C#モデルクラスの文字列変数に長さを設定することが可能です。これにより、Entity FrameworkがSQLを生成します。 nvarchar(50)
ではなく、固定長のnvarchar型(nvarchar(max)
など)を使用します。
たとえば、次の代わりに:
public string Name { get; set; }
以下を使用できます。
[StringLength(50)]
public string Name { get; set; }
次のように、必要に応じて、型をvarchar
ではなくnvarchar
に強制することもできます。
[Column(TypeName = "VARCHAR")]
[StringLength(50)]
public string Name { get; set; }
最大の懸念事項を索引付けします。 BOLから:
ラージオブジェクト(LOB)データ型の列
ntext
、text
、varchar(max)
、nvarchar(max)
、varbinary(max)
、xml
、またはimage
は、インデックスのキー列として指定できません。
適切にインデックスを作成できないと、クエリが遅くなります。また、データの整合性の観点から、nvarchar(max)
を使用すると、制限を指定するよりも多くの不良データをフィールドに入力できます。
はい、string
をnvarchar(max)
にマッピングする際のデフォルトのEF動作は適切ではありません。 EF 6では、独自のカスタム規則を追加して、この動作を独自の優先デフォルトマッピングでオーバーライドできます。
_protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Properties<string>()
.Configure(s => s.HasMaxLength(200).HasColumnType("varchar") );
base.OnModelCreating(modelBuilder);
}
_
上記のようにOnModelCreating
をオーバーライドすると、すべての文字列のデフォルトのマッピングがvarchar(200)
に変更されます。