Soal 1Di konsol kursus ini, kamu INSERT string '123' ke kolom yang dideklarasikan INTEGER. Pernyataan mana yang benar?
String, Angka, Boolean, dan Konversi Tipe Implisit
Memakai tabel typed_demo, lihat bagaimana tipe yang dideklarasikan berbeda dari storage class, perhatikan '10' dan 123 saling bertukar lewat typeof(), pahami boolean direpresentasikan sebagai 0 / 1, lalu bandingkan dengan tipe ketat MySQL seperti CHAR / VARCHAR / INT / DECIMAL — semua dengan menjalankan kueri sungguhan.
Data yang akan kita pakai — tabel typed_demo
Saat kamu membuat kolom, kamu mendeklarasikan tipe seperti INTEGER / TEXT / REAL, dan itu menentukan bagaimana kolom memperlakukan nilai yang disimpannya.
Di artikel ini kamu akan menelusuri bagaimana string, angka, dan boolean disimpan dan dibandingkan di SQL, lalu bagaimana cara konsol kursus ini menangani tipe (juga dikenal sebagai type affinity dalam dokumentasi SQLite) berbeda dengan tipe ketat di MySQL.
Tipe yang dideklarasikan vs storage class — setiap nilai membawa tipenya sendiri
Tipe yang dimiliki sebuah nilai saat runtime disebut storage class, dan ada lima jenis: NULL / INTEGER (bilangan bulat) / REAL (desimal) / TEXT (string) / BLOB (biner).
Kamu bisa memeriksa storage class apa yang dimiliki sebuah nilai saat ini dengan fungsi typeof(nilai).
Kalau kamu memasukkan string yang terlihat seperti angka ke kolom yang dideklarasikan TEXT, kebijakan kolomnya adalah "perlakukan ini sebagai teks," jadi nilainya tetap berupa string.
Tetapi kalau kamu memasukkan string yang terlihat seperti angka seperti '123' ke kolom yang dideklarasikan INTEGER, kebijakan kolomnya bekerja dan mengonversinya menjadi integer 123 sebelum disimpan.
'123' yang masuk ke kolom INTEGER menjadi integer, sedangkan '10' yang masuk ke kolom TEXT tetap menjadi string. Tipe aktual setiap nilai selalu bisa diperiksa dengan typeof().-- Contoh mandiri singkat yang menunjukkan "tipe yang dideklarasikan kolom menentukan tipe yang tersimpan"
-- String yang terlihat seperti angka di kolom INTEGER dikonversi menjadi integer
CREATE TABLE IF NOT EXISTS aff_probe(num INTEGER, txt TEXT);
INSERT OR IGNORE INTO aff_probe VALUES ('123','123'), ('hello','hello');
-- Pakai typeof untuk memeriksa storage class sesungguhnya
SELECT num, typeof(num) AS num_class,
txt, typeof(txt) AS txt_class
FROM aff_probe;
-- Kolom num: '123' menjadi integer, 'hello' tidak bisa dikonversi sehingga tetap teks
-- Kolom txt: keduanya tetap berupa teks
String dan angka saling bertukar — '123' dan 123
Ketika sebuah angka dibutuhkan, string dikonversi menjadi angka secara otomatis; ketika sebuah string dibutuhkan, angka dikonversi menjadi string.
Sebagai contoh, '123' + 0 mengonversi string '123' menjadi angka 123 dan mengembalikan 123, jadi string yang terlihat seperti angka bisa langsung dipakai di aritmetika.
Sebaliknya, 123 || '' (|| adalah penggabungan string) mengubah angka menjadi string.
Operator pembanding bekerja dengan cara yang sama: kalau satu sisi adalah kolom INTEGER, sisi lainnya disejajarkan sebagai angka; kalau satu sisi adalah kolom TEXT, sisi lainnya disejajarkan sebagai string.
Tetapi dengan dua literal mentah seperti '1' = 1 tidak ada kolom yang menetapkan kebijakan, sehingga nilai-nilainya tetap bertipe berbeda dan hasilnya adalah 0 (tidak cocok).
-- Perhatikan konversi string <-> angka (contoh read-only)
SELECT '123' + 0 AS str_to_num, -- string menjadi angka 123
'abc' + 0 AS not_a_num, -- tidak bisa dikonversi, menjadi 0
123 || '' AS num_to_str, -- angka menjadi string '123'
typeof('123' + 0) AS class_after_add,
'1' = 1 AS literal_cmp, -- literal mentah: 0 (tidak cocok)
7 / 2 AS int_div, -- integer / integer = integer 3
7.0 / 2 AS real_div; -- ada desimal di campuran menghasilkan 3.5
Boolean — TRUE / FALSE disimpan sebagai 1 / 0
SQL tidak memiliki tipe boolean yang berdiri sendiri — nilai kebenaran direpresentasikan oleh integer 1 (true) dan 0 (false).
Ekspresi pembanding seperti 1 = 1 atau 3 > 2 mengembalikan 1 untuk true dan 0 untuk false.
Di mana pun kamu bisa menulis sebuah kondisi, seperti CASE WHEN kolom THEN ..., apa pun yang bukan 0 (biasanya 1) diperlakukan sebagai true, dan 0 diperlakukan sebagai false.
NULL adalah keadaan ketiga yang bukan true maupun false ("tidak diketahui"), dan dalam kondisi WHERE atau CASE ia berperilaku seperti false dalam arti bahwa barisnya "tidak terpilih".
-- Ekspresi pembanding mengembalikan 1 / 0 (contoh read-only)
SELECT (1 = 1) AS is_true, -- 1
(1 = 2) AS is_false, -- 0
(3 > 2) AS gt, -- 1
TRUE AS true_kw, -- sama dengan 1
FALSE AS false_kw; -- sama dengan 0
-- Pakai kolom flag langsung sebagai kondisi
SELECT a, flag,
CASE WHEN flag THEN 'enabled' ELSE 'disabled' END AS state
FROM typed_demo;
Dibandingkan dengan tipe ketat MySQL
Apa yang kamu lihat sejauh ini adalah konversi tipe implisit — nilai diubah bentuknya secara fleksibel berdasarkan konteks.
Sebaliknya, MySQL dan Oracle memiliki tipe ketat: ketika kamu mendeklarasikan CHAR(10) / VARCHAR(255) / TEXT untuk string atau INT / DECIMAL(10,2) untuk angka, hanya nilai dengan tipe itu yang bisa masuk, dan panjang serta presisi diberlakukan persis seperti yang dideklarasikan.
Sebuah angka biasanya tidak akan menyelinap ke kolom string lewat konversi implisit, dan nilai yang melebihi panjang yang dideklarasikan akan menghasilkan error atau dipotong.
Kode di bawah ini adalah cara MySQL mendeklarasikan tipe.
Konsol kursus ini sengaja tidak memberlakukan pemeriksaan panjang, jadi ketika kamu mempelajari batasan panjang seperti VARCHAR(10), cukup ingat "beginilah MySQL menulisnya" — sintaks itu berlaku ketika kamu pindah ke database lain.
-- Deklarasi tipe ketat di MySQL (read-only — jangan dijalankan di konsol ini)
CREATE TABLE product (
id INT PRIMARY KEY, -- hanya angka
code CHAR(8), -- panjang tetap, 8 karakter
name VARCHAR(100) NOT NULL, -- sampai 100 karakter
note TEXT, -- string panjang
price DECIMAL(10,2) NOT NULL, -- 8 digit + 2 desimal
in_stock TINYINT(1) DEFAULT 0 -- flag 0/1 untuk boolean
);
-- Di MySQL, memasukkan 101 karakter ke VARCHAR(100) akan
-- error atau dipotong tergantung pengaturan.
-- Memasukkan 'abc' ke kolom INT akan error.
-- Konsol kursus ini menjalankan semuanya berkat konversi tipe implisit.
Tips — CHAR vs VARCHAR dan kapan memakai yang mana
`CHAR(n)` adalah panjang tetap: kalau nilainya lebih pendek dari n karakter, ia di-pad dengan spasi di belakang untuk memenuhi seluruh n karakter.
`VARCHAR(n)` adalah panjang variabel: ia menyimpan nilai sesuai panjang aktualnya (n adalah batas atas).
Pakai `CHAR` ketika: nilainya selalu panjang tetap, seperti kode negara ('JP' / 'US'), kode jenis kelamin, atau bagian hash dengan panjang tetap. Layout tetap bisa sedikit lebih cepat untuk pembandingan dan perhitungan posisi record.
Pakai `VARCHAR` ketika: panjang bervariasi — nama, alamat email, judul, deskripsi, dan sebagainya. Ia hanya memakai ruang yang benar-benar dibutuhkan, sehingga penyimpanan tetap kecil.
Kalau ragu, `VARCHAR` adalah default yang lebih aman. Memakai CHAR untuk data dengan panjang variabel bisa menyebabkan ketidakcocokan pembandingan yang halus karena padding spasi di belakang (misalnya 'JP' vs 'JP ' ditangani secara tidak konsisten).
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Pernyataan mana yang dengan benar menggambarkan bagaimana boolean direpresentasikan di SQL?
Soal 3Pernyataan mana yang dengan benar menggambarkan perbedaan antara konsol kursus ini (konversi tipe implisit) dan tipe ketat MySQL?