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.
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.
Jawaban:
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"
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.
Jika Anda bekerja dengan saya dan Anda bekerja dengan Oracle, saya mungkin akan membuat Anda menggunakannya varchar
di hampir setiap keadaan. Asumsi yang char
menggunakan 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 exists
lebih 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.
Selain manfaat kinerja, CHAR
dapat digunakan untuk menunjukkan bahwa semua nilai harus memiliki panjang yang sama, misalnya kolom untuk singkatan negara bagian AS.
CHAR
, Anda harus memastikan batasan diskon Anda.
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.
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
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.
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.
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.
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.
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.
CHAR
kolom, indeks juga perlu diperbarui. Tidak ada perbedaan dalam memperbarui kolom VARCHAR atau CHAR dalam hal itu. Pikirkan tentang memperbarui FOO
ke BAR
.
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.
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.
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.
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.
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.
Fragmentasi. Char mencadangkan ruang dan VarChar tidak. Pemecahan halaman diperlukan untuk mengakomodasi pembaruan ke varchar.
CHAR
kolom.
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)
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.