Saya ragu untuk menambahkan jawaban lain di sini karena sudah ada beberapa, tetapi beberapa poin perlu dibuat yang belum dibuat atau belum dibuat dengan jelas.
Pertama: Do tidak selalu menggunakan NVARCHAR
. Itu adalah sikap / pendekatan yang sangat berbahaya, dan seringkali mahal. Dan tidak ada yang lebih baik untuk mengatakan " Jangan pernah menggunakan kursor" karena mereka kadang-kadang merupakan cara paling efisien untuk menyelesaikan masalah tertentu, dan kerja sama yang umum dalam melakukan WHILE
loop hampir selalu lebih lambat daripada Kursor yang dilakukan dengan benar .
Satu-satunya waktu Anda harus menggunakan istilah "selalu" adalah ketika menasihati untuk "selalu melakukan yang terbaik untuk situasi". Memang itu seringkali sulit untuk ditentukan, terutama ketika mencoba menyeimbangkan keuntungan jangka pendek dalam waktu pengembangan (manajer: "kami membutuhkan fitur ini - yang belum Anda ketahui sampai sekarang - seminggu yang lalu!") Dengan lama biaya pemeliharaan jangka panjang (manajer yang awalnya menekan tim untuk menyelesaikan proyek 3 bulan dalam sprint 3 minggu: "mengapa kita mengalami masalah kinerja ini? Bagaimana mungkin kita melakukan X yang tidak memiliki fleksibilitas? Kita tidak mampu satu atau dua sprint untuk memperbaikinya. Apa yang bisa kita lakukan dalam seminggu sehingga kita bisa kembali ke item prioritas kita? Dan kita pasti perlu menghabiskan lebih banyak waktu dalam desain sehingga ini tidak terus terjadi! ").
Kedua: jawaban @ gbn menyentuh beberapa poin yang sangat penting untuk dipertimbangkan ketika membuat keputusan pemodelan data tertentu ketika jalurnya tidak 100% jelas. Tetapi ada lebih banyak untuk dipertimbangkan:
- ukuran file log transaksi
- waktu yang diperlukan untuk mereplikasi (jika menggunakan replikasi)
- waktu yang diperlukan untuk ETL (jika ETLing)
- waktu yang diperlukan untuk mengirim log ke sistem jarak jauh dan memulihkan (jika menggunakan Pengiriman Log)
- ukuran cadangan
- lamanya waktu yang dibutuhkan untuk menyelesaikan cadangan
- lamanya waktu yang diperlukan untuk melakukan pemulihan (ini mungkin penting suatu hari ;-)
- ukuran yang dibutuhkan untuk tempdb
- kinerja pemicu (untuk tabel yang dimasukkan dan dihapus yang disimpan dalam tempdb)
- kinerja pembuatan versi baris (jika menggunakan SNAPSHOT ISOLATION, karena versi store di tempdb)
- kemampuan untuk mendapatkan ruang disk baru ketika CFO mengatakan bahwa mereka hanya menghabiskan $ 1 juta pada SAN tahun lalu dan sehingga mereka tidak akan mengotorisasi $ 250k lain untuk penyimpanan tambahan
- lamanya waktu yang diperlukan untuk melakukan operasi INSERT dan UPDATE
- lamanya waktu yang dibutuhkan untuk melakukan pemeliharaan indeks
- dll, dll, dll
Pemborosan ruang memiliki efek kaskade besar pada seluruh sistem. Saya menulis artikel yang menjelaskan secara rinci tentang topik ini: Disk Is Cheap! ORLY? (diperlukan pendaftaran gratis; maaf saya tidak mengendalikan kebijakan itu).
Ketiga: Sementara beberapa jawaban salah berfokus pada aspek "ini adalah aplikasi kecil", dan beberapa benar menyarankan untuk "menggunakan apa yang sesuai", tidak ada jawaban yang memberikan panduan nyata kepada OP. Rincian penting yang disebutkan dalam Pertanyaan adalah bahwa ini adalah halaman web untuk sekolah mereka. Bagus! Jadi kami dapat menyarankan bahwa:
- Kolom untuk Mahasiswa dan / atau nama Fakultas harus mungkin menjadi
NVARCHAR
sejak, dari waktu ke waktu, itu hanya mendapatkan lebih mungkin bahwa nama-nama dari budaya lain akan muncul di tempat-tempat.
- Tetapi untuk alamat jalan dan nama kota? Tujuan aplikasi tidak dinyatakan (akan sangat membantu) tetapi dengan asumsi catatan alamat, jika ada, hanya berkaitan dengan wilayah geografis tertentu (yaitu satu bahasa / budaya), kemudian gunakan
VARCHAR
dengan Halaman Kode yang sesuai (yang ditentukan dari Collation of the field).
- Jika menyimpan kode ISO Negara dan / atau Negara (tidak perlu menyimpan
INT
/ TINYINT
karena kode ISO panjangnya tetap, dapat dibaca oleh manusia, dan baik, standar :) gunakan CHAR(2)
untuk dua kode huruf dan CHAR(3)
jika menggunakan 3 kode huruf. Dan pertimbangkan untuk menggunakan Kolasi biner seperti Latin1_General_100_BIN2
.
- Jika menyimpan kode pos (yaitu kode pos), gunakan
VARCHAR
karena merupakan standar internasional untuk tidak pernah menggunakan huruf apa pun di luar AZ. Dan ya, masih menggunakan VARCHAR
bahkan jika hanya menyimpan kode pos AS dan bukan INT karena kode pos bukan angka, mereka adalah string, dan beberapa dari mereka memiliki "0" terdepan. Dan pertimbangkan untuk menggunakan Kolasi biner seperti Latin1_General_100_BIN2
.
- Jika menyimpan alamat email dan / atau URL, gunakan
NVARCHAR
karena keduanya sekarang dapat berisi karakter Unicode.
- dan seterusnya....
Keempat: Sekarang Anda memiliki NVARCHAR
data yang menggunakan ruang dua kali lebih banyak daripada yang dibutuhkan untuk data yang cocok dengan baik VARCHAR
("cocok dengan baik" = tidak berubah menjadi "?") Dan entah bagaimana, seolah-olah dengan sihir, aplikasi tumbuh dan sekarang ada jutaan catatan di setidaknya satu dari bidang ini di mana sebagian besar baris adalah ASCII standar tetapi beberapa berisi karakter Unicode sehingga Anda harus menyimpannya NVARCHAR
, pertimbangkan yang berikut ini:
Jika Anda menggunakan SQL Server 2008 - 2016 RTM dan pada Enterprise Edition, ATAU jika menggunakan SQL Server 2016 SP1 (yang membuat Kompresi Data tersedia di semua edisi) atau lebih baru, maka Anda dapat mengaktifkan Kompresi Data . Kompresi Data dapat (tetapi tidak akan "selalu") mengompresi data Unicode di dalam NCHAR
dan NVARCHAR
bidang. Faktor penentu adalah:
NCHAR(1 - 4000)
dan NVARCHAR(1 - 4000)
gunakan Skema Kompresi Standar untuk Unicode , tetapi hanya dimulai pada SQL Server 2008 R2, DAN hanya untuk data ROW, bukan OVERFLOW! Ini tampaknya lebih baik daripada algoritma kompresi ROW / PAGE biasa.
NVARCHAR(MAX)
dan XML
(dan saya kira juga VARBINARY(MAX)
,, TEXT
dan NTEXT
) data yang DALAM ROW (bukan baris di halaman LOB atau OVERFLOW) setidaknya dapat dikompresi HALAMAN, tetapi tidak dikompresi ROW. Tentu saja, kompresi PAGE tergantung pada ukuran nilai in-row: Saya diuji dengan VARCHAR (MAX) dan melihat bahwa 6000 karakter / baris byte tidak akan dikompres, tetapi 4000 karakter / byte baris melakukannya.
- Data OFF ROW, LOB atau OVERLOW = Tidak Ada Kompresi Untuk Anda!
Jika menggunakan SQL Server 2005, atau 2008 - 2016 RTM dan bukan pada Enterprise Edition, Anda dapat memiliki dua bidang: satu VARCHAR
dan satu NVARCHAR
. Misalnya, Anda menyimpan URL yang sebagian besar merupakan karakter ASCII dasar (nilai 0 - 127) dan karenanya cocok VARCHAR
, tetapi terkadang memiliki karakter Unicode. Skema Anda dapat mencakup 3 bidang berikut:
...
URLa VARCHAR(2048) NULL,
URLu NVARCHAR(2048) NULL,
URL AS (ISNULL(CONVERT(NVARCHAR([URLa])), [URLu])),
CONSTRAINT [CK_TableName_OneUrlMax] CHECK (
([URLa] IS NOT NULL OR [URLu] IS NOT NULL)
AND ([URLa] IS NULL OR [URLu] IS NULL))
);
Dalam model ini, Anda hanya PILIH dari [URL]
kolom yang dihitung. Untuk memasukkan dan memperbarui, Anda menentukan bidang mana yang akan digunakan dengan melihat apakah mengubah mengubah nilai yang masuk, yang harus NVARCHAR
bertipe:
INSERT INTO TableName (..., URLa, URLu)
VALUES (...,
IIF (CONVERT(VARCHAR(2048), @URL) = @URL, @URL, NULL),
IIF (CONVERT(VARCHAR(2048), @URL) <> @URL, NULL, @URL)
);
Anda dapat GZIP nilai yang masuk ke VARBINARY(MAX)
dan kemudian unzip di jalan keluar:
- Untuk SQL Server 2005 - 2014: Anda dapat menggunakan SQLCLR. SQL # (pustaka SQLCLR yang saya tulis) hadir dengan Util_GZip dan Util_GUnzip dalam versi Gratis
- Untuk SQL Server 2016 dan yang lebih baru: Anda dapat menggunakan built-in
COMPRESS
dan DECOMPRESS
fungsi, yang juga GZip.
Jika menggunakan SQL Server 2017 atau yang lebih baru, Anda bisa melihat membuat tabel Clustered Columnstore Index.
Meskipun ini bukan opsi yang layak, SQL Server 2019 memperkenalkan dukungan asli untuk UTF-8 di VARCHAR
/ CHAR
tipe data. Saat ini ada terlalu banyak bug untuk digunakan, tetapi jika mereka diperbaiki, maka ini merupakan opsi untuk beberapa skenario. Silakan lihat posting saya, " Dukungan Asli UTF-8 di SQL Server 2019: Juruselamat atau Nabi Palsu? ", Untuk analisis terperinci dari fitur baru ini.