Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Tipe Data ENUM (Enumeration) di MySQL:12 Fakta Teratas dan Tips Berguna

Data MySQL ENUM adalah tipe data string dengan nilai yang dipilih dari daftar nilai yang diizinkan. Anda menetapkan nilai yang diizinkan ini selama pembuatan tabel seperti yang ditunjukkan di bawah ini:

CREATE TABLE Product
(
    id int NOT NULL PRIMARY KEY,
    productName varchar(30) NOT NULL,
    color enum('blue','red','yellow','black','white') NOT NULL DEFAULT 'blue'
);

Mudah bukan?

Sebagai permulaan, validasi data instan tanpa tabel lain dan kunci asing. Di bawah mode server yang ketat, ini berarti Anda tidak dapat memaksa entri yang salah. Ini bagus!

Atau itu?

Seperti hal lain di dunia, tidak selalu bahagia selamanya.

Setelah membaca 12 fakta kunci berikut tentang MySQL ENUM, Anda dapat memutuskan apakah itu bagus untuk database atau tabel berikutnya di MySQL.

Untuk artikel ini, versi MySQL adalah 8.0.23, dan mesin penyimpanannya adalah InnoDB.

1. MySQL ENUM adalah Jenis Pasangan Nilai Kunci/String

MySQL ENUM adalah pasangan kunci/nilai. Nilai adalah string, dan kunci adalah nomor indeks.

Tapi di mana indeksnya?

MySQL secara otomatis memberikan nomor saat muncul di daftar Anda. Jadi, apakah itu tentang daftar warna, jenis pelanggan, salam, atau metode pembayaran, nomor akan diberikan. Itu adalah daftar tetap yang tidak akan pernah berkembang. Pikirkan 20 item atau lebih sedikit dan nilai yang tidak akan pernah memiliki atribut lebih lanjut. Jika tidak, Anda memerlukan meja.

Tapi bagaimana indeks ini diberi nomor?

2. Indeks MySQL ENUM Dimulai dengan 1 Tapi Bisa NULL atau Nol

Saya akan mulai dengan sebuah contoh.

CREATE TABLE people
(
  id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
  lastname varchar(30) NOT NULL,
  firstname varchar(30) NOT NULL,
  middlename varchar(30) NOT NULL,
  gender enum('Male','Female') NOT NULL DEFAULT 'Female',
  country enum('United States', 'Canada', 'Brazil', 
               'United Kingdom','Poland','Ukraine', 'Lithuania',  
               'Japan','Philippines','Thailand', 'Australia','New Zealand')  
              DEFAULT 'United States',
  modifieddate datetime NOT NULL DEFAULT NOW() 
);

Ada 2 nilai MySQL ENUM di sini: gender dan negara . Mari saya mulai dengan gender kolom yang berisi 2 nilai:Pria dan Wanita . Indeks untuk Pria adalah 1, dan Wanita adalah 2. Ini berarti bahwa indeks kunci dimulai dengan 1.

Dari contoh sederhana ini, Anda dapat mengidentifikasi indeks untuk negara kolom. Ini memiliki 12 nilai. Dimulai dengan Amerika Serikat dengan indeks 1 dan diakhiri dengan Selandia Baru dengan indeks 12.

Catatan :indeks ini tidak mengacu pada indeks tabel yang kami gunakan untuk penelusuran cepat.

Selain angka-angka ini dari 1 hingga 65.535, kolom ENUM juga bisa NULL atau nol. Dalam contoh kami, negara kolom menerima NULL. Jadi, selain indeks 1 sampai 12, NULL adalah indeks lain yang mungkin dengan nilai NULL.

Anda juga dapat memiliki 0 index. Ini terjadi dalam situasi berikut:

  • Mode server untuk MySQL Anda tidak ketat.
  • Anda memasukkan nilai yang tidak ada dalam daftar nilai yang diizinkan.
  • Kemudian, penyisipan akan berhasil, tetapi nilainya adalah string kosong dengan indeks nol.

Untuk menghindari kesalahan, selalu gunakan mode server yang ketat.

