Apa kasus penggunaan untuk memilih CHAR lebih dari VARCHAR di SQL?

270

Saya menyadari bahwa CHAR direkomendasikan jika semua nilai saya adalah lebar tetap. Tapi, jadi apa? Mengapa tidak memilih VARCHAR untuk semua bidang teks hanya agar aman.

SkunkSpinner
sumber

Jawaban:

386

Umumnya pilih CHAR jika semua baris memiliki panjang yang hampir sama . Pilih VARCHAR saat panjangnya bervariasi . CHAR juga mungkin sedikit lebih cepat karena semua baris memiliki panjang yang sama.

Ini bervariasi berdasarkan implementasi DB, tetapi umumnya VARCHAR menggunakan satu atau dua byte lebih dari penyimpanan (untuk panjang atau penghentian) di samping data aktual. Jadi (dengan asumsi Anda menggunakan set karakter satu byte) menyimpan kata "FooBar"

  • CHAR (6) = 6 byte (tanpa overhead)
  • VARCHAR (10) = 8 byte (2 byte overhead)
  • CHAR (10) = 10 byte (4 byte overhead)

Intinya adalah CHAR bisa lebih cepat dan lebih hemat ruang untuk data dengan panjang yang relatif sama (dalam perbedaan dua karakter panjang).

Catatan : Microsoft SQL memiliki 2 byte overhead untuk VARCHAR. Ini mungkin berbeda dari DB ke DB, tetapi umumnya setidaknya ada 1 byte overhead yang diperlukan untuk menunjukkan panjang atau EOL pada VARCHAR.

Seperti yang ditunjukkan oleh Gaven dalam komentar, jika Anda menggunakan multi-byte, set karakter panjang variabel seperti UTF8 maka CHAR menyimpan jumlah maksimum byte yang diperlukan untuk menyimpan jumlah karakter. Jadi jika UTF8 membutuhkan paling banyak 3 byte untuk menyimpan sebuah karakter, maka CHAR (6) akan diperbaiki pada 18 byte, bahkan jika hanya menyimpan karakter latin1. Jadi dalam hal ini VARCHAR menjadi pilihan yang jauh lebih baik.

Jim McKeeth
sumber
20
Alasan lain adalah pemisahan halaman dan fragmentasi. Saya punya meja dengan IDEN PK yang mendapat 99% terfragmentasi karena pemisahan halaman pada kolom varchar. Tabel yang sangat aktif dan pada dasarnya aplikasi baris baru baris kosong akan dibuat dan kemudian diisi. Char memperbaiki masalah fragmentasi.
paparazzo
12
@ Jim McKeeth - perhitungan ini hanya benar jika Anda menggunakan charset latin1. Karena kebanyakan orang harus menggunakan utf8 hari ini, kolom CHAR Anda akan menggunakan rata-rata 3x ruang sebagai VARCHAR yang menyimpan sebagian besar karakter di bidang multibahasa dasar.
Gavin Towey
11
@ JimmcKeeth ya, itu benar sekali. Karena CHAR adalah panjang tetap, maka itu harus diperbaiki pada ruang maksimum yang mungkin dapat digunakan. Dalam UTF8 itu 3 byte per karakter. Untuk varchar, gratis menggunakan 1-3 byte per karakter sesuai kebutuhan. Ini ada dalam manual MySQL: dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html
Gavin Towey
3
Apa bedanya dengan string FooBar dan varchar (100) vs char (100)? Saya berpikir bahwa menunjukkan perbedaan lebih baik, ya? Tidak?
Nenotlep
4
@GavinTowey SQLSERVER menggunakan UCS-2 untuk tipe data NCHAR dan NVARCHAR-nya. Itu selalu dua byte per karakter.
1010
69

Jika Anda bekerja dengan saya dan Anda bekerja dengan Oracle, saya mungkin akan membuat Anda menggunakannya varchardi hampir setiap keadaan. Asumsi yang charmenggunakan daya pemrosesan lebih sedikit daripadavarchar mungkin benar ... untuk saat ini ... tetapi mesin basis data menjadi lebih baik dari waktu ke waktu dan aturan umum semacam ini memiliki "mitos" masa depan.

Hal lain: Saya belum pernah melihat masalah kinerja karena seseorang memutuskan untuk ikut varchar. Anda akan menggunakan waktu dengan lebih baik untuk menulis kode yang baik (lebih sedikit panggilan ke basis data) dan SQL yang efisien (bagaimana cara kerja indeks, bagaimana pengoptimal membuat keputusan, mengapa existslebih cepat daripadain biasanya ...).

