MySQL, lebih baik memasukkan NULL atau string kosong?

230

Saya memiliki formulir di situs web yang memiliki banyak bidang berbeda. Beberapa kolom bersifat opsional, sementara beberapa lainnya wajib. Dalam DB saya, saya memiliki tabel yang menampung semua nilai-nilai ini, apakah lebih baik praktik untuk memasukkan nilai NULL atau string kosong ke dalam kolom DB di mana pengguna tidak menaruh data apa pun?

roflwaffle
sumber

Jawaban:

220

Dengan menggunakan NULLAnda dapat membedakan antara "tidak ada data" dan "masukkan data kosong".

Beberapa perbedaan lagi:

  • A LENGTHdari NULLadalah NULL, LENGTHdari string kosong adalah 0.

  • NULLs diurutkan sebelum string kosong.

  • COUNT(message)akan menghitung string kosong tetapi tidak NULLs

  • Anda dapat mencari string kosong menggunakan variabel terikat tetapi tidak untuk NULL. Kueri ini:

    SELECT  *
    FROM    mytable 
    WHERE   mytext = ?

    tidak akan pernah cocok dengan NULLdi mytext, apa pun nilai Anda lulus dari klien. Untuk mencocokkan NULLs, Anda harus menggunakan permintaan lain:

    SELECT  *
    FROM    mytable 
    WHERE   mytext IS NULL
Quassnoi
sumber
3
tapi mana yang menurut Anda lebih cepat? 0 atau NULL atau ""
Atul Dravid
8
di InnoDB NULL membutuhkan lebih sedikit ruang
Timo Huovinen
37
Saya pikir ini adalah jawaban yang oke, tetapi juga benar-benar mengabaikan elemen "praktik terbaik" dari pertanyaan dan hanya berfokus pada fakta-fakta yang relevan secara tangensial (urutan dan panjang NULL? Ini tidak masalah). Pada sebagian besar tipe input data teks tidak ada perbedaan antara "tidak ada respons" dan "respons kosong", jadi saya pikir ini adalah pertanyaan hebat yang pantas mendapatkan jawaban yang lebih baik.
Nick
6
NULLs juga berfungsi dengan baik ketika bidang UNIQUE diatur. Misalnya jika Anda memiliki bidang seperti SIM untuk menambahkan Nomor DL ​​seseorang dan orang itu tidak memilikinya. Karena ini adalah bidang unik, orang pertama tanpa DL No. akan ditambahkan tetapi bukan yang berikutnya karena akan menampilkan kesalahan batasan unik. Jadi, NULL lebih baik.
Saifur Rahman Mohsin
1
@ Quassnoi ah maaf ... maksud saya, mengapa praktik yang buruk menetapkan lisensi mengemudi sebagai unik ...?
cedbeu
44

Satu hal yang perlu dipertimbangkan, jika Anda pernah berencana untuk beralih database, adalah bahwa Oracle tidak mendukung string kosong . Mereka dikonversi ke NULL secara otomatis dan Anda tidak dapat meminta mereka menggunakan klausa seperti WHERE somefield = ''.

Matt Solnit
sumber
11
Ini terdengar sangat mencurigakan bagi saya, bahkan pada tautan Anda, jadi saya mencobanya. Bidang kosong, setel ke '', oracle mengabaikannya. Panjang laporan sebagai nol daripada 0. Itu sangat salah. Pasti ada jalan keluarnya. Pikir saya akan memposting ini sebagai pertanyaan lain.
Steve B.
1
Steve B.: lihat pertanyaan ini: stackoverflow.com/questions/1171196/…
Quassnoi
Terima kasih untuk referensi, meskipun saya masih tidak mengerti alasannya. Diposting sebagai stackoverflow.com/questions/1268177/...
Steve B.
Mungkin patut memperbarui jawaban untuk memasukkan info dari tautan yang diposting oleh Quassnoi
SamuelKDavis
7
Peoplesoft (dengan Oracle DB) menggunakan satu ruang untuk menunjukkan nilai kosong. Sangat bodoh. Mereka juga menggunakan 0,00025 untuk menunjukkan 0 untuk FTE karena 0 tidak diperbolehkan. Pilihan yang indah dibuat dalam produk itu.
JP Duffy
9

Satu hal yang perlu diingat adalah bahwa NULL dapat membuat codepath Anda jauh lebih sulit. Dalam Python misalnya sebagian basis data adapter / ORMs peta NULLuntukNone .

Jadi hal-hal seperti:

print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow

mungkin menghasilkan "Halo, Tidak Ada Joe Doe!" Untuk menghindarinya Anda perlu kode seperti ini:

if databaserow.title:
    print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow
else:
    print "Hello, %(firstname) %(lastname)!" % databaserow

Yang dapat membuat segalanya menjadi lebih kompleks.

maks
sumber
25
Menurut pendapat saya menyalahgunakan basis data Anda untuk "memperbaiki" kesalahan dalam kode Anda atau kerangka kerja adalah praktik pengkodean yang sangat buruk. Ketika tidak ada data, Anda harus menyisipkan NULL dan konsisten menggunakannya. Kalau tidak, Anda harus menggunakan pernyataan seperti: if (myString == null || myString = ""). Ketika suatu objek tidak diatur atau didefinisikan dalam kode Anda, Anda juga menggunakan NULL alih-alih semacam "placeholder" (yang merupakan string kosong menurut pendapat saya).
Gertjan
5
Sangat tergantung pada Bahasa pilihan Anda. Dalam Python "jika bukan myString:" tes untuk None dan "". Mungkin terutama masalah budaya. "Praktek buruk" Orang Jawa adalah keanggunan orang yang dinamis.
maks
9

Lebih baik untuk memasukkan NULLkonsistensi dalam database Anda di MySQL. Kunci asing dapat disimpan sebagai NULLtetapi BUKAN sebagai string kosong.

Anda akan memiliki masalah dengan string kosong di kendala. Anda mungkin harus memasukkan catatan palsu dengan string kosong yang unik untuk memenuhi batasan Kunci Asing. Latihan yang buruk kurasa.

Lihat juga: Bisakah kunci asing NULL dan / atau duplikat?

micaball
sumber
Masalah kendala telah membuat saya tersandung di masa lalu sehingga itu sebabnya saya "memberi +1" jawaban ini.
HPWD
Tetapi jika Anda menggunakan NULL pastikan Anda tidak pernah berakhir dengan string kosong juga. Mudah dilakukan dengan banyak teknologi UI.
Tuntable
5

Saya tidak tahu praktik terbaik apa yang akan ada di sini, tetapi saya biasanya akan memilih null, kecuali jika Anda ingin null berarti sesuatu yang berbeda dari string kosong, dan input pengguna cocok dengan definisi string kosong Anda.

Perhatikan bahwa saya mengatakan ANDA perlu mendefinisikan bagaimana Anda ingin mereka berbeda. Terkadang masuk akal untuk membuatnya berbeda, kadang tidak. Jika tidak, pilih saja dan pertahankan. Seperti yang saya katakan, saya cenderung lebih menyukai NULL.

Oh, dan ingatlah bahwa jika kolom adalah nol, catatan cenderung muncul dalam hampir semua kueri yang memilih (memiliki klausa mana, dalam istilah SQL) yang didasarkan pada kolom itu, kecuali jika pemilihannya untuk kolom nol tentu saja.

Platinum Azure
sumber
1
... Dan sekarang saya melihat jawaban di atas saya, saya pikir aman untuk mengatakan bahwa perbedaan yang biasa Anda pedulikan adalah tidak ada data versus data kosong. :-)
Platinum Azure
1

Jika Anda menggunakan beberapa kolom dalam indeks unik dan setidaknya salah satu dari kolom ini adalah wajib (yaitu bidang formulir yang diperlukan), jika Anda mengatur kolom lain dalam indeks ke NULL, Anda mungkin berakhir dengan baris duplikat. Itu karena nilai NULL diabaikan dalam kolom unik. Dalam hal ini, gunakan string kosong di kolom lain dari indeks unik untuk menghindari baris yang digandakan.

KOLOM DALAM INDEKS UNIK:
(event_type_id, event_title, tanggal, lokasi, url)

CONTOH 1:
(1, 'BBQ', '2018-07-27', null, null)
(1, 'BBQ', '2018-07-27', null, null) // diizinkan dan digandakan.

CONTOH 2:
(1, 'BBQ', '2018-07-27', '', '')
(1, 'BBQ', '2018-07-27', '', '') // TIDAK diizinkan karena sudah digandakan.

Berikut ini beberapa kode:

CREATE TABLE `test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `event_id` int(11) DEFAULT NULL,
  `event_title` varchar(50) DEFAULT NULL,
  `date` date DEFAULT NULL,
  `location` varchar(50) DEFAULT NULL,
  `url` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `event_id` (`event_id`,`event_title`,`date`,`location`,`url`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Sekarang masukkan ini untuk melihatnya akan memungkinkan baris yang digandakan:

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-27', NULL, NULL);

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-27', NULL, NULL);

Sekarang masukkan ini dan periksa apakah itu tidak diizinkan:

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-28', '', '');

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-28', '', '');

Jadi, tidak ada yang benar atau salah di sini. Terserah Anda memutuskan mana yang paling sesuai dengan aturan bisnis Anda.

João Marques
sumber