Juga perlu diingat bahwa sering ada perbedaan yang sangat besar antara CHAR dan VARCHAR saat melakukan perbandingan indeks
Apakah ini berlaku / masih berlaku untuk Postgres?
Saya menemukan halaman-halaman di Oracle yang mengklaim CHARlebih atau kurang alias VARCHARdan karena itu kinerja indeksnya sama, tetapi saya tidak menemukan apa pun yang pasti di Postgres.
CHARdan VARCHARdiimplementasikan persis sama di Postgres (dan Oracle). Tidak ada perbedaan dalam kecepatan saat menggunakan tipe data tersebut.
Namun, ada satu perbedaan yang dapat membuat perbedaan dalam kinerja: charkolom selalu diisi dengan panjang yang ditentukan. Jadi jika Anda mendefinisikan kolom sebagai char(100)dan satu sebagai varchar(100)tetapi hanya menyimpan 10 karakter di masing-masing, char(100)kolom menggunakan 100 karakter untuk setiap nilai (10 karakter yang Anda simpan, ditambah 90 spasi), sedangkan varcharkolom hanya menyimpan 10 karakter.
Membandingkan 100 karakter dengan 100 karakter akan lebih lambat daripada membandingkan 10 karakter dengan 10 karakter - meskipun saya ragu Anda benar-benar dapat mengukur perbedaan ini dalam query SQL.
Jika Anda mendeklarasikan keduanya dengan panjang 10 karakter dan selalu menyimpan tepat 10 karakter di dalamnya, maka sama sekali tidak ada perbedaan apa pun (ini berlaku untuk Oracle dan Postgres)
Jadi satu-satunya perbedaan adalah padding yang dilakukan untuk chartipe data.
Juga perlu diingat bahwa sering ada perbedaan yang sangat besar antara CHAR dan VARCHAR saat melakukan perbandingan indeks
Kutipan di atas hanya benar jika (dan hanya jika) charkolom didefinisikan terlalu lebar (yaitu Anda membuang-buang ruang karena padding). Jika panjang charkolom selalu digunakan sepenuhnya (jadi tidak ada bantalan terjadi), maka kutipan di atas salah (setidaknya untuk Postgres dan Oracle)
Dari sudut pandang saya, chartipe data tidak benar-benar memiliki penggunaan kata nyata. Cukup gunakan varchar(atau textdi Postgres) dan lupakan yang charada.
Membandingkan 100 karakter dengan 100 karakter akan lebih lambat daripada membandingkan 10 karakter dengan 10 karakter - meskipun saya ragu Anda benar-benar dapat mengukur perbedaan ini dalam permintaan SQL. - Bergantung pada apa yang kueri lakukan selain mengurutkan, perbedaannya bisa sangat besar. Itu sebabnya Postgres 9.5 memiliki fitur "kunci disingkat" baru: pgeoghegan.blogspot.de/2015/01/...
chirlu
6
Saya setuju dengan semua yang dikatakan oleh a_horse_with_no_name, dan saya umumnya setuju dengan saran komentar Erwin:
Tidak, char lebih rendah (dan ketinggalan jaman). teks dan varchar melakukan (hampir) sama.
Metadata
Dengan satu pengecualian kecil, satu - satunya waktu yang saya gunakan char()adalah ketika saya ingin meta-data mengatakan ini HARUS memiliki x-karakter. Meskipun saya tahu bahwa char()hanya mengeluh jika inputnya melebihi batas, saya akan sering melindungi dari underruns dalam CHECKkendala. Sebagai contoh,
CREATETABLE foo (
x char(10)CHECK( length(x)=10));INSERTINTO foo VALUES(repeat('x',9));
Saya melakukan ini karena beberapa alasan,
char(x)kadang-kadang disimpulkan dengan skema-loader sebagai kolom dengan lebar tetap. Ini mungkin membuat perbedaan dalam bahasa yang dioptimalkan untuk string dengan lebar tetap.
Ini menetapkan konvensi yang masuk akal dan mudah ditegakkan. Saya dapat menulis skema-loader dalam bahasa untuk menghasilkan kode dari konvensi ini.
Perlu contoh di mana saya dapat melakukan ini,
Singkatan dua huruf, meskipun karena daftar ini dapat disebutkan, saya biasanya akan melakukannya dengan ENUM .
Perhatikan bahwa beberapa orang mungkin merasa tidak nyaman dengan ketidaksesuaian pesan kesalahan di kedua sisi batas, tetapi itu tidak mengganggu saya
test=#INSERTINTO foo VALUES(repeat('x',9));
ERROR: new rowfor relation "foo" violates checkconstraint"foo_x_check"
DETAIL: Failing rowcontains(xxxxxxxxx ).
test=#INSERTINTO foo VALUES(repeat('x',11));
ERROR: value too long for type character(10)
Kontras dengan varchar
Selain itu, saya pikir saran di atas sangat cocok dengan konvensi yang hampir selalu digunakantext . Anda bertanya tentang varchar(n)juga. Saya tidak pernah menggunakannya . Setidaknya, saya tidak ingat kapan terakhir kali saya menggunakan varchar(n).
Jika spec memiliki bidang lebar statis yang saya percayai, saya menggunakan char(n),
Kalau tidak, saya menggunakan textyang efektif varchar(tanpa batas)
Jika saya menemukan spec yang memiliki kunci teks panjang variabel yang bermakna dan saya percaya memiliki panjang maksimum konstan, saya akan menggunakan varchar(n) juga. Namun, saya tidak bisa memikirkan apa pun yang cocok dengan kriteria itu.
sales_reporting_db=#createtable x (y char(2));CREATETABLE
sales_reporting_db=#insertinto x values('Y');INSERT01
sales_reporting_db=#select'*'|| y ||'*'from x;?column?----------*Y*
Peramal
SQL>createtable x ( y char(2));Table created.
SQL>insertinto x values('Y');1row created.
SQL>select'*'|| y ||'*'from x;'*'|----*Y *
Saya setuju dengan semua yang dikatakan oleh a_horse_with_no_name, dan saya umumnya setuju dengan saran komentar Erwin:
Metadata
Dengan satu pengecualian kecil, satu - satunya waktu yang saya gunakan
char()
adalah ketika saya ingin meta-data mengatakan ini HARUS memiliki x-karakter. Meskipun saya tahu bahwachar()
hanya mengeluh jika inputnya melebihi batas, saya akan sering melindungi dari underruns dalamCHECK
kendala. Sebagai contoh,Saya melakukan ini karena beberapa alasan,
char(x)
kadang-kadang disimpulkan dengan skema-loader sebagai kolom dengan lebar tetap. Ini mungkin membuat perbedaan dalam bahasa yang dioptimalkan untuk string dengan lebar tetap.Perlu contoh di mana saya dapat melakukan ini,
ENUM
.Kesalahan
Perhatikan bahwa beberapa orang mungkin merasa tidak nyaman dengan ketidaksesuaian pesan kesalahan di kedua sisi batas, tetapi itu tidak mengganggu saya
Kontras dengan
varchar
Selain itu, saya pikir saran di atas sangat cocok dengan konvensi yang hampir selalu digunakan
text
. Anda bertanya tentangvarchar(n)
juga. Saya tidak pernah menggunakannya . Setidaknya, saya tidak ingat kapan terakhir kali saya menggunakanvarchar(n)
.char(n)
,text
yang efektifvarchar
(tanpa batas)Jika saya menemukan spec yang memiliki kunci teks panjang variabel yang bermakna dan saya percaya memiliki panjang maksimum konstan, saya akan menggunakan
varchar(n)
juga. Namun, saya tidak bisa memikirkan apa pun yang cocok dengan kriteria itu.Catatan tambahan
char
di sini tidak perlu bingung dengan"char"
yang merupakan tipe satu-byte dan memiliki kinerja yang solid dan manfaat penghematan ruang.Tanya Jawab terkait:
sumber
Postgresql
Peramal
Postgresql tidak pad dengan spasi.
sumber
SELECT pg_column_size(y) FROM x;
Saya menemukan ini paling berguna, dan penjelasan 3 baris cepat:
sumber