Pikiran terakhir: Saya telah melihat segala macam masalah dengan penggunaan CHAR, orang yang mencari '' ketika mereka seharusnya mencari '', atau orang yang mencari 'FOO' ketika mereka seharusnya mencari 'FOO (sekelompok ruang di sini)' , atau orang yang tidak memotong trailing blank, atau bug dengan Powerbuilder menambahkan hingga 2000 blanko ke nilai yang dikembalikan dari prosedur Oracle.

Ethan Post
sumber
20
Saya agak tidak setuju dengan paragraf pertama Anda, karena char dapat memberikan petunjuk yang dapat berguna untuk optimizer, bahkan yang di masa depan, dan mungkin membantu untuk mengomunikasikan maksud kolom. Tapi +1 untuk paragraf ketiga Anda. Saya benci semua ruang ekstra. Sebuah bidang harus menyimpan apa pun yang saya masukkan tanpa bantalan [explicative]. Pada dasarnya, saya hanya menggunakan char jika semua data memiliki panjang yang persis sama, tidak lebih dan tidak kurang, sekarang dan selamanya. Ini sangat jarang, tentu saja, dan biasanya char (1).
Jeffrey L Whitledge
char juga memberikan petunjuk kepada analis dan pengembang ... hal ini adalah x jumlah karakter .... Jika mereka berpikir untuk membuat serial dalam beberapa format lain, itu mungkin bisa membantu. (Saya terpaksa menyimpan checksum md5 di char di mssql yang tidak memiliki tipe uuid ... dan saya tidak pernah menginginkan apa pun <32 byte ... juga memberi batasan pada kolom).
joefromct
31

Selain manfaat kinerja, CHARdapat digunakan untuk menunjukkan bahwa semua nilai harus memiliki panjang yang sama, misalnya kolom untuk singkatan negara bagian AS.

Hank Gay
sumber
Atau kode negara - dapat membantu membedakan antara menggunakan singkatan kode negara 2 atau 3 karakter
Dan Field
Jika itu benar-benar panjang yang tetap, maka harus ada kendala yang menegakkannya. Meskipun jika Anda menggunakan CHAR, Anda harus memastikan batasan diskon Anda.
jpmc26
18

Char sedikit lebih cepat, jadi jika Anda memiliki kolom yang Anda TAHU akan panjangnya, gunakan char. Misalnya, menyimpan (M) ale / (F) emale / (U) yang diketahui berdasarkan gender, atau 2 karakter untuk negara bagian AS.

Jarrett Meyer
sumber
4
Tidak yakin itu jawaban yang HEBAT, karena ENUM biasanya lebih masuk akal, meskipun saya tidak yakin seberapa luas didukung jenis itu (di luar MySQL).
Bobby Jack
Tampak bagi saya bahwa set negara tidak selalu berubah, jadi char (2) tampaknya jauh lebih tepat daripada enum.
Kearns
1
@Obby Jack - Saya tidak tahu detail spesifik dari implementasi SQL enum tertentu, tetapi perlu diingat bahwa enum yang disimpan sebagai integer 4 byte mungkin memerlukan lebih banyak ruang daripada kolom char (1) atau char (2) dengan data yang sama. Ada perasaan di mana enum lebih logis dalam hal interpretasinya, dan itu mungkin menarik, tetapi segala sesuatu dalam sistem RDBMS abstrak pada tingkat tertentu dan tunduk pada predikat yang ditentukan untuk tabel.
Jeffrey L Whitledge
4
Contoh buruk, ENUM adalah yang terbaik untuk kasus itu. Contoh yang lebih baik adalah kode bandara IATA 3 huruf
Andrew G. Johnson
5
@Andrew, tidak semua db mendukung tipe data ENUM. MSSQLServer, misalnya, tidak. Juga, ENUM, disimpan sebagai int, membutuhkan 4 byte. CHAR (1) membutuhkan 1 byte, dan NCHAR (1) membutuhkan 2 byte.
Jarrett Meyer
17

Apakah NChar atau Char tampil lebih baik daripada alternatif mereka?

Pertanyaan yang bagus Jawaban sederhananya adalah ya dalam situasi tertentu. Mari kita lihat apakah ini bisa dijelaskan.

