Belajar dengan membaca secara berurutan

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.

Sebelum masuk ke latihan, lihat dulu definisi kolom dan baris sampel dari tabel typed_demo. (Jalankan dengan benar dan penjelasan akan muncul.)

① Pakai PRAGMA table_info(typed_demo); untuk memeriksa nama kolom, tipe yang dideklarasikan, dan primary key.

② Pakai SELECT * FROM typed_demo; untuk mengintip setiap baris.

SQL Editor

Jalankan query untuk melihat hasil

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.

Tipe yang dideklarasikan vs storage class
Nilai yang dimasukkanTipe kolom yang dideklarasikanTipe tersimpan'123'Kolom INTEGERinteger 123(typeof=integer)'10'Kolom TEXTstring '10'(typeof=text)
Tipe yang kamu deklarasikan pada kolom adalah kebijakan untuk "bagaimana nilai ini harus ditangani." '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

Bayangkan kamu ingin memeriksa "tipe (integer / real / string) apa yang sebenarnya disimpan untuk setiap nilai di typed_demo."

① Ambil kolom a, b, c, dan flag dari typed_demo.

② Tambahkan typeof() untuk setiap kolom juga, dengan alias a_class / b_class / c_class / flag_class.

③ Jangan saring barisnya — kedua baris harus muncul di hasil.

SQL Editor

Jalankan query untuk melihat hasil

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).

String dan angka mengonversi berdasarkan konteks
EkspresiKonversiHasil'123' + 0'123' menjadiangka 123123'abc' + 0tidak bisa dikonversi,diperlakukan sebagai 00
Ketika aritmetika dibutuhkan, string yang terlihat seperti angka berubah menjadi angka; ketika penggabungan dibutuhkan, angka berubah menjadi string. String seperti 'abc' yang tidak bisa dikonversi menjadi angka diperlakukan sebagai 0 dalam aritmetika.
-- 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

Bayangkan kamu ingin "memperlakukan string yang terlihat seperti angka di kolom b (TEXT) milik typed_demo sebagai angka untuk aritmetika dan pembandingan."

① Ambil kolom b dari typed_demo.

② Tambahkan b + 0 dengan alias b_plus0. Baris yang terlihat seperti angka menjadi angka, dan baris non-angka menjadi 0.

③ Lalu tambahkan pemeriksaan apakah b sebagai angka lebih besar dari 5, dengan alias gt5 (karena kamu membandingkan nilai kolom b terhadap literal numerik, pembandingan terjadi antar angka).

SQL Editor

Jalankan query untuk melihat hasil

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".

Boolean sebagai integer 1 / 0
Ekspresi / nilaiInterpretasi boolean1 / TRUE / 3>2true0 / FALSE / 1>2falseNULLtidak diketahui — tidak terpilih
Ekspresi pembanding mengembalikan 1 untuk true dan 0 untuk false. Kolom flag yang menyimpan 1 / 0 bisa langsung dipakai sebagai kondisi, dan NULL diperlakukan sebagai keadaan ketiga yang bukan true maupun false.
-- 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;

Bayangkan kamu ingin "mengubah kolom flag (integer 1 / 0) di typed_demo menjadi label yang bisa dibaca manusia."

① Ambil a dan flag dari typed_demo.

② Pakai flag langsung sebagai kondisi di sebuah CASE WHEN ... dan tambahkan kolom ketiga dengan alias state yang mengembalikan 'enabled' untuk baris true (1) dan 'disabled' untuk baris false (0).

③ Untuk juga melihat apa yang dikembalikan ekspresi pembanding untuk true / false, tambahkan kolom keempat dengan hasil flag = 1 dengan alias is_on.

SQL Editor

Jalankan query untuk melihat hasil

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.

Konversi tipe implisit vs tipe ketat MySQL
Konsol kursus ini(konversi implisit)MySQL(tipe ketat)'123' di kolom INTEGER ->disimpan sebagai integer 123Kolom INT = hanya angka /VARCHAR(10) = sampai 10 karakterPanjang / presisitidak diberlakukanMelebihi panjang:error / pemotongan
Konsol kursus ini memakai konversi tipe implisit — '123' yang dimasukkan ke kolom INTEGER menjadi integer dan pernyataannya berjalan. MySQL memakai tipe ketat — tipe dan panjang yang dideklarasikan diberlakukan, dan nilai yang tidak cocok akan error atau dipotong.
-- 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).

Bayangkan kamu ingin "menjumlahkan dan merata-ratakan nilai di kolom b (TEXT) milik typed_demo sebagai angka, dan menghitung berapa baris yang true di kolom flag." Ini menunjukkan bahwa konversi tipe implisit membuat kamu bisa mengagregasi kolom teks secara numerik.

① Ambil sum dari kolom b milik typed_demo dengan alias sum_b, dan average dengan alias avg_b. Hanya baris yang terlihat seperti angka yang ditambahkan sebagai angka.

② Dalam kueri yang sama, ambil sum dari kolom flag dengan alias enabled_count (karena flag adalah 1 / 0, sum sama dengan jumlah baris yang true).

③ Jangan kelompokkan apa pun — kembalikan satu baris ringkasan untuk seluruh tabel.

SQL Editor

Jalankan query untuk melihat hasil
QUIZ

Cek Pemahaman

Jawab setiap pertanyaan satu per satu.

Soal 1Di konsol kursus ini, kamu INSERT string '123' ke kolom yang dideklarasikan INTEGER. Pernyataan mana yang benar?

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?