Semakin besar proyek analisis, semakin rapuh kebiasaan menyimpan data di banyak berkas CSV: data ganda, format berubah-ubah, dan pembaruan tidak konsisten. Database relasional menyelesaikan masalah tersebut dengan satu wadah terstruktur dan bahasa query standar — SQL. MATLAB dapat berbicara langsung dengan database tersebut: interface sqlite sudah ada di MATLAB inti sejak R2015a, sedangkan Database Toolbox membuka akses ke database server seperti PostgreSQL dan MySQL. Chapter ini membahas konsep database, koneksi, pengambilan data, penulisan data, dan keamanan query. Cakupan materinya:
- konsep database relasional dan lima perintah SQL inti
sqlitedi MATLAB inti vs Database Toolbox- koneksi,
fetch,sqlread, dansqlwrite - modifikasi data dengan
executeserta transaksicommit/close - bahaya SQL injection dan query berparameter
Konsep Database Relasional #
Aturannya: data hidup di tabel — baris merepresentasikan satu entitas, kolom merepresentasikan atribut, dan tipe kolom dijaga konsisten oleh mesin database. Mekanismenya: SQL (Structured Query Language) adalah bahasa deklaratif — kita menyatakan data apa yang ingin didapat, mesin database yang memutuskan cara memindai dan menyaring. Lima perintah inti yang dipakai hampir setiap hari:
| Perintah SQL | Tugas | Paduan di chapter ini |
|---|---|---|
SELECT | ambil kolom tertentu | querySederhana + tampilkan |
WHERE | saring baris dengan predikat | querySederhana, queryRentang |
INSERT | tambah baris baru | mutasi pegawai(end+1) |
UPDATE | ubah nilai kolom | loop ubah gaji |
DELETE | buang baris | hapusBaris |
Ditulis dalam SQL, kelima operasi tabel pegawai tampak seperti ini:
SELECT nama, gaji FROM pegawai WHERE kota = 'Jakarta';
INSERT INTO pegawai VALUES ('Fajar', 'Jakarta', 7200);
UPDATE pegawai SET gaji = gaji + 500 WHERE nama = 'Andi';
DELETE FROM pegawai WHERE nama = 'Rina';Kalimat WHERE kota = 'Jakarta' dievaluasi per baris oleh query engine — persis pola yang akan kita tiru dengan MATLAB murni di bagian akhir chapter.
sqlite di Core MATLAB vs Database Toolbox #
Aturannya: pilih jalur koneksi berdasar tempat data berada. Mekanismenya: sqlite membuka berkas database tunggal tanpa server — seluruh tabel, indeks, dan transaksi hidup dalam satu berkas di disk. Database Toolbox berperan berbeda: membuat koneksi jaringan ke database server lewat JDBC atau ODBC. Perbandingannya:
| Aspek | sqlite (MATLAB inti) | Database Toolbox |
|---|---|---|
| Sejak | R2015a | produk terpisah (berlangganan) |
| Wadah data | satu berkas .db di disk | server: PostgreSQL, MySQL, Oracle, dsb. |
| Cocok untuk | proyek lokal, analisis, data menengah | data perusahaan, akses bersama |
| Fungsi kunci | sqlite, fetch, execute, sqlread, sqlwrite | database, fetch, execute, sqlwrite |
Untuk proyek pribadi dan tim kecil, sqlite hampir selalu cukup: tidak ada instalasi server, berkas mudah disalin sebagai bagian proyek reproducible.
Koneksi dan Pengambilan Data #
Aturannya: setiap sesi database dimulai dari objek koneksi dan ditutup dengan close — koneksi yang terlupakan mengunci berkas SQLite dari proses lain. Mekanismenya: objek conn menyimpan pegangan ke berkas database; fetch mengirim teks SQL, menjalankan query di mesin SQLite, lalu mengemas hasilnya sebagai table MATLAB:
conn = sqlite('penjualan.db'); % buka berkas database
data = fetch(conn, 'SELECT * FROM pegawai'); % hasil dikembalikan sebagai table
close(conn); % tutup sambunganFungsi fetch(conn, sqlquery) menjalankan query lalu mengembalikan tabel table — kolom database menjadi variabel, baris database menjadi baris tabel. Fungsi sqlread mengambil satu tabel utuh tanpa menulis SQL: sqlread(conn, 'pegawai') mengembalikan seluruh isi tabel pegawai. Untuk arah sebaliknya, sqlwrite mengekspor table MATLAB menjadi baris baru di database: sqlwrite(conn, 'pegawai', tabelBaru) menyisipkan setiap baris tabelBaru ke tabel pegawai. Ketiga fungsi tersebut hanya berjalan di MATLAB — runner Octave tidak memiliki sqlite, sehingga blok di atas diverifikasi terhadap dokumentasi resmi tanpa dijalankan runner.
Modifikasi Data dan Transaksi #
Aturannya: perubahan skema dan isi database dilakukan lewat execute, bukan fetch. Mekanismenya: execute(conn, sqlquery) menjalankan pernyataan SQL yang tidak mengembalikan data — CREATE TABLE, INSERT, UPDATE, DELETE — langsung pada berkas database:
conn = sqlite('penjualan.db');
execute(conn, 'CREATE TABLE pegawai (nama TEXT, kota TEXT, gaji REAL)');
execute(conn, 'INSERT INTO pegawai VALUES (''Fajar'', ''Jakarta'', 7200)');
commit(conn);
close(conn);Transaksi menjaga kelompok perubahan tetap utuh: bila sesi berakhir sebelum commit, perubahan yang belum dikomit tidak dijadikan permanen, dan rollback membatalkannya secara eksplisit. Pola amannya: buka koneksi → execute serangkaian perubahan yang saling bergantung → commit → close. Untuk menyisipkan data bertumpuk, sqlwrite dengan table lebih ringkas daripada merangkai INSERT satu per satu.
Keamanan: SQL Injection #
Aturannya: nilai yang berasal dari pengguna tidak boleh dirangkai langsung ke dalam teks SQL. Mekanismenya: teks SQL adalah kode — bila input pengguna menyusup ke teks tersebut, pengguna bisa menyuntikkan klausa tambahan dan membaca atau merusak seluruh tabel:
% BERBAHAYA: input pengguna digabung ke teks SQL
q = ['SELECT * FROM pegawai WHERE nama = ''' inputNama ''''];
data = fetch(conn, q);Varian yang aman memisahkan kode SQL dari nilai. Untuk sqlite, rute paling bersih adalah sqlwrite: nilai berada di dalam table dan tidak pernah menyentuh teks SQL:
sqlwrite(conn, 'pegawai', dataBaru); % nilai lewat table, bukan string SQLPada Database Toolbox, query berparameter memakai placeholder ? — data dikirim terpisah dari teks SQL lewat bentuk execute ber-data:
sql = "INSERT INTO pegawai VALUES (?, ?, ?)";
execute(conn, sql, dataBaru); % dataBaru: table berisi nilaiKoneksi JDBC dapat melangkah lebih jauh dengan objek SQLPreparedStatement: nilai di-bind ke parameter sekali, lalu pernyataan yang sama dijalankan berulang dengan nilai berbeda — pola standar aplikasi produksi. Objek prepared statement hanya tersedia untuk koneksi JDBC, bukan untuk sqlite.
Mini Query Engine di MATLAB Murni #
Karena sqlite hanya ada di MATLAB, contoh.m menguji konsep SQL di atas data di memori: tabel menjadi struct array, dan tiap operasi SQL menjadi fungsi murni. Fungsi querySederhana meniru SELECT ... WHERE kolom = nilai:
function hasil = querySederhana(data, kolom, nilai)
% QUERYSEDERHANA SELECT ... WHERE kolom = nilai (teks).
% Pembandingan dilakukan per baris, meniru evaluasi
% predikat WHERE oleh mesin database.
hasil = data(strcmp({data.(kolom)}, nilai));
endPredikat numerik WHERE gaji >= batas dan pengurutan ORDER BY gaji mengikuti pola yang sama:
function hasil = queryRentang(data, kolom, batas)
% QUERYRENTANG SELECT ... WHERE kolom >= batas (numerik).
hasil = data([data.(kolom)] >= batas);
end
function hasil = urutkan(data, kolom)
% URUTKAN ORDER BY kolom ASC (indeks hasil sort).
[~, idx] = sort([data.(kolom)]);
hasil = data(idx);
endAlur ujinya mengikuti siklus hidup query sungguhan:
Operasi mutasi INSERT/UPDATE/DELETE diuji dalam satu blok pada data yang sama:
pegawai(end+1) = struct('nama', 'Fajar', 'kota', 'Jakarta', 'gaji', 7200);
assert(numel(pegawai) == 6, 'INSERT gagal');
fprintf('INSERT Fajar : 5 -> %d baris\n', numel(pegawai));
for k = 1:numel(pegawai)
if strcmp(pegawai(k).nama, 'Andi')
pegawai(k).gaji = pegawai(k).gaji + 500; % UPDATE SET gaji = gaji + 500
end
end
gajiAndi = pegawai(strcmp({pegawai.nama}, 'Andi')).gaji;
assert(isequal(gajiAndi, 8600), 'UPDATE gagal');
fprintf('UPDATE Andi +500: gaji 8100 -> %d\n', gajiAndi);
pegawai = hapusBaris(pegawai, 'nama', 'Rina');
assert(numel(pegawai) == 5, 'DELETE gagal');
fprintf('DELETE Rina : 6 -> %d baris\n', numel(pegawai));Output yang Dihasilkan (keseluruhan contoh.m):
== Bagian 1: SELECT * FROM pegawai ==
nama kota gaji
Budi Jakarta 7500
Siti Bandung 6200
Andi Jakarta 8100
Rina Surabaya 5400
Dewi Bandung 6900
jumlah baris: 5
== Bagian 2: WHERE kota = 'Jakarta' ==
nama kota gaji
Budi Jakarta 7500
Andi Jakarta 8100
jumlah baris: 2
== Bagian 3: WHERE gaji >= 6000 ORDER BY gaji ==
nama kota gaji
Siti Bandung 6200
Dewi Bandung 6900
Budi Jakarta 7500
Andi Jakarta 8100
== Bagian 4: INSERT, UPDATE, DELETE ==
INSERT Fajar : 5 -> 6 baris
UPDATE Andi +500: gaji 8100 -> 8600
DELETE Rina : 6 -> 5 baris
mini query engine: SELECT/WHERE/ORDER/INSERT/UPDATE/DELETE PASSFilter kota = 'Jakarta' menyisakan dua dari lima baris, filter rentang gaji >= 6000 menyisakan empat baris yang terurut naik, lalu tiga mutasi menggerakkan jumlah baris 5 → 6 → 5 dengan gaji Andi naik menjadi 8600 — angka-angka tersebut dijaga oleh assert sehingga regresi logika langsung gagal.
Ringkasan #
Kerja database di MATLAB berdiri di atas empat gerbang: objek koneksi (sqlite('file.db') di MATLAB inti sejak R2015a, atau database di Database Toolbox untuk server SQL), pembacaan (fetch mengembalikan table, sqlread mengambil tabel utuh), penulisan (execute untuk SQL tanpa hasil, sqlwrite untuk ekspor table), dan housekeeping transaksi (commit lalu close). Nilai dari pengguna selalu lewat placeholder ?, sqlwrite, atau prepared statement JDBC — jangan pernah merangkai string SQL. Skrip contoh.m menutup konsep dengan mini query engine teruji: SELECT/WHERE/ORDER BY/INSERT/UPDATE/DELETE semuanya lulus di atas struct array lima baris.