Berapa ukuran nilai "Null" di SQL Server


118

Saya memiliki meja besar dengan katakanlah 10 kolom. 4 dari mereka tetap nol sebagian besar waktu. Saya memiliki kueri yang tidak mengambil ukuran apa pun atau tidak ada ukuran dalam byte. Saya membaca beberapa artikel yang beberapa di antaranya mengatakan:

http://www.sql-server-citation.com/2009/12/common-mistakes-in-sql-server-part-4.html

Ada kesalahpahaman bahwa jika kita memiliki nilai NULL dalam tabel itu tidak menempati ruang penyimpanan. Faktanya adalah, nilai NULL menempati ruang - 2 byte

SQL: Menggunakan nilai NULL vs. nilai default

Sebuah NULLnilai dalam database adalah sistem nilai yang mengambil satu byte dari penyimpanan dan menunjukkan bahwa nilai yang tidak hadir sebagai lawan dari ruang atau nol atau nilai default lainnya.

Bisakah Anda membimbing saya mengenai ukuran yang diambil oleh nilai nol.

Jawaban:


146

Jika bidang memiliki lebar tetap, penyimpanan NULL mengambil ruang yang sama dengan nilai lainnya - lebar bidang.

Jika bidang memiliki lebar variabel, nilai NULL tidak membutuhkan ruang.

Selain ruang yang dibutuhkan untuk menyimpan nilai null, ada juga overhead untuk memiliki kolom nullable. Untuk setiap baris, satu bit digunakan per kolom nullable untuk menandai apakah nilai untuk kolom itu null atau tidak. Ini benar apakah panjang kolom tetap atau variabel.


Alasan perbedaan yang Anda amati dalam informasi dari sumber lain:

  • Awal artikel pertama agak menyesatkan. Artikel ini tidak berbicara tentang biaya penyimpanan nilai NULL, tetapi biaya memiliki kemampuan untuk menyimpan NULL (yaitu biaya pembuatan kolom nullable). Memang benar bahwa ada biaya dalam ruang penyimpanan untuk membuat kolom menjadi nullable, tetapi setelah Anda selesai, dibutuhkan lebih sedikit ruang untuk menyimpan NULL daripada yang diperlukan untuk menyimpan nilai (untuk kolom lebar variabel).

  • Tautan kedua sepertinya adalah pertanyaan tentang Microsoft Access. Saya tidak tahu detail bagaimana Access menyimpan NULL tetapi saya tidak akan terkejut jika itu berbeda dengan SQL Server.


1
@Mark "Memang benar bahwa ada biaya dalam ruang penyimpanan untuk membuat kolom menjadi nullable, tetapi setelah Anda selesai, dibutuhkan lebih sedikit ruang untuk menyimpan NULL daripada yang diperlukan untuk menyimpan nilai (untuk kolom lebar variabel)" Dengan ini yang Anda maksud untuk mengatakan itu membutuhkan 1 bit sebagai ukuran yang diambil dalam memori untuk tipe data variabel.
Rocky Singh

13
Unit memori terkecil yang dapat dialamatkan di sebagian besar sistem komputer adalah satu byte(biasanya 8 bit). Jadi pada kenyataannya, a bitmengambil a byte. Jawaban bagus Mark: +1.
JohnB

20
Namun, bit kedua, dan bit ketiga, dan hingga bit kedelapan cocok dalam byte yang sama.
Matti Virkkunen

1
@ Mark - Ya, itu terlihat jauh lebih jelas. Permintaan maaf atas komentar yang menghilang. Saya bermaksud merevisinya tetapi Koneksi Internet saya terputus antara penghapusan dan pengiriman! Ini juga bergantung sedikit (Dari bagian komentar di sini) "Untuk heap dan catatan indeks berkerumun, selalu ada bitmap NULL. Untuk indeks non-cluster, tidak akan ada jika semua kolom dalam indeks BUKAN NULL."
Martin Smith

2
@ Martin Smith: Saya tidak tahu itu. Itu membuat segalanya menjadi lebih rumit karena jika saya memahaminya dengan benar itu berarti membuat kolom nullable tidak menambah ruang penyimpanan yang diperlukan (karena bitmap null selalu ada) kecuali kolom itu juga ada dalam indeks dan kolom lain di indeks tidak dapat dibatalkan. Dalam hal ini indeks sekarang harus menyertakan bitmap nol.
Mark Byers

30

Tautan berikut mengklaim bahwa jika kolom memiliki panjang variabel, yaitu varcharkemudian NULLmengambil 0 byte (ditambah 1 byte digunakan untuk menandai apakah nilainya NULLatau tidak):

Tautan di atas, serta tautan di bawah, mengklaim bahwa untuk kolom dengan panjang tetap, yaitu char(10)atau int, nilai NULLmenempati panjang kolom (ditambah 1 byte untuk menandai apakah itu NULLatau tidak):

Contoh:

  1. Jika Anda menyetel char(10)keNULL , itu menempati 10 byte (nol)
  2. Sebuah int membutuhkan 4 byte (juga dikosongkan).
  3. Satu varchar(1 million)set NULLmembutuhkan 0 byte (+ 2 byte)

Catatan: sedikit bersinggungan, ukuran penyimpanan varcharadalah panjang data yang dimasukkan + 2 byte.


Bukankah varchar yang menyimpan NULL membutuhkan 0 + 2 + 1 (NULL overhead) byte?
Akash

Ini harus + 1 bit untuk menandai NULL. @ Akash: 2 byte seharusnya tidak diperlukan karena bitmap sudah menandai nilainya sebagai NULL (tidak ada info yang akan ditambahkan).
Simo Kivistö

5

Dari tautan ini :

Setiap baris memiliki bitmap nol untuk kolom yang memungkinkan null. Jika baris di kolom itu nol maka bit di bitmap adalah 1 selain itu 0.

Untuk tipe data ukuran variabel, ukuran akrual adalah 0 byte.

Untuk tipe data ukuran tetap, ukuran akrual adalah ukuran tipe data default dalam byte yang disetel ke nilai default (0 untuk angka, '' untuk karakter).


Maksud Anda mengatakan untuk tipe data seperti nvarchar (max) varchar (max) Null akan membutuhkan 0 byte dan untuk int, karakter dll itu akan mengambil ukuran default ke nilai default yang mereka miliki?
Rocky Singh

4

Menyimpan nilai NULL tidak memakan tempat.

"Faktanya adalah, nilai NULL menempati ruang - 2 byte."

Ini adalah kesalahpahaman - itu 2 byte per baris , dan saya cukup yakin bahwa semua baris menggunakan 2 byte itu terlepas dari apakah ada kolom nullable.

Nilai NULL dalam database adalah nilai sistem yang membutuhkan satu byte penyimpanan

Ini berbicara tentang database secara umum, bukan secara khusus SQL Server. SQL Server tidak menggunakan 1 byte untuk menyimpan nilai NULL.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.