Apa perbedaan kinerja utama antara tipe data SQL Server varchar dan nvarchar?

236

Saya sedang mengerjakan basis data untuk aplikasi web kecil di sekolah saya menggunakan SQL Server 2005.
Saya melihat beberapa aliran pemikiran tentang masalah varcharvs nvarchar:

  1. Gunakan varcharkecuali Anda berurusan dengan banyak data yang diinternasionalkan, kemudian gunakan nvarchar.
  2. Cukup gunakan nvarcharuntuk semuanya.

Saya mulai melihat manfaat dari tampilan 2. Saya tahu bahwa nvarchar memang memakan ruang dua kali lebih banyak, tetapi itu tidak selalu merupakan masalah besar karena ini hanya akan menyimpan data untuk beberapa ratus siswa. Bagi saya sepertinya akan lebih mudah untuk tidak khawatir tentang hal itu dan biarkan semuanya menggunakan nvarchar. Atau ada sesuatu yang saya lewatkan?

Jason Baker
sumber
pertanyaan serupa di sini: stackoverflow.com/questions/312170/... EDIT oleh le dorfier: yang menarik sampai pada kesimpulan sebaliknya.
Booji Boy
6
referensi utas yang jauh lebih luas yang sampai pada kesimpulan sebaliknya. stackoverflow.com/questions/312170/…
dkretz
2
Jason: Saya harap ini bukan permintaan yang tidak pantas, tetapi bisakah Anda mempertimbangkan mengubah jawaban yang diterima menjadi gbn . Jawaban JoeBarone sangat salah karena berbagai alasan. Setelah itu "diterima" menyesatkan novis untuk membuat pilihan yang buruk. Tidak perlu dan boros untuk "selalu menggunakan NVARCHAR", dan dapat memiliki dampak yang sangat negatif pada kinerja dan biaya / anggaran perangkat keras. Beberapa baris, bahkan beberapa ribu, tidak masalah. Tetapi sistem tumbuh lebih cepat dari yang diharapkan orang, sehingga jawaban yang diterima saat ini adalah merugikan masyarakat. Terima kasih.
Solomon Rutzky

Jawaban:

140

Selalu gunakan nvarchar.

Anda mungkin tidak pernah memerlukan karakter bita ganda untuk sebagian besar aplikasi. Namun, jika Anda perlu mendukung bahasa bita-ganda dan Anda hanya memiliki dukungan bita-tunggal dalam skema basis data Anda, sangat mahal untuk kembali dan memodifikasi seluruh aplikasi Anda.

Biaya migrasi satu aplikasi dari varchar ke nvarchar akan jauh lebih banyak daripada sedikit ruang disk tambahan yang akan Anda gunakan di sebagian besar aplikasi.

Joe Barone
sumber
4
jauh lebih sulit untuk kembali dan menambahkan dukungan untuk teks / pesan multibahasa, zona waktu, satuan ukuran dan mata uang, sehingga setiap orang HARUS selalu kode ini dalam aplikasi mereka sejak hari pertama, SELALU (bahkan jika itu hanya di web halaman rumah Anda) aplikasi)!
KM.
82
Bagaimana dengan ukuran indeks, penggunaan memori dll? Saya menganggap Anda selalu menggunakan int ketika Anda bisa menggunakan tinyint juga "berjaga-jaga"?
gbn
99
Selalu coding / perencanaan untuk situs multi-bahasa (ketika Anda tidak memiliki firasat bahwa Anda akan membutuhkannya) adalah seperti memberi tahu semua orang dewasa muda bahwa mereka harus membeli SUV 8 kursi besar, boros gas untuk mobil pertama mereka ... lagipula , mereka mungkin akan menikah suatu hari dan mungkin memiliki 6 anak,. Saya lebih suka menikmati kinerja dan efisiensi sementara saya bisa dan membayar harga untuk upgrade ketika / jika saya membutuhkannya.
EJ Brennan
4
@ cbmeeks: Saya tidak kode untuk apa yang saya tidak tahu. Tetapi jika Anda dapat menggunakannya tanpa hit kinerja yang nyata, maka basis data Anda tidak cukup besar untuk itu menjadi masalah ...
gbn
60
Biasanya ketika orang memulai jawaban mereka dengan kata "Selalu" maka Anda harus mengabaikan semua yang datang setelah itu. (Perhatikan saya memulai pernyataan itu dengan kata "biasanya" :)
Brandon Moore
226

