Saya memiliki beberapa database yang dibuat menggunakan Entity Framework Code First; aplikasi bekerja dan secara umum saya cukup senang dengan apa yang pertama kali saya lakukan dengan Code. Saya seorang programmer pertama, dan DBA kedua, karena kebutuhan. Saya membaca tentang DataAttributes untuk menjelaskan lebih lanjut dalam C # apa yang saya ingin database lakukan; dan pertanyaan saya adalah: hukuman apa yang akan saya makan dengan memasukkan nvarchar(max)
string ini di meja saya (lihat contoh di bawah)?
Ada beberapa kolom dalam tabel khusus ini; di C # mereka didefinisikan sebagai:
[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; }
Saya berharap untuk meminta dan / atau mengurutkan berdasarkan Nama, Sumber, Dihasilkan, dan Ditulis. Saya berharap Nama dan Sumber berada dalam panjang karakter 0-50, kadang-kadang hingga 150. Saya berharap tabel ini mulai cukup kecil (<100r baris), tetapi tumbuh secara signifikan dari waktu ke waktu (> 1jej baris). Jelas pesan bisa kecil atau besar, dan mungkin tidak akan dipertanyakan.
Yang ingin saya ketahui, apakah ada hit kinerja untuk kolom Nama dan Sumber saya didefinisikan sebagai nvarchar(max)
ketika saya tidak pernah berharap mereka lebih besar dari 150 karakter?
[MaxLength]
atau[StringLength]
atribut. Beberapa kemungkinan faktor negatif tambahan dari kolom yangvarchar(max)
mana - mana akan merusak kinerja Anda - jangan lakukan itu! Gunakan tipe data yang sesuai -varchar(max)
HANYA SAJA jika Anda BENAR - BENAR membutuhkan lebih dari 8000 karakter! (Saya belum pernah melihat nama atau email seseorang selama itu!) - Lihat Apa gunanya Menggunakan VARCHAR (n) Lagi? untuk info lebih lanjutJawaban:
Item data nvarchar (max) yang lebih besar (lebih dari 8000 byte atau lebih) akan tumpah ke penyimpanan teks dan membutuhkan I / O tambahan. Item yang lebih kecil akan disimpan secara berturut-turut. Ada opsi yang mengontrol perilaku ini - lihat artikel MSDN ini untuk detail lebih lanjut.
Jika disimpan dalam baris tidak ada overhead kinerja I / O yang signifikan; mungkin ada overhead CPU tambahan pada pemrosesan tipe data tetapi ini kemungkinan kecil.
Namun, meninggalkan kolom nvarchar (maks) di sekitar database di mana mereka tidak diperlukan adalah bentuk yang agak buruk. Itu memang memiliki beberapa overhead kinerja dan seringkali ukuran data cukup membantu dalam memahami tabel data - misalnya, kolom varchar lebar 50 atau 100 karakter cenderung menjadi deskripsi atau bidang teks bebas di mana satu itu (katakanlah) 10- 20 karakter mungkin merupakan kode. Anda akan terkejut betapa banyak makna yang harus disimpulkan dari sebuah database melalui asumsi seperti ini.
Bekerja di pergudangan data, sesering mungkin tidak pada sistem legacy yang kurang didukung atau terdokumentasi, memiliki skema database yang mudah dipahami cukup berharga. Jika Anda menganggap database sebagai warisan aplikasi, cobalah bersikap baik kepada orang-orang yang akan mewarisinya dari Anda.
sumber
Meskipun ini tidak menjawab pertanyaan spesifik Anda, ini mungkin menghalangi Anda dari perlu untuk mengajukan pertanyaan di tempat pertama: Dimungkinkan untuk menetapkan panjang pada variabel string Anda di kelas model C # Anda, yang akan menyebabkan Entity Framework untuk menghasilkan SQL yang menggunakan tipe nvarchar dengan panjang tetap (misalnya
nvarchar(50)
), bukannvarchar(max)
.Misalnya, alih-alih:
Anda dapat gunakan:
Anda juga bisa memaksakan tipe menjadi
varchar
bukannvarchar
, jika diinginkan, sebagai berikut:Sumber: https://stackoverflow.com/questions/7341783/entity-framework-data-annotations-set-stringlength-varchar/7341920
sumber
varchar(50)
), tetapi EF 6 membutuhkan apa yang ada di jawaban ini.Pengindeksan menjadi perhatian terbesar. Dari BOL:
Jika Anda tidak dapat mengindeks dengan benar, Anda akan memiliki pertanyaan lambat. Dan dari perspektif integritas data, memiliki
nvarchar(max)
akan memungkinkan lebih banyak data buruk dimasukkan ke dalam bidang daripada menentukan batasnya.sumber
Ya, perilaku EF default dalam pemetaan
string
kenvarchar(max)
tidak baik. Di EF 6 Anda dapat menambahkan konvensi kustom Anda sendiri untuk mengesampingkan perilaku ini dengan pemetaan default pilihan Anda sendiri.Mengesampingkan
OnModelCreating
seperti di atas akan mengubah pemetaan default untuk semua stringvarchar(200)
.sumber
the default EF behavior in mapping string to nvarchar(max) is not good
ini tampaknya menjadi pendapat umum Anda. dapatkah Anda menjelaskan mengapa ini tidak baik? Atau, Anda pikir, EF bukan kerangka kerja untuk aplikasi bisnis di mana Anda perlu bekerja dengan berbagai bahasa? Karena itulah tipe kolom yang diinginkan untuk menangani banyak bahasa pada basis data.max
mengerikan. Tetapi jika Anda ingin menangani beberapa bahasa (dan karakter yang berbeda) Anda perlu menggunakannvarchar
apakah saya salah?