Apakah nilai kolom kosong menempati ruang penyimpanan yang sama dengan nilai kolom yang diisi?
15
Saya punya tabel dengan 2 kolom. Jenis kedua kolom diatur ke varchar(38). Jika saya membuat baris dengan nilai kosong untuk salah satu kolom, apakah akan mengambil ruang penyimpanan yang sama seolah-olah nilainya tidak kosong?
Dengan kata lain, akankah MySQL menyediakan ruang penyimpanan untuk kolom (tergantung pada jenisnya) ketika sebuah baris dibuat?
Nilai SQL NULL menyimpan satu atau dua byte di direktori rekaman. Selain itu, nilai SQL NULL cadangan nol byte di bagian data catatan jika disimpan dalam kolom panjang variabel . Dalam kolom panjang tetap, ia menyimpan panjang tetap kolom di bagian data catatan. Dengan menyimpan ruang tetap untuk nilai NULL memungkinkan pembaruan kolom dari NULL ke nilai non-NULL dilakukan di tempat tanpa menyebabkan fragmentasi halaman indeks.
Bagian panjang variabel dari header catatan berisi vektor bit untuk menunjukkan kolom NULL. Jika jumlah kolom dalam indeks yang bisa NULL adalah N, vektor bit menempati CEILING (N / 8) byte . (Misalnya, jika ada 9 hingga 15 kolom yang dapat berupa NULL, vektor bit menggunakan dua byte.) Kolom yang NULL tidak menempati ruang selain bit dalam vektor ini . Bagian panjang variabel dari header juga berisi panjang kolom panjang variabel. Setiap panjang membutuhkan satu atau dua byte, tergantung pada panjang maksimum kolom. Jika semua kolom dalam indeks BUKAN NULL dan memiliki panjang tetap, header catatan tidak memiliki bagian panjang variabel.
Berdasarkan poin-poin ini, berikut adalah NULLnilai yang digunakan untuk penyimpanan kolom
panjang variabel: nilai NULL tidak menggunakan penyimpanan di baris itu sendiri
panjang tetap: Mengambil ruang yang dipesan
Sekarang, Anda harus memutuskan antara menggunakan CHAR dan VARCHAR karena apa yang dibawa poin pertama
Dengan mempertahankan ruang tetap untuk nilai NULL memungkinkan pembaruan kolom dari NULL ke nilai non-NULL dilakukan di tempat tanpa menyebabkan fragmentasi halaman indeks
Halo Rolando, ada item lain yang saya lupa sebutkan, perbedaan alokasi memori antara deklarasi tipe varchar (5) dan varchar (100). Atau benar-benar penalti yang ditimbulkan karena alokasi berlebihan.
Craig Efrein
@CraigEfrein Anda harus menambahkan alokasi memori ke jawaban Anda. (BTW saya sudah
mengangkat
1
Hukuman untuk alokasi berlebihan terjadi ketika Anda memiliki kompleks SELECTyang perlu membuat tabel temp. Jika memungkinkan, ini akan digunakan MEMORY, dan dikonversi VARCHARke CHARuntuk tabel tmp. Sekarang VARCHAR(100)mengambil 100 (atau 300) byte yang diperbaiki, sehingga mungkin memperlambat permintaan.
Rick James
@RolandoMySQLDBA, Apakah perilaku yang dijelaskan dalam jawaban Anda berlaku untuk format baris Mysql 5.7 DINAMIK dan KOMPAK.
Ini hanya membahas ruang yang digunakan oleh kolom varchar dan tidak mempertimbangkan total ruang penyimpanan yang digunakan oleh baris, indeksnya, kunci primer dan kolom lainnya.
Seperti ypercube menyebutkan dalam komentarnya, ada pertimbangan tambahan untuk penyimpanan baris secara keseluruhan ketika setidaknya ada satu kolom yang dapat dibatalkan.
Bagian panjang variabel dari header catatan berisi vektor bit untuk menunjukkan kolom NULL. Jika ada 9 hingga 15 kolom yang bisa NULL, vektor bit menggunakan dua byte.)
...
Bagian panjang variabel dari header juga berisi panjang kolom panjang variabel. Setiap panjang membutuhkan satu atau dua byte, tergantung pada panjang maksimum kolom. Jika semua kolom dalam indeks BUKAN NULL dan memiliki panjang tetap, header catatan tidak memiliki bagian panjang variabel
Dan ya, ruang penyimpanan yang digunakan berubah berdasarkan pada jenis yang Anda pilih, apakah itu tetap atau variabel, pemeriksaan dan faktor-faktor lain seperti mesin.
Satu pertimbangan tambahan dengan varchar dan itu adalah memori. Penting dalam MySQL untuk membatasi ukuran kolom panjang variabel sebanyak mungkin. Meskipun kolomnya variabel dan ruang penyimpanan yang digunakan adalah variabel, MySQL akan mengalokasikan memori dalam bentuk potongan tetap untuk menyimpan nilai. Misalnya varchar (200) akan menggunakan lebih banyak memori yang varchar (5). Ini bukan masalah ruang penyimpanan, tetapi masih sesuatu yang perlu dipertimbangkan saat mendefinisikan kolom Anda.
SELECT
yang perlu membuat tabel temp. Jika memungkinkan, ini akan digunakanMEMORY
, dan dikonversiVARCHAR
keCHAR
untuk tabel tmp. SekarangVARCHAR(100)
mengambil 100 (atau 300) byte yang diperbaiki, sehingga mungkin memperlambat permintaan.Terlepas dari panjang yang Anda tentukan untuk kolom varchar Anda, ruang penyimpanan yang digunakan oleh kolom kosong akan sama.
Jenis CHAR dan VARCHAR
Ini hanya membahas ruang yang digunakan oleh kolom varchar dan tidak mempertimbangkan total ruang penyimpanan yang digunakan oleh baris, indeksnya, kunci primer dan kolom lainnya.
Seperti ypercube menyebutkan dalam komentarnya, ada pertimbangan tambahan untuk penyimpanan baris secara keseluruhan ketika setidaknya ada satu kolom yang dapat dibatalkan.
Struktur Baris Fisik Innodb
Dan ya, ruang penyimpanan yang digunakan berubah berdasarkan pada jenis yang Anda pilih, apakah itu tetap atau variabel, pemeriksaan dan faktor-faktor lain seperti mesin.
MySQL membuat rekomendasi untuk mengoptimalkan penyimpanan data di sini: Mengoptimalkan Ukuran Data
Memperbarui
Satu pertimbangan tambahan dengan varchar dan itu adalah memori. Penting dalam MySQL untuk membatasi ukuran kolom panjang variabel sebanyak mungkin. Meskipun kolomnya variabel dan ruang penyimpanan yang digunakan adalah variabel, MySQL akan mengalokasikan memori dalam bentuk potongan tetap untuk menyimpan nilai. Misalnya varchar (200) akan menggunakan lebih banyak memori yang varchar (5). Ini bukan masalah ruang penyimpanan, tetapi masih sesuatu yang perlu dipertimbangkan saat mendefinisikan kolom Anda.
sumber
CHARACTER SET
latin1 atau ascii. Untuk utf8, Storage WajibCHAR(4)
adalah 12.