Jelas kita semua tahu bahwa jika saya membuat tabel dengan kolom varchar (255) (sebut saja kolom ini myColumn) dan menyisipkan sejuta baris tetapi hanya memasukkan beberapa karakter ke dalam myColumn untuk setiap baris, tabelnya akan jauh lebih kecil (secara keseluruhan) jumlah halaman data yang dibutuhkan oleh mesin penyimpanan) daripada jika saya telah membuat myColumn sebagai char (255). Kapan saja saya melakukan operasi (DML) pada tabel itu dan meminta banyak baris, itu akan lebih cepat ketika myColumn adalah varchar karena saya tidak harus pindah sekitar semua ruang "ekstra" pada akhirnya. Bergerak, seperti ketika SQL Server melakukan jenis internal seperti selama operasi yang berbeda atau gabungan, atau jika memilih gabungan selama rencana kueri, dll.

Tetapi ada beberapa overhead dalam menggunakan varchar. SQL Server harus menggunakan indikator dua byte (overhead) untuk, pada setiap baris, untuk mengetahui berapa banyak byte yang dimiliki myColumn baris tertentu di dalamnya. Bukan 2 byte tambahan yang menghadirkan masalah, melainkan harus "mendekode" panjang data di myColumn pada setiap baris.

Dalam pengalaman saya, paling masuk akal untuk menggunakan char daripada varchar pada kolom yang akan digabungkan ke dalam query. Misalnya kunci utama dari sebuah tabel, atau beberapa kolom lain yang akan diindeks. Nomor Pelanggan pada tabel demografis, atau CodeID pada tabel decode, atau mungkin Nomor Pesanan pada tabel pesanan. Dengan menggunakan char, mesin kueri dapat lebih cepat melakukan penggabungan karena ia dapat melakukan aritmatika penunjuk langsung (secara deterministik) daripada harus memindahkan pointer itu sejumlah variabel byte saat membaca halaman. Saya tahu saya mungkin kehilangan Anda pada kalimat terakhir itu. Bergabung dalam SQL Server didasarkan pada gagasan "predikat". Predikat adalah suatu kondisi. Misalnya myColumn = 1, atau OrderNumber <500.

Jadi jika SQL Server melakukan pernyataan DML, dan predikat, atau "kunci" yang digabungkan adalah panjang tetap (karakter), mesin kueri tidak harus melakukan banyak pekerjaan untuk mencocokkan baris dari satu tabel ke baris dari meja lain. Tidak perlu mencari tahu berapa lama data di baris dan kemudian berjalan di string untuk menemukan akhirnya. Semua itu butuh waktu.

Sekarang ingatlah bahwa ini dapat dengan mudah diimplementasikan dengan buruk. Saya telah melihat char digunakan untuk bidang kunci utama dalam sistem online. Lebar harus dijaga tetap kecil yaitu char (15) atau sesuatu yang masuk akal. Dan itu bekerja paling baik dalam sistem online karena Anda biasanya hanya mengambil atau memasang sejumlah kecil baris, jadi harus "rtrim" ruang trailing yang akan Anda dapatkan di set hasil adalah tugas yang sepele daripada harus bergabung dengan jutaan baris dari satu tabel ke jutaan baris di tabel lain.

Alasan lain mengapa CHAR masuk akal dibandingkan varchar pada sistem online adalah karena mengurangi pemisahan halaman. Dengan menggunakan char, Anda pada dasarnya "memesan" (dan membuang-buang) ruang itu jadi jika pengguna datang kemudian dan menempatkan lebih banyak data ke dalam kolom itu SQL telah mengalokasikan ruang untuk itu dan di dalamnya berjalan.

Alasan lain untuk menggunakan CHAR mirip dengan alasan kedua. Jika seorang programmer atau pengguna melakukan pembaruan "batch" ke jutaan baris, misalnya menambahkan kalimat ke bidang catatan, Anda tidak akan menerima panggilan dari DBA Anda di tengah malam bertanya-tanya mengapa drive mereka penuh. Dengan kata lain, ini mengarah pada pertumbuhan ukuran database yang lebih mudah diprediksi.

Jadi itu adalah 3 cara sistem online (OLTP) dapat mengambil manfaat dari char over varchar. Saya hampir tidak pernah menggunakan char dalam skenario gudang / analisis / OLAP karena biasanya Anda memiliki begitu banyak data sehingga semua kolom char tersebut dapat bertambah hingga banyak ruang terbuang.