Disk space bukan masalah ... tetapi memori dan kinerja akan. Gandakan halaman yang dibaca, ukuran indeks ganda, LIKE aneh dan = perilaku konstan dll

Apakah Anda perlu menyimpan skrip Cina dll? Ya atau tidak...

Dan dari MS BOL " Penyimpanan dan Efek Kinerja dari Unicode "

Edit :

Pertanyaan SO terbaru yang menyoroti seberapa buruk kinerja nvarchar ...

SQL Server menggunakan CPU tinggi ketika mencari di dalam string nvarchar

gbn
sumber
19
+1, jika aplikasi Anda go internasional, Anda akan memiliki banyak masalah lain yang perlu dikhawatirkan dengan pencarian / ganti ke nvarchar: teks / pesan multibahasa, zona waktu, satuan ukuran dan mata uang
KM.
2
Tetapi bagaimana jika Anda terkadang perlu menyimpan nama asing, seperti José atau Bjørn?
Qwertie
7
@ Qwertie: maka Anda menggunakan nvarchar. Apa yang tidak Anda lakukan, menggunakannya secara tidak perlu. Kedua nama itu cocok dengan varchar pula IIRC
gbn
6
Mengatakan ruang disk bukan masalah tidak benar untuk semua orang. Kami telah secara naif menggunakan nvarchar jika tidak perlu dalam aplikasi perbankan besar dengan milyaran catatan disimpan selama bertahun-tahun. Dengan penyimpanan berbasis SAN yang mahal dengan replikasi, cadangan, dan pemulihan bencana, ini sebenarnya dapat diterjemahkan ke dalam jutaan dolar dalam biaya untuk nvarchar vs varchar. Belum lagi ada dampak kinerja besar (100%) harus membaca dua kali lebih banyak dari disk untuk setiap membaca.
codemonkey
2
@codemonkey, et al: Saya melakukan apa yang saya bisa untuk mengatasi masalah ruang terbuang secara holistik dalam artikel berikut: Disk Is Cheap! ORLY? (Namun, pendaftaran gratis diperlukan). Artikel ini dimaksudkan untuk membantu mencegah situasi yang terjadi pada codemonkey terkait penyimpanan yang mahal dan tingkat perusahaan.
Solomon Rutzky
59

Bersikaplah konsisten! BERGABUNG dengan VARCHAR ke NVARCHAR memiliki kinerja yang luar biasa.

Thomas Harlan
sumber
115
Jika Anda melakukan penggabungan pada bidang karakter maka basis data Anda mungkin memiliki masalah yang lebih buruk daripada apakah menggunakan nvarchar atau varchar, secara umum.
Brandon Moore
@ Thomas Harlan Sebuah tes sederhana menunjukkan kepada saya bahwa tidak ada perbedaan nyata antara bergabung nvarchardengan varcharvs mengkonversi nvarcharke varchardan bergabung dengan varchar. Kecuali tentu saja Anda berarti konsisten dalam tipe data kolom, bukan bergabung.
ajeh
1
@ajeh dan Thomas: 1) tes "sederhana" seringkali menyesatkan karena tidak mencakup variasi yang menyebabkan perbedaan perilaku. 2) Jika seseorang melihat kinerja drastis ketika pencampuran VARCHARdan NVARCHAR, itu harus karena pengindeksan VARCHARkolom bersama dengan jenis Kolasi yang digunakan untuk kolom itu (dan karenanya indeks). Saya membahas topik ini secara rinci dalam posting blog berikut: Dampak pada Indeks Saat Memadukan Jenis VARCHAR dan NVARCHAR .
Solomon Rutzky
44

nvarchar akan memiliki overhead yang signifikan dalam memori, penyimpanan, set kerja dan pengindeksan, jadi jika spesifikasi menentukan bahwa itu benar-benar tidak akan pernah diperlukan, jangan repot-repot.

