Tabel adalah wadah utama data di dalam basis data relasional, dan pernyataan CREATE TABLE adalah pernyataan yang mendeklarasikan tabel tersebut. Topik ini membahas anatomi CREATE TABLE pada MySQL 8.0, mulai dari mendeklarasikan kolom beserta tipenya, menetapkan nilai bawaan dengan DEFAULT, sampai membaca kembali definisi tabel melalui SHOW CREATE TABLE. Seluruh contoh memakai basis data perpustakaan yang memuat tabel anggota dan buku, sehingga setiap keputusan tipe dan nilai bawaan dapat diuji langsung dengan klien mysql.
Struktur dasar pernyataan CREATE TABLE#
Pernyataan CREATE TABLE menyebut nama tabel terlebih dahulu, lalu memuat daftar definisi kolom di dalam tanda kurung. Setiap definisi kolom terdiri atas nama kolom, tipe data, dan atribut tambahan seperti NOT NULL atau DEFAULT. Deklarasi kunci seperti PRIMARY KEY ditulis setelah daftar kolom, sedangkan opsi tabel seperti ENGINE=InnoDB ditulis di akhir pernyataan. Kerangka umumnya terlihat seperti berikut.
-- tidak-dijalankan
CREATE TABLE nama_tabel (
kolom_1 TIPE_DATA atribut,
kolom_2 TIPE_DATA atribut,
PRIMARY KEY (kolom_1)
) ENGINE=InnoDB;Seluruh topik di modul ini memakai satu berkas skema yang sama sebagai titik berangkat. Berkas diawali DROP DATABASE IF EXISTS dan CREATE DATABASE agar setiap eksekusi memulai ulang dari keadaan yang sama, lalu membuat tabel anggota dan buku.
-- tidak-dijalankan
DROP DATABASE IF EXISTS perpustakaan;
CREATE DATABASE perpustakaan;
USE perpustakaan;
CREATE TABLE anggota (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
nama VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL,
tanggal_bergabung DATE,
status VARCHAR(20) NOT NULL DEFAULT 'aktif',
PRIMARY KEY (id)
) ENGINE=InnoDB;
CREATE TABLE buku (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
kode_buku VARCHAR(12) NOT NULL,
judul VARCHAR(200) NOT NULL,
penulis VARCHAR(100) NOT NULL,
tahun SMALLINT UNSIGNED,
stok INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
) ENGINE=InnoDB;Jalankan perintah berikut untuk mengeksekusi berkas skema tersebut. Perintah DDL melalui klien dalam mode batch tidak mencetak apa pun ketika berhasil, sehingga keberhasilannya diverifikasi dengan SHOW TABLES.
# membuat ulang basis data perpustakaan dari nol
mysql -u root < skema-perpustakaan.sql# memeriksa daftar tabel hasil eksekusi skema
mysql -t -u root perpustakaan -e "SHOW TABLES"+------------------------+
| Tables_in_perpustakaan |
+------------------------+
| anggota |
| buku |
+------------------------+Memilih tipe dan panjang kolom#
Tipe data menentukan rentang nilai yang dapat disimpan dan ruang penyimpanan per baris, sehingga pilihan tipenya diambil dari kebutuhan data, bukan dari kebiasaan menulis. Kolom nama memakai VARCHAR(100) karena nama lengkap orang jarang melebihi seratus karakter, sedangkan kolom email diberi ruang lebih longgar pada VARCHAR(150). Kolom tanggal_bergabung memakai tipe DATE karena nilainya hanya tanggal tanpa komponen waktu.
Kolom numerik memakai UNSIGNED apabila nilainya tidak mungkin negatif. Kolom tahun bertipe SMALLINT UNSIGNED yang memuat rentang 0 sampai 65535, rentang yang lebih dari cukup untuk tahun terbit buku. Kolom stok dan kedua kolom id memakai INT UNSIGNED karena jumlah dan penomoran sama-sama tidak mengenal nilai negatif. Dengan UNSIGNED, rentang positif yang tersedia menjadi dua kali lebih lebar, dan angka negatif yang tidak masuk akal ditolak langsung oleh server pada tipe datanya. Atribut AUTO_INCREMENT pada kolom id membuat server mengisi nomor berurutan untuk baris baru yang tidak menyebut nilai kolom tersebut.
Nilai bawaan dengan DEFAULT#
Atribut DEFAULT menetapkan nilai yang dipakai server ketika pernyataan INSERT tidak menyebut kolom tersebut. Tabel skema di atas memakai dua nilai bawaan, yaitu status yang berbawaan 'aktif' dan stok yang berbawaan 0. Nilai bawaan semacam ini menjaga agar baris tetap lengkap tanpa mengharuskan setiap INSERT menuliskan semua kolom.
Perilaku sebaliknya juga perlu diketahui. Kolom yang tidak memiliki NOT NULL dan tidak memiliki DEFAULT berperilaku seperti berbawaan NULL, sehingga kolom tanggal_bergabung tetap menyimpan NULL bila tidak diisi. Amati perbedaan tersebut pada percobaan berikut.
# mengisi satu baris anggota dan dua baris buku tanpa menyebut kolom berbawaan
mysql -t -u root perpustakaan <<'SQL'
INSERT INTO anggota (nama, email)
VALUES ('Ali', '[email protected]');
INSERT INTO buku (kode_buku, judul, penulis, tahun)
VALUES ('AL-001', 'Algoritma Dasar', 'Rina Handayani', 2021),
('ST-014', 'Struktur Data Terapan', 'Budi Santoso', 2019);
SELECT id, nama, email, status, tanggal_bergabung FROM anggota ORDER BY id;
SELECT id, kode_buku, judul, stok FROM buku ORDER BY id;
SQL+----+------+-----------------+--------+-------------------+
| id | nama | email | status | tanggal_bergabung |
+----+------+-----------------+--------+-------------------+
| 1 | Ali | [email protected] | aktif | NULL |
+----+------+-----------------+--------+-------------------+
+----+-----------+-----------------------+------+
| id | kode_buku | judul | stok |
+----+-----------+-----------------------+------+
| 1 | AL-001 | Algoritma Dasar | 0 |
| 2 | ST-014 | Struktur Data Terapan | 0 |
+----+-----------+-----------------------+------+Kolom status terisi aktif dan kolom stok terisi 0 tanpa satu pun perintah penyisipan yang menyebut keduanya. Kolom tanggal_bergabung yang tidak beratribut apa pun menyimpan NULL. Perilaku ketiga kolom ini berasal dari definisi CREATE TABLE, bukan dari perintah INSERT.
Membaca definisi dengan SHOW CREATE TABLE#
Server menyimpan definisi setiap tabel dalam bentuk kanonis yang tidak selalu sama dengan teks aslinya. Nama tipe ditulis huruf kecil, nama kolom diberi tanda kutip terbalik, dan kolom tanpa atribut diberi keterangan DEFAULT NULL. Pernyataan SHOW CREATE TABLE menampilkan definisi kanonis tersebut beserta opsi tabel dan nilai counter AUTO_INCREMENT saat ini.
# menampilkan definisi kanonis tabel anggota
mysql -t -u root perpustakaan -e "SHOW CREATE TABLE anggota\G"*************************** 1. row ***************************
Table: anggota
Create Table: CREATE TABLE `anggota` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`nama` varchar(100) NOT NULL,
`email` varchar(150) NOT NULL,
`tanggal_bergabung` date DEFAULT NULL,
`status` varchar(20) NOT NULL DEFAULT 'aktif',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ciDefinisi kanonis ini menjadi rujukan paling tepercaya ketika definisi tabel perlu diperiksa, misalnya untuk memastikan bahwa atribut yang dimaksud benar-benar terpasang. Dokumen desain dan definisi aktual dapat berbeda karena penyuntingan manual, sedangkan keluaran SHOW CREATE TABLE selalu menyatakan keadaan tabel yang sebenarnya.
Kesalahan umum#
Kesalahan pertama adalah membuat tabel dengan nama yang sudah dipakai. CREATE TABLE tidak menimpa tabel yang ada, melainkan langsung gagal dengan error 1050. Karena berkas skema di awal topik selalu menghapus basis data terlebih dahulu, error ini hanya muncul ketika pernyataan pembuatan dijalankan dua kali tanpa pembersihan.
# mencoba membuat tabel yang sudah ada
mysql -u root perpustakaan -e "CREATE TABLE anggota (id INT)"ERROR 1050 (42S01) at line 1: Table 'anggota' already existsKesalahan kedua berupa kelalaian sintaks, misalnya koma yang hilang di antara dua definisi kolom. Server menolak seluruh pernyataan dan menampilkan error 1064 beserta potongan teks yang membuatnya tersandung.
# CREATE TABLE dengan koma yang hilang antara dua definisi kolom
mysql -u root perpustakaan -e "CREATE TABLE kategori (id INT UNSIGNED PRIMARY KEY nama VARCHAR(50) NOT NULL)"ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'nama VARCHAR(50) NOT NULL)' at line 1Kesalahan ketiga tidak menghasilkan error sama sekali. Kolom wajib yang didefinisikan tanpa NOT NULL akan menerima NULL tanpa suara, dan kelalaian ini baru terlihat ketika data sudah bertumpuk. Definisikan NOT NULL pada setiap kolom yang selalu harus terisi sejak tabel pertama kali dibuat.
Ringkasan#
CREATE TABLEmendeklarasikan nama tabel, definisi kolom beserta tipenya, deklarasi kunci, dan opsi tabel dalam satu pernyataan.- Tipe dan panjang kolom dipilih dari rentang nilai yang dibutuhkan, dan
UNSIGNEDdipakai untuk kolom yang nilainya tidak mungkin negatif. DEFAULTmengisi kolom yang tidak disebut padaINSERT, sedangkan kolom tanpaNOT NULLdan tanpaDEFAULTberperilaku berbawaanNULL.SHOW CREATE TABLEmenampilkan definisi kanonis tabel, dan menjadi rujukan kebenaran atas keadaan tabel yang sebenarnya.
Referensi#
- CREATE TABLE Statement — MySQL 8.0 Reference Manual
— Sintaks lengkap
CREATE TABLE, atribut kolom, dan opsi tabel. - Numeric Types — MySQL 8.0 Reference Manual
— Rentang nilai tiap tipe numerik yang menjadi dasar pemilihan tipe
iddanstok.