Ingatlah bahwa char dapat membuat basis data Anda jauh lebih besar tetapi sebagian besar alat cadangan memiliki kompresi data sehingga cadangan Anda cenderung memiliki ukuran yang sama seperti jika Anda telah menggunakan varchar. Misalnya LiteSpeed ​​atau RedGate SQL Backup.

Penggunaan lain adalah dalam tampilan yang dibuat untuk mengekspor data ke file dengan lebar tetap. Katakanlah saya harus mengekspor beberapa data ke file flat untuk dibaca oleh mainframe. Itu lebar tetap (tidak dibatasi). Saya suka menyimpan data dalam tabel "pementasan" saya sebagai varchar (sehingga menghabiskan lebih sedikit ruang pada basis data saya) dan kemudian menggunakan tampilan untuk CAST semuanya sesuai dengan char, dengan panjang yang sesuai dengan lebar lebar tetap untuk kolom itu . Sebagai contoh:

create table tblStagingTable (
pkID BIGINT (IDENTITY,1,1),
CustomerFirstName varchar(30),
CustomerLastName varchar(30),
CustomerCityStateZip varchar(100),
CustomerCurrentBalance money )

insert into tblStagingTable
(CustomerFirstName,CustomerLastName, CustomerCityStateZip) ('Joe','Blow','123 Main St Washington, MD 12345', 123.45)

create view vwStagingTable AS
SELECT CustomerFirstName = CAST(CustomerFirstName as CHAR(30)),
CustomerLastName = CAST(CustomerLastName as CHAR(30)),
CustomerCityStateZip = CAST(CustomerCityStateZip as CHAR(100)),
CustomerCurrentBalance = CAST(CAST(CustomerCurrentBalance as NUMERIC(9,2)) AS CHAR(10))

SELECT * from vwStagingTable

Ini keren karena secara internal data saya mengambil lebih sedikit ruang karena menggunakan varchar. Tetapi ketika saya menggunakan DTS atau SSIS atau bahkan hanya memotong dan menempelkan dari SSMS ke Notepad, saya bisa menggunakan tampilan dan mendapatkan jumlah ruang trailing yang tepat. Dalam DTS kami dulu memiliki fitur yang disebut, sial aku lupa saya pikir itu disebut "menyarankan kolom" atau sesuatu. Di SSIS Anda tidak bisa melakukan itu lagi, Anda harus mendefinisikan manajer koneksi file flat. Tetapi karena Anda memiliki pengaturan tampilan, SSIS dapat mengetahui lebar setiap kolom dan dapat menghemat banyak waktu saat membangun tugas aliran data Anda.

Jadi intinya ... gunakan varchar. Ada sejumlah kecil alasan untuk menggunakan char dan itu hanya untuk alasan kinerja. Jika Anda memiliki sistem dengan hundrends jutaan baris, Anda akan melihat perbedaan yang nyata jika predikatnya deterministik (char) tetapi untuk sebagian besar sistem menggunakan char hanya membuang-buang ruang.

Semoga itu bisa membantu. Jeff

Jeff
sumber
Anda mengatakan bahwa obrolan tetap membutuhkan lebih banyak ruang tidak hanya saat disimpan, tetapi juga saat diangkut atau "dipindahkan" seperti yang Anda katakan? Dari DB Server ke klien saya misalnya? Kapan kita kehilangan byte nol itu?
The Red Pea
9

Ada manfaat kinerja, tetapi di sini ada satu yang belum disebutkan: migrasi baris. Dengan char, Anda memesan seluruh ruang terlebih dahulu. Jadi katakanlah Anda memiliki char (1000), dan Anda menyimpan 10 karakter, Anda akan menggunakan semua 1000 charaters of space. Dalam varchar2 (1000), Anda hanya akan menggunakan 10 karakter. Masalahnya muncul saat Anda memodifikasi data. Katakanlah Anda memperbarui kolom yang sekarang berisi 900 karakter. Mungkin saja ruang untuk memperluas varchar tidak tersedia di blok saat ini. Dalam hal itu, mesin DB harus memigrasi baris ke blok lain, dan membuat pointer di blok asli ke baris baru di blok baru. Untuk membaca data ini, mesin DB sekarang harus membaca 2 blok.
Tidak ada yang dapat dengan tegas mengatakan bahwa varchar atau char lebih baik. Ada ruang untuk tradeoff waktu, dan pertimbangan apakah data akan diperbarui, terutama jika ada kemungkinan baik itu akan tumbuh.