Saya tidak akan memiliki aturan "selalu nvarchar" yang keras dan cepat karena dapat menjadi pemborosan dalam banyak situasi - terutama ETL dari ASCII / EBCDIC atau pengidentifikasi dan kolom kode yang sering berupa kunci dan kunci asing.

Di sisi lain, ada banyak kasus kolom, di mana saya pasti akan menanyakan pertanyaan ini lebih awal dan jika saya tidak segera mendapatkan jawaban yang sulit dan cepat, saya akan membuat kolom nvarchar.

Cade Roux
sumber
26

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 WHILEloop 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 NVARCHARsejak, 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 VARCHARdengan Halaman Kode yang sesuai (yang ditentukan dari Collation of the field).
  • Jika menyimpan kode ISO Negara dan / atau Negara (tidak perlu menyimpan INT/ TINYINTkarena 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 VARCHARkarena merupakan standar internasional untuk tidak pernah menggunakan huruf apa pun di luar AZ. Dan ya, masih menggunakan VARCHARbahkan 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 NVARCHARkarena keduanya sekarang dapat berisi karakter Unicode.
  • dan seterusnya....

Keempat: Sekarang Anda memiliki NVARCHARdata 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:

  1. 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 NCHARdan NVARCHARbidang. Faktor penentu adalah:

    1. 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.
    2. NVARCHAR(MAX)dan XML(dan saya kira juga VARBINARY(MAX),, TEXTdan 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.
    3. Data OFF ROW, LOB atau OVERLOW = Tidak Ada Kompresi Untuk Anda!
  2. Jika menggunakan SQL Server 2005, atau 2008 - 2016 RTM dan bukan pada Enterprise Edition, Anda dapat memiliki dua bidang: satu VARCHARdan 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 NVARCHARbertipe:

    INSERT INTO TableName (..., URLa, URLu)
    VALUES (...,
            IIF (CONVERT(VARCHAR(2048), @URL) = @URL, @URL, NULL),
            IIF (CONVERT(VARCHAR(2048), @URL) <> @URL, NULL, @URL)
           );
  3. 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 COMPRESSdan DECOMPRESSfungsi, yang juga GZip.
  4. Jika menggunakan SQL Server 2017 atau yang lebih baru, Anda bisa melihat membuat tabel Clustered Columnstore Index.

  5. Meskipun ini bukan opsi yang layak, SQL Server 2019 memperkenalkan dukungan asli untuk UTF-8 di VARCHAR/ CHARtipe 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.

Solomon Rutzky
sumber
7
Bertepuk tangan lambat Cukup kagum bahwa "selalu menggunakan nvarchar" mendapat 140 suara dan ini tidak. Kerja bagus di pos ini.
schizoid04
1
@ schizoid04 Terima kasih. Agar adil, jawaban yang diterima diposting 7 tahun sebelum saya, jadi ada banyak lalu lintas yang memilihnya (dan / atau berbagai lainnya) yang tidak pernah kembali untuk mengevaluasi kembali. Namun, ia memberikan tandingan yang sangat kuat pada teori "wisdom of the crowd" yang mendorong forum berbasis suara. Ada terlalu banyak informasi yang salah di luar sana. Misalnya, ini di DBA.SE. Jawaban lainnya, diterima sebelum saya memposting milik saya, adalah "benar" dengan definisi tersempit, menyesatkan, dan berisi info yang saya bantah dalam milik saya, namun masih melebihi saya.
Solomon Rutzky
22

Untuk aplikasi Anda, nvarchar baik-baik saja karena ukuran basis datanya kecil. Mengatakan "selalu gunakan nvarchar" adalah penyederhanaan besar. Jika Anda tidak diharuskan menyimpan hal-hal seperti Kanji atau karakter gila lainnya, gunakan VARCHAR, itu akan menggunakan ruang yang jauh lebih sedikit. Pendahulu saya di pekerjaan saya saat ini merancang sesuatu menggunakan NVARCHAR ketika itu tidak diperlukan. Kami baru-baru ini beralih ke VARCHAR dan menyimpan 15 GB hanya pada tabel itu (sangat ditulis untuk). Selanjutnya, jika Anda kemudian memiliki indeks pada tabel itu dan Anda ingin memasukkan kolom itu atau membuat indeks komposit, Anda baru saja membuat ukuran file indeks Anda lebih besar.

Hanya bijaksana dalam keputusan Anda; dalam pengembangan SQL dan definisi data tampaknya jarang ada "jawaban default" (selain menghindari kursor di semua biaya, tentu saja).

WebMasterP
sumber
10

Karena aplikasi Anda kecil, pada dasarnya tidak ada kenaikan biaya yang cukup besar untuk menggunakan nvarchar di atas varchar, dan Anda menyelamatkan diri dari potensi sakit kepala di jalan jika Anda perlu menyimpan data unicode.

tffffni
sumber
8

Secara umum; Mulailah dengan tipe data paling mahal yang memiliki kendala paling sedikit. Masukkan ke dalam produksi . Jika kinerja mulai menjadi masalah, cari tahu apa yang sebenarnya disimpan di nvarcharkolom tersebut. Apakah ada karakter di sana yang tidak cocok varchar? Jika tidak, beralihlah ke varchar. Jangan mencoba melakukan pra-optimalisasi sebelum Anda tahu di mana rasa sakitnya. Dugaan saya adalah bahwa pilihan antara nvarchar / varchar bukanlah yang akan memperlambat aplikasi Anda di masa mendatang. Akan ada bagian lain dari aplikasi di mana penyetelan kinerja akan memberi Anda lebih banyak keuntungan .

Kjetil Klaussen
sumber
7

Selama beberapa tahun terakhir semua proyek kami telah menggunakan NVARCHAR untuk semuanya, karena semua proyek ini multibahasa. Data yang diimpor dari sumber eksternal (misalnya file ASCII, dll.) Dikonversi ke Unicode sebelum dimasukkan ke dalam database.

Saya belum pernah menemukan masalah terkait kinerja dari indeks yang lebih besar, dll. Indeks memang menggunakan lebih banyak memori, tetapi memori itu murah.

Apakah Anda menggunakan prosedur tersimpan atau membuat SQL on the fly, pastikan semua konstanta string diawali dengan N (mis. SET @foo = N'Hello world. ';) Sehingga konstanta juga Unicode. Ini menghindari konversi tipe string apa pun pada saat runtime.

YMMV.

menghancurkan
sumber
4
Anda mungkin tidak memiliki beberapa ratus juta catatan di tabel yang Anda kerjakan. Saya setuju bahwa untuk sebagian besar aplikasi default ke nvarchar baik-baik saja, tetapi tidak semua.
Brandon Moore
7

Saya dapat berbicara dari pengalaman tentang hal ini, waspadalah nvarchar. Kecuali Anda benar-benar membutuhkannya, bidang data ini merusak kinerja pada basis data yang lebih besar. Saya mewarisi database yang menyakitkan dalam hal kinerja dan ruang. Kami dapat mengurangi basis data 30GB sebesar 70%! Ada beberapa modifikasi lain yang dibuat untuk membantu dengan kinerja tetapi saya yakin varcharitu membantu secara signifikan dengan itu juga. Jika database Anda memiliki potensi untuk menumbuhkan tabel hingga sejuta + catatan, jauhi nvarcharsemua biaya.

JA
sumber
4

Saya sering menangani pertanyaan ini di tempat kerja:

  • Umpan inventaris dan harga FTP - Deskripsi item dan teks lainnya berada di nvarchar saat varchar berfungsi dengan baik. Mengubah ini ke varchar mengurangi ukuran file hampir setengah dan sangat membantu dengan unggahan.

  • Skenario di atas bekerja dengan baik sampai seseorang memasukkan karakter khusus dalam deskripsi item (mungkin merek dagang, tidak dapat mengingat)

Saya masih tidak menggunakan nvarchar setiap kali melalui varchar. Jika ada keraguan atau potensi untuk karakter khusus, saya menggunakan nvarchar. Saya menemukan saya menggunakan varchar sebagian besar ketika saya dalam kendali 100% dari apa yang mengisi bidang.

K Richard
sumber
3

Mengapa, dalam semua diskusi ini, tidak disebutkan UTF-8? Mampu menyimpan rentang unicode penuh karakter tidak berarti kita harus selalu mengalokasikan dua-byte-per-karakter (atau "titik kode" untuk menggunakan istilah UNICODE). Semua ASCII adalah UTF-8. Apakah SQL Server memeriksa bidang VARCHAR () yang teksnya ketat ASCII (yaitu bit byte atas nol)? Saya harap tidak.

Jika kemudian Anda ingin menyimpan unicode dan ingin kompatibilitas dengan aplikasi ASCII-satunya yang lebih tua, saya akan berpikir menggunakan VARCHAR () dan UTF-8 akan menjadi peluru ajaib: Itu hanya menggunakan lebih banyak ruang ketika perlu.

Bagi Anda yang tidak terbiasa dengan UTF-8, mungkin saya merekomendasikan primer .

Tevya
sumber
2
Apa yang Anda sarankan mungkin berfungsi untuk beberapa aplikasi, tetapi kita juga harus mempertimbangkan dampak dari lapisan pengkodean ekstra pada cara teks SQL diproses. Khususnya, pengumpulan, pencarian, dan pencocokan pola akan dilakukan. Dan jika laporan dijalankan terhadap basis data, alat pelaporan standar tidak akan menginterperasi karakter multi-byte dengan benar. Impor dan ekspor dalam jumlah besar mungkin akan terpengaruh. Saya pikir — dalam jangka panjang — skema ini mungkin lebih merepotkan daripada nilainya.
Jeffrey L Whitledge
1
Tidak mungkin untuk menyimpan UTF-8 di kolom VARCHAR. MSSQL akan selalu mengonversi data UTF-8 Anda ke susunan kolom. Jika Anda mengacaukan susunan (seperti mencoba menyimpan CP1252 dalam bahasa Latin_1) konversi tidak akan berfungsi dan Anda akan berakhir dengan byte tambahan dalam data Anda. Mungkin muncul untuk bekerja dengan baik ketika Anda mengkonversi latin_1 ke UTF-8 (di sisi aplikasi) dan kembali lagi ke latin_1 (sisi db) tapi itu hanya ilusi. Anda dapat menyelinap dengan DB otomatis yang mengkonversi ke pemeriksaan kolom Anda dengan menggunakan freetds dan mengatur protokol ke sesuatu yang kurang dari 7, tetapi Anda kehilangan kemampuan untuk meminta nvarchar.
chugadie
1
@ Chugadie dan Tevya: jawaban ini agak tidak masuk akal. SQL Server hanya menggunakan UCS-2 / UTF-16 untuk menyimpan data Unicode (yaitu Ntipe XML dan -prefixed). Anda tidak mendapatkan pilihan menggunakan UTF-8. Juga, pengkodean Unicode (UTF-8, UCS-2 / UTF-16, dan UTF-32) tidak dapat diterapkan ke bidang VARCHAR.
Solomon Rutzky
2

Akan ada contoh luar biasa ketika Anda ingin secara sengaja membatasi tipe data untuk memastikan itu tidak mengandung karakter dari set tertentu. Sebagai contoh, saya memiliki skenario di mana saya perlu menyimpan nama domain dalam database. Internasionalisasi untuk nama domain tidak dapat diandalkan pada saat itu sehingga lebih baik untuk membatasi input di tingkat dasar, dan membantu menghindari masalah potensial.

Chris Halcrow
sumber
1

Jika Anda menggunakan NVARCHARhanya karena prosedur yang disimpan oleh sistem memerlukannya, kejadian yang paling sering terjadi adalah tidak dapat dijelaskan sp_executesql, dan SQL dinamis Anda sangat panjang, Anda akan lebih baik dari perspektif kinerja melakukan semua manipulasi string (penggabungan, penggantian dll.) VARCHARKemudian mengonversi hasil akhir NVARCHARdan memasukkannya ke dalam parameter proc. Jadi tidak, jangan selalu gunakan NVARCHAR!

ajeh
sumber