3. MySQL ENUM Membatasi Kemungkinan Nilai dalam Kolom

Dalam mode ketat, negara kolom dalam contoh kita sebelumnya hanya akan menerima 12 kemungkinan nilai. Jadi, jika Anda mencoba melakukan ini, kesalahan "Data terpotong untuk kolom 'negara'" akan muncul:

INSERT INTO people (lastname, firstname, middlename, gender, country)
  VALUES ('Choi', 'Seungcheol', '','Male','South Korea');

Pesan kesalahan di bawah ini terjadi karena Korea Selatan tidak ada dalam daftar enumerated.

Pesan kesalahannya sama seperti di MySQL Workbench.

Jika Server MySQL yang digunakan di sini peka huruf besar/kecil, ini juga tidak akan diterima:

INSERT INTO people (lastname, firstname, middlename, gender, country)
  VALUES ('Hemsworth', 'Chris', '', 'MALE', 'united states');

Mengapa? Kami mendefinisikan jenis kelamin sebagai Laki-laki , bukan MALE . Dan negaranya adalah Amerika Serikat , bukan Amerika Serikat.

Pada akhirnya, nilai enumerasi dalam tipe data MySQL ENUM bertindak seperti batasan kunci asing tetapi tanpa tabel lain.

Selain itu, ada manfaat lain yang disediakan data MySQL ENUM.

4. Output Ramah Tanpa Menggunakan JOIN

Tidak perlu BERGABUNG, tetapi hasilnya ramah. Mari kita ambil contoh ENUM di MySQL di bawah ini untuk menjelaskannya:

SELECT * FROM people 
WHERE country = 4;

Kueri ini akan mengambil orang dari Inggris Raya. Secara default, Anda melihat string yang Anda tentukan di kolom ENUM. Tetapi secara internal, indeks bernomor disimpan. Ini hasilnya:

Catatan :Data yang Anda lihat dibuat menggunakan dbForge Studio untuk alat penghasil data MySQL. Saya membuat 50.000 nama menggunakan alat ini.

Sementara itu, output yang sama dapat dicapai saat menggunakan tabel dan gabungan terpisah.

SELECT
 p.id
,p.lastname
,p.firstname
,p.middlename
,CASE WHEN p.gender = 'M' THEN 'Male' ELSE 'Female' END AS gender
,c.countryname AS country
,p.modifieddate
FROM people_no_enums p
LEFT JOIN country c ON p.country = c.id
WHERE p.country = 4;

Jadi, haruskah Anda menggunakan MySQL ENUM untuk menghindari GABUNG sama sekali? Tentu saja tidak! Ini bagus untuk daftar kecil tapi tetap. Lebih banyak data dengan jumlah baris yang tidak terbatas dan lebih banyak atribut memerlukan tabel. Dan untuk membuat output yang lebih bersahabat seperti pada Gambar 2, Anda juga memerlukan JOIN. Memiliki tabel terpisah lebih fleksibel dan tidak memerlukan apa pun dari pengembang saat data ditayangkan. Ini tidak terjadi dengan Enumdatatype.

5. Filter Enumerasi MySQL berdasarkan Indeks atau Nilai String

Pada poin #4, Anda melihat contoh dengan klausa WHERE untuk difilter dengan kolom ENUM. Itu menggunakan indeks untuk menentukan negara. Jadi, ini juga akan berhasil:

SELECT * from people
WHERE country IN (1,3,5)
AND gender = 1;

Anda juga dapat menggunakan nilai string, seperti di bawah ini:

SELECT * FROM people 
WHERE country='Philippines'
AND gender = 'Female';

6. Pengurutan berdasarkan Indeks

Penyortiran bisa sedikit rumit. Nilai ENUM disimpan menurut nomor indeksnya, bukan nilainya. Lihat kode di bawah ini dan output yang mengikuti pada Gambar 3.

SELECT DISTINCT 
 country AS CountryName
,country + 0 AS CountryId
FROM people
ORDER BY country;

Jika Anda ingin pengurutan berdasarkan nilai, masukkan kolom ke CHAR, seperti di bawah ini.