Tony BenBrahim
sumber
Saya pikir Anda memiliki kesalahan ketik dalam posting Anda - bukankah seharusnya varchar2 (1000) menjadi CHAR (1000)?
Matt Rogish
8

Ada perbedaan antara optimasi kinerja awal dan menggunakan jenis aturan praktik terbaik. Jika Anda membuat tabel baru di mana Anda akan selalu memiliki bidang panjang tetap, masuk akal untuk menggunakan CHAR, Anda harus menggunakannya dalam kasus itu. Ini bukan optimasi awal, melainkan menerapkan aturan praktis (atau praktik terbaik).

yaitu - Jika Anda memiliki bidang status 2 huruf, gunakan CHAR (2). Jika Anda memiliki bidang dengan nama negara bagian yang sebenarnya, gunakan VARCHAR.

Bryan Rehbein
sumber
8

Saya akan memilih varchar kecuali kolom menyimpan nilai tetap seperti kode negara bagian AS - yang selalu sepanjang 2 karakter dan daftar kode negara bagian yang valid tidak sering berubah :).

Dalam setiap kasus lain, bahkan seperti menyimpan kata sandi hash (yang merupakan panjang tetap), saya akan memilih varchar.

Mengapa - kolom tipe char selalu dipenuhi dengan spasi, yang membuat kolom my_column didefinisikan sebagai char (5) dengan nilai 'ABC' di dalam perbandingan:

my_column = 'ABC' -- my_column stores 'ABC  ' value which is different then 'ABC'

Salah.

Fitur ini dapat menyebabkan banyak bug menjengkelkan selama pengembangan dan membuat pengujian lebih sulit.

Grzegorz Gierlik
sumber
1
Setidaknya dalam MSSQL Server, 'abc' = 'abc'. Saya tidak pernah tahu apakah saya suka atau benci fitur itu ....
Mark Brackett
Bacaan yang bagus tentang pelapisan char di sini Padding
Edward
6

CHAR menghabiskan lebih sedikit ruang penyimpanan daripada VARCHAR jika semua nilai data Anda di bidang itu sama panjang. Sekarang mungkin pada tahun 2009 database 800GB adalah sama untuk semua maksud dan tujuan sebagai 810GB jika Anda mengubah VARCHAR menjadi CHAR, tetapi untuk string pendek (1 atau 2 karakter), CHAR masih merupakan "praktik terbaik" industri, menurut saya.

Sekarang jika Anda melihat berbagai tipe data yang disediakan sebagian besar basis data bahkan untuk bilangan bulat saja (bit, mungil, int, bigint), ADA alasan untuk memilih satu di antara yang lain. Cukup memilih bigint setiap kali sebenarnya sedikit mengabaikan tujuan dan penggunaan lapangan. Jika suatu bidang hanya mewakili usia seseorang dalam tahun, bigint adalah berlebihan. Sekarang itu tidak selalu "salah", tetapi tidak efisien.

Tetapi ini argumen yang menarik, dan seiring dengan meningkatnya basis data, dapat diperdebatkan CHAR vs VARCHAR menjadi kurang relevan.

Scott Duffy
sumber
4

Saya mendukung komentar Jim McKeeth.

Juga, pengindeksan dan pemindaian tabel penuh lebih cepat jika tabel Anda hanya memiliki kolom CHAR. Pada dasarnya optimizer akan dapat memprediksi seberapa besar setiap record jika hanya memiliki kolom CHAR, sementara itu perlu memeriksa nilai ukuran setiap kolom VARCHAR.

Selain itu jika Anda memperbarui kolom VARCHAR ke ukuran yang lebih besar dari konten sebelumnya, Anda dapat memaksa database untuk membangun kembali indeksnya (karena Anda memaksa database untuk secara fisik memindahkan catatan pada disk). Sementara dengan kolom CHAR itu tidak akan pernah terjadi.

Tetapi Anda mungkin tidak akan peduli dengan hit kinerja kecuali meja Anda besar.

Ingat kata-kata bijak Djikstra. Optimalisasi kinerja awal adalah akar dari semua kejahatan.

Alvaro Rodriguez
sumber
4
Ada tingkat spekulasi dalam komentar Anda. Saya telah melihat berkali-kali asumsi seperti ini diuji dan kebalikannya ternyata benar. Masalahnya adalah banyak insinyur akan mengambil info seperti ini sebagai Injil. Tolong teman-teman, buat kasus uji yang mencerminkan situasi nyata Anda.
Ethan Post
Ethan sepenuhnya benar. Ini tergantung pada implementasi yang Anda gunakan tanpa referensi ke aktual (Produk, Versi), itu sama sekali tidak berguna.
David Schmitt
Saat Anda memperbarui CHARkolom, indeks juga perlu diperbarui. Tidak ada perbedaan dalam memperbarui kolom VARCHAR atau CHAR dalam hal itu. Pikirkan tentang memperbarui FOOke BAR.
a_horse_with_no_name
4

Banyak orang telah menunjukkan bahwa jika Anda tahu panjang pasti nilai menggunakan CHAR memiliki beberapa manfaat. Tetapi sementara menyimpan negara bagian AS sebagai CHAR (2) sangat bagus hari ini, ketika Anda menerima pesan dari penjualan bahwa 'Kami baru saja melakukan penjualan pertama kami ke Australia', Anda berada dalam dunia yang penuh kesakitan. Saya selalu mengirim untuk melebih-lebihkan berapa lama saya pikir bidang perlu daripada membuat dugaan 'tepat' untuk meliput acara mendatang. VARCHAR akan memberi saya lebih banyak fleksibilitas di bidang ini.

Craig
sumber
3

Saya pikir dalam kasus Anda, mungkin tidak ada alasan untuk tidak memilih Varchar. Ini memberi Anda fleksibilitas dan seperti yang telah disebutkan oleh sejumlah responden, kinerjanya sudah sedemikian rupa sehingga kecuali dalam keadaan yang sangat spesifik kita manusia biasa (yang bertentangan dengan Google DBA) tidak akan melihat perbedaannya.

Suatu hal yang menarik yang perlu diperhatikan ketika datang ke DB Type adalah sqlite (database mini populer dengan kinerja yang cukup mengesankan) menempatkan semuanya ke dalam database sebagai string dan tipe on the fly.

Saya selalu menggunakan VarChar dan biasanya membuatnya jauh lebih besar daripada yang mungkin saya butuhkan. Misalnya. 50 untuk Firstname, seperti yang Anda katakan mengapa tidak hanya untuk aman.

Toby Allen
sumber
3

Saya tidak akan pernah menggunakan karakter. Saya pernah berdebat dengan banyak orang dan mereka selalu memunculkan klise yang lelah bahwa char lebih cepat. Baiklah saya katakan, seberapa cepat? Apa yang kita bicarakan di sini, milidetik, detik, dan jika ya, berapa banyak? Anda memberi tahu saya karena seseorang mengklaim beberapa milidetik lebih cepat, kita harus memperkenalkan banyak bug yang sulit diperbaiki ke dalam sistem?

Jadi, inilah beberapa masalah yang akan Anda hadapi:

Setiap bidang akan diisi, sehingga Anda berakhir dengan kode selamanya yang memiliki RTRIM di mana-mana. Ini juga merupakan pemborosan ruang disk besar untuk bidang yang lebih panjang.

Sekarang katakanlah Anda memiliki contoh klasik bidang char hanya dengan satu karakter tetapi bidang tersebut opsional. Jika seseorang melewati string kosong ke bidang itu, ia menjadi satu ruang. Jadi ketika aplikasi / proses lain menanyakannya, mereka mendapatkan satu ruang tunggal, jika mereka tidak menggunakan rtrim. Kami memiliki xml dokumen, file, dan program lain, hanya menampilkan satu ruang, dalam bidang opsional dan memecahkan banyak hal.

Jadi sekarang Anda harus memastikan bahwa Anda melewati nol dan bukan string kosong, ke bidang char. Tapi itu BUKAN penggunaan yang benar dari null. Ini adalah penggunaan null. Katakanlah Anda mendapatkan file dari vendor

Nama | Jenis Kelamin | Kota

Bob || Los Angeles

Jika jenis kelamin tidak ditentukan dari yang Anda masukkan Bob, string kosong dan Los Angeles ke dalam tabel. Sekarang katakanlah Anda mendapatkan file dan formatnya berubah dan jenis kelamin tidak lagi disertakan tetapi dulu.

Nama | Kota

Bob | Seattle

Nah sekarang karena gender tidak termasuk, saya akan menggunakan null. Varchars mendukung ini tanpa masalah.

Char di sisi lain berbeda. Anda selalu harus mengirim nol. Jika Anda pernah mengirim string kosong, Anda akan berakhir dengan bidang yang memiliki spasi di dalamnya.

Saya bisa terus-menerus dengan semua bug yang harus saya perbaiki dari karakter dan dalam sekitar 20 tahun pembangunan.

Mauro Torres
sumber
2

Ada beberapa overhead pemrosesan kecil dalam menghitung ukuran sebenarnya yang dibutuhkan untuk nilai kolom dan mengalokasikan ruang untuk Varchar, jadi jika Anda yakin berapa lama nilainya akan selalu, lebih baik menggunakan Char dan menghindari klik.

Guy Starbuck
sumber
2

Ini ruang klasik versus pengorbanan kinerja.

Dalam MS SQL 2005, Varchar (atau NVarchar untuk lanuagues membutuhkan dua byte per karakter yaitu Cina) adalah panjang variabel. Jika Anda menambah baris setelah ditulis ke hard disk, ia akan menempatkan data di lokasi yang tidak bertentangan dengan baris asli dan menyebabkan fragmentasi file data Anda. Ini akan mempengaruhi kinerja.

Jadi, jika ruang bukan masalah maka Char lebih baik untuk kinerja tetapi jika Anda ingin menjaga ukuran database turun maka varsar lebih baik.

Leo Moore
sumber
2

Fragmentasi. Char mencadangkan ruang dan VarChar tidak. Pemecahan halaman diperlukan untuk mengakomodasi pembaruan ke varchar.

paparazzo
sumber
Karena banyak faktor lain, pemisahan halaman dapat terjadi saat memperbarui CHARkolom.
Rick James
1

ketika menggunakan nilai-nilai varchar SQL Server membutuhkan tambahan 2 byte per baris untuk menyimpan beberapa info tentang kolom itu sedangkan jika Anda menggunakan char itu tidak perlu begitu kecuali Anda

SQLMenace
sumber
0

Dalam beberapa database SQL, VARCHAR akan diisi ke ukuran maksimum untuk mengoptimalkan offset, Ini untuk mempercepat pemindaian tabel penuh dan indeks.

Karena itu, Anda tidak memiliki penghematan ruang dengan menggunakan VARCHAR (200) dibandingkan dengan CHAR (200)

FlySwat
sumber
3
Database mana yang mengimplementasikan VARCHAR seperti itu?
Troels Arvin
5
Serius, basis data apa yang mengimplementasikannya seperti itu? Apa yang Anda gambarkan biasanya berlaku untuk CHAR, bukan VARCHAR.
Richard Simões
mysql akan mengonversi varchar menjadi chars jika ada char dan varchar di tabel yang sama.
Malfist
Interpretasi saya atas komentar MySQL adalah bahwa ini tidak berlaku untuk penyimpanan tabel utama, tetapi mungkin relevan untuk tabel temp misalnya. untuk pengelompokan / pengurutan data. dev.mysql.com/doc/refman/8.0/en/char.html stackoverflow.com/questions/262238/…
Thomas W
0

Menggunakan CHAR (NCHAR) dan VARCHAR (NVARCHAR) membawa perbedaan dalam cara server database menyimpan data. Yang pertama memperkenalkan trailing blanks; Saya mengalami masalah ketika menggunakannya dengan LIKE operator dalam fungsi SQL SERVER. Jadi saya harus membuatnya aman dengan menggunakan VARCHAR (NVARCHAR) setiap saat.

Misalnya, jika kita memiliki tabel TEST (ID INT, Status CHAR (1)) , dan Anda menulis fungsi untuk mendaftar semua catatan dengan beberapa nilai spesifik seperti berikut:

CREATE FUNCTION List(@Status AS CHAR(1) = '')
RETURNS TABLE
AS
RETURN
SELECT * FROM TEST
WHERE Status LIKE '%' + @Status '%'

Dalam fungsi ini kami berharap bahwa ketika kami menempatkan parameter default, fungsi akan mengembalikan semua baris, tetapi kenyataannya tidak. Ubah tipe data @Status ke VARCHAR akan memperbaiki masalah.

Tuan Le PN
sumber
Ini dapat diubah juga dengan ansi_padding Bagaimana nilai diambil
Edward