SELECT DISTINCT 
 country AS CountryName
,country + 0 AS CountryId
FROM people
ORDER BY CAST(country AS char);

Bagaimana dengan ini?

SELECT DISTINCT 
 country AS CountryName
,country + 0 AS CountryId
FROM people
ORDER BY CountryName;

Dari tampilannya, nilai akan digunakan untuk menyortir. Tapi itu tidak terjadi. Outputnya akan sama seperti pada Gambar 3. ORDER BY dengan CAST adalah cara terbaik untuk mengurutkan berdasarkan nilai.

7. Penyimpanan MySQL ENUM Hanya Hingga 2 Bytes

Menurut dokumentasi resmi, penyimpanan default MySQL ENUM melibatkan file index. Tabel yang dihasilkan lebih kompak dibandingkan dengan menyimpan nilai. Satu (1) byte untuk enumerasi dengan 1 hingga 255 kemungkinan nilai. Dua (2) byte untuk 256 hingga 65.535 kemungkinan nilai.

Tapi ada rahasia yang ingin kuberitahukan padamu.

Tentu saja, ketika menyangkut penyimpanan, nilai akan menempati lebih dari indeks. Karena desain tabel yang tepat menghasilkan jejak penyimpanan yang lebih kecil, mari buat tabel lain dengan tabel negara terpisah.

CREATE TABLE country
(
   id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
   countryname varchar(30) NOT NULL,
   modifieddate datetime DEFAULT NOW()
);

CREATE TABLE people_no_enums
(
  id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
  lastname varchar(30) NOT NULL,
  firstname varchar(30) NOT NULL,
  middlename varchar(30) NOT NULL,
  gender char(1) not NULL,
  country tinyint DEFAULT 1,
  modifieddate datetime NOT NULL DEFAULT NOW() 
);

Sekarang, mari kita masukkan data yang sama.

INSERT INTO country (id, countryname, modifieddate)
  VALUES (1, 'United States', NOW()), (2, 'Canada', NOW()), (3, 'Brazil', NOW()), 
         (4, 'United Kingdom', NOW()), (5, 'Poland', NOW()), (6, 'Ukraine', NOW()), 
         (7, 'Lithuania', NOW()), (8, 'Japan', NOW()), (9, 'Philippines', NOW()), 
         (10, 'Thailand', NOW()), (11, 'Australia', NOW()), 
         (12, 'New Zealand', NOW());

INSERT INTO people_no_enums
SELECT
 p.id
,p.lastname
,p.firstname
,p.middlename
,CASE WHEN p.gender = 1 THEN 'M' ELSE 'F' END AS gender
,c.id
,p.modifieddate
FROM people p
LEFT JOIN country c ON p.country = c.countryname;

Untuk melakukannya, kami menggunakan tabel INFORMATION_SCHEMA.TABLES. Lihat kode di bawah ini:

SELECT
table_name,
ROUND(((data_length + index_length)), 2) AS "Size in Bytes"
FROM information_schema.TABLES
WHERE table_schema = "testenumsdb"
AND TABLE_NAME LIKE 'people%'
ORDER BY (data_length + index_length) DESC;

Tabel yang dinormalisasi tanpa kolom ENUM dibandingkan dengan tabel dengannya memerlukan ukuran yang sama dalam byte. Keduanya memiliki 50.000 catatan dengan nama yang sama menggunakan mesin penyimpanan InnoDB. Tapi tentu saja, negara yang baru meja akan menempati ruang juga. Anda perlu mempertimbangkan keuntungan dan kerugian lain dari penggunaan ENUM.

8. MySQL ENUM hanya untuk Literal String

MySQL ENUM hanya menerima literal string. Jadi, kode di bawah ini tidak akan berfungsi:

CREATE TABLE Product
(
   id int NOT NULL PRIMARY KEY,
   productName varchar(30),
   color enum('red','orange',CONCAT('red','orange'))
);

Fungsi CONCAT di dalam Enumdatatype tidak diizinkan serta ekspresi SQL valid lainnya.

9. MySQL ENUM Tidak Dapat Digunakan Kembali

Dari titik ini, Anda akan melihat sisi gelap MySQL ENUM.

Pertama, Anda tidak dapat menggunakannya kembali. Anda harus menduplikasi warna, ukuran, dan enumerasi prioritas yang sama jika Anda membutuhkannya di tabel lain. Desain seperti pada Gambar 6 di bawah ini tidak mungkin dilakukan dengan ENUM.

Untuk menggunakan ENUM pada 2 tabel di atas, Anda perlu menduplikasi daftar prioritas pada 2 tabel.

10. Menambahkan Lebih Banyak Nilai Membutuhkan Mengubah Tabel

Dalam gender list sebelumnya, kami mencoba menggunakan 2 item saja:Pria dan Wanita . Bagaimana jika perusahaan Anda memutuskan untuk merangkul LGBTQ? Anda perlu menjalankan ALTER TABLE dan menambahkan ke akhir enumerasi Lesbian , Gay , Biseksual , Transgender , dan Aneh . Ini kodenya:

ALTER TABLE people
   MODIFY COLUMN gender     
          enum('Male','Female','Lesbian','Gay','Bisexual','Transgender','Queer')     
          NOT NULL DEFAULT 'Male';

Menjalankan ini di laptop saya dengan 50.000 catatan hanya membutuhkan waktu kurang dari satu detik. Tabel yang lebih besar dan lebih kompleks akan menghabiskan lebih banyak waktu. Jika daftar gender berupa tabel, Anda hanya perlu memasukkan 5 nilai baru.

Mengganti nama suatu nilai juga membutuhkan ALTER TABLE. Tabel terpisah hanya membutuhkan pernyataan UPDATE yang mudah.

11. Anda Tidak Dapat Dengan Mudah Membuat Daftar Nilai yang Mungkin

Apakah Anda mengisi daftar dropdown atau tombol radio yang dikelompokkan dari sebuah tabel? Sangat mudah ketika Anda memiliki meja negara. Lakukan SELECT id , nama negara DARI negara , dan Anda siap mengisi daftar tarik-turun.

Tapi bagaimana Anda akan melakukannya dengan MySQL ENUM?

Pertama, dapatkan informasi kolom dari tabel INFORMATION_SCHEMA.COLUMNS, seperti ini:

/* Get the possible values for country ENUM. */
SELECT  
 TABLE_NAME
,COLUMN_NAME
,COLUMN_TYPE
FROM information_schema.columns
WHERE TABLE_SCHEMA='testenumsdb'
  AND TABLE_NAME = 'people'
  AND COLUMN_NAME = 'country';

Kemudian, Anda harus mengurai string itu dan memformatnya sebelum Anda mengisi daftar dropdown. Cukup kuno, bukan?

Tapi ada satu hal terakhir.

12. MySQL ENUM Tidak Standar

ENUM adalah ekstensi MySQL ke standar ANSI SQL. Produk RDBMS lainnya tidak mendukung ini. Jadi, lihat tutorial MySQL yang sesuai sebelum memulai proyek Anda. Jika Anda perlu mem-port database MySQL Anda yang penuh dengan ENUM ke SQL Server, misalnya, Anda perlu melakukan solusi. Solusinya akan bervariasi tergantung pada bagaimana Anda mendesain tabel target di SQL Server.

Intinya

Anda harus mempertimbangkan pro dan kontra menggunakan MySQL ENUM. Memiliki tabel terpisah dengan normalisasi yang tepat diterapkan adalah yang paling fleksibel di masa depan yang tidak pasti.

Kami menyambut poin tambahan. Jadi, buka bagian Komentar di bawah dan beri tahu kami tentang hal itu. Anda juga dapat membagikan ini di platform media sosial favorit Anda.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menampilkan kueri terakhir yang dieksekusi di MySQL?

  2. MAKEDATE() Contoh – MySQL

  3. MySQL vs MySQLi saat menggunakan PHP

  4. Cara Mengatur Ulang Kata Sandi Root MySQL

  5. Praktik Terbaik dalam Penskalaan Basis Data:Bagian 1