Array vs Tabel Ternormalisasi
Kapan array menjadi pilihan yang tepat.
Array vs Tabel Ternormalisasi adalah pelajaran SQL Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar SQL Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus SQL Academy mencakup 4 pelajaran total.
Dua Cara Menyimpan Beberapa Nilai
Ketika satu baris perlu menyimpan beberapa nilai yang saling terkait, PostgreSQL menyediakan dua pendekatan utama: menyimpannya sebagai kolom larik pada baris yang sama, atau membuat tabel anak terpisah yang menyimpan setiap nilai dalam barisnya sendiri.
Memahami kapan harus menggunakan setiap pendekatan merupakan keterampilan penting untuk merancang basis data yang efisien dan mudah dipelihara.
Pendekatan Ternormalisasi
Dalam schema yang sepenuhnya ternormalisasi, setiap bagian data berada dalam barisnya sendiri. Jika seorang pengguna dapat memiliki beberapa nomor telepon, Anda membuat tabel user_phones dengan kunci asing yang merujuk kembali ke users.
Ini adalah model relasional klasik dan merupakan pilihan bawaan dalam sebagian besar situasi.
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE user_phones (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(id),
phone TEXT NOT NULL
);
INSERT INTO users (name) VALUES ('Alice'), ('Bob');
INSERT INTO user_phones (user_id, phone) VALUES
(1, '+1-555-0101'),
(1, '+1-555-0102'),
(2, '+1-555-0200');Pendekatan Larik
TEXT[] PostgreSQL (atau tipe apa pun yang diikuti oleh []) memungkinkan Anda menyimpan beberapa nilai langsung dalam satu kolom. Tidak diperlukan tabel tambahan.
Data nomor telepon yang sama dapat disimpan dalam satu baris ringkas untuk setiap pengguna.
CREATE TABLE users_with_phones (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
phones TEXT[]
);
INSERT INTO users_with_phones (name, phones) VALUES
('Alice', ARRAY['+1-555-0101', '+1-555-0102']),
('Bob', ARRAY['+1-555-0200']);Membuat Kueri pada Larik Itu Mudah
Mencari di dalam kolom larik dapat dilakukan dengan mudah menggunakan operator ANY atau operator @> (memuat). Anda dapat menemukan semua pengguna yang memiliki nomor telepon tertentu dengan klausa WHERE sederhana.
-- Find users who have a specific phone number
SELECT name
FROM users_with_phones
WHERE '+1-555-0101' = ANY(phones);
-- Or using the array-contains operator
SELECT name
FROM users_with_phones
WHERE phones @> ARRAY['+1-555-0101'];Saat Larik Lebih Unggul: Pencarian Sederhana
Larik merupakan pilihan yang tepat ketika:
- Daftar nilai dibaca bersama sebagai satu kesatuan (label, penanda, kategori)
- Anda tidak pernah perlu menggabungkan berdasarkan elemen individual
- Daftar memiliki batas atas alami dan jarang diperbarui sebagian
Contoh klasiknya adalah menyimpan label pada sebuah tulisan blog. Anda selalu mengambil semua label sekaligus dan jarang mencari tulisan berdasarkan satu label dalam penggabungan yang kompleks.
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
tags TEXT[]
);
INSERT INTO posts (title, tags) VALUES
('Intro to SQL', ARRAY['sql', 'beginner', 'database']),
('Advanced Indexes', ARRAY['sql', 'performance', 'indexes']),
('NoSQL Overview', ARRAY['nosql', 'beginner']);
-- Get all posts tagged 'beginner'
SELECT title FROM posts
WHERE 'beginner' = ANY(tags);Saat Tabel Ternormalisasi Lebih Unggul: Relasi
Tabel ternormalisasi merupakan pilihan yang lebih baik ketika:
- Setiap nilai memerlukan atributnya sendiri (misalnya, nomor telepon memiliki tipe: rumah/kantor)
- Anda perlu menggabungkan berdasarkan nilai individual
- Nilai berubah secara mandiri dan sering
- Anda memerlukan integritas referensial melalui kunci asing
-- Phone numbers need a 'type' attribute — array can't do this cleanly
CREATE TABLE user_phones (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(id),
phone TEXT NOT NULL,
type TEXT CHECK (type IN ('home', 'work', 'mobile'))
);
INSERT INTO user_phones (user_id, phone, type) VALUES
(1, '+1-555-0101', 'home'),
(1, '+1-555-0102', 'work');Perbedaan Pengindeksan
Dengan tabel ternormalisasi, Anda dapat menambahkan indeks B-tree standar pada kunci asing atau kolom nilai. Dengan larik, Anda memerlukan indeks GIN (Indeks Terbalik Umum) agar pencarian di dalam larik dapat dilakukan dengan cepat.
Indeks GIN bekerja dengan baik, tetapi ukurannya lebih besar dan pembaruannya lebih lambat daripada indeks B-tree.
-- Index for fast array element lookups
CREATE INDEX idx_posts_tags ON posts USING GIN (tags);
-- Now this query uses the index efficiently
EXPLAIN SELECT title FROM posts
WHERE tags @> ARRAY['sql'];Agregasi Antarbaris: Tabel Ternormalisasi Lebih Unggul
Ketika Anda perlu menghitung, mengelompokkan, atau melakukan agregasi pada nilai individual, tabel ternormalisasi jauh lebih alami. Agregasi di dalam larik memerlukan unnest(), yang terlebih dahulu memperluas larik menjadi baris—pada dasarnya membuat kembali struktur ternormalisasi saat kueri dijalankan.
-- Count posts per tag (array approach — needs unnest)
SELECT tag, COUNT(*) AS post_count
FROM posts, unnest(tags) AS tag
GROUP BY tag
ORDER BY post_count DESC;
-- With a normalized post_tags table this would be simpler:
-- SELECT tag, COUNT(*) FROM post_tags GROUP BY tag;Memodifikasi Elemen Larik
Memperbarui atau menghapus satu elemen di dalam larik memerlukan sintaks yang kurang praktis—Anda harus mengganti seluruh larik atau menggunakan array_remove(). Dalam tabel ternormalisasi, Anda cukup menggunakan DELETE atau UPDATE pada baris tertentu.
-- Remove a single tag from an array column
UPDATE posts
SET tags = array_remove(tags, 'beginner')
WHERE id = 1;
-- Append a new tag
UPDATE posts
SET tags = array_append(tags, 'tutorial')
WHERE id = 1;
SELECT title, tags FROM posts WHERE id = 1;Menegakkan Nilai yang Valid
Dalam tabel ternormalisasi, Anda dapat menggunakan kunci asing untuk memastikan bahwa setiap nilai berasal dari sekumpulan nilai yang diketahui. Larik tidak dapat merujuk ke tabel lain—larik tidak mendukung kunci asing.
Jika Anda memerlukan integritas referensial yang terjamin untuk setiap elemen, tabel anak adalah satu-satunya pilihan.
-- Normalized: only valid category IDs allowed (FK enforced)
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
name TEXT UNIQUE NOT NULL
);
CREATE TABLE post_categories (
post_id INT REFERENCES posts(id),
category_id INT REFERENCES categories(id),
PRIMARY KEY (post_id, category_id)
);
-- Array: no constraint possible — any text value is accepted
-- UPDATE posts SET tags = ARRAY['totally_invalid_tag'] WHERE id = 1;Panduan Praktis Pengambilan Keputusan
Gunakan larik ketika data berupa daftar datar sederhana, selalu dibaca sebagai satu kesatuan, tidak memiliki atribut tambahan untuk setiap elemen, dan integritas referensial tidak diperlukan (misalnya label, penanda, kata kunci pencarian).
Gunakan tabel anak ternormalisasi ketika setiap elemen memiliki atributnya sendiri, Anda menggabungkan atau melakukan agregasi pada nilai individual, memerlukan kunci asing, atau setiap elemen sering diperbarui atau dihapus.
-- Summary example: tags as array (good fit)
SELECT title, tags
FROM posts
WHERE tags @> ARRAY['sql']
ORDER BY title;
-- Unnest when you need row-level processing
SELECT title, unnest(tags) AS tag
FROM posts
ORDER BY title, tag;Uji Cepat
Skenario manakah yang paling sesuai untuk menyimpan data sebagai larik PostgreSQL, bukan sebagai tabel anak ternormalisasi?
Ringkasan Pelajaran
Dalam pelajaran ini, Anda mempelajari pertimbangan utama antara larik dan tabel ternormalisasi di PostgreSQL.
- Larik ringkas dan praktis untuk daftar datar yang dibaca sebagai satu kesatuan, seperti label—tetapi tidak memiliki kunci asing, membuat pembaruan per elemen kurang praktis, dan memerlukan indeks GIN untuk pencarian cepat.
- Tabel ternormalisasi mendukung atribut per elemen, integritas kunci asing, agregasi yang efisien, dan pembaruan sederhana pada tingkat baris—dengan biaya berupa penggabungan tambahan.
- Pilihan yang tepat bergantung pada cara Anda mengueri, memperbarui, dan menghubungkan data—bukan hanya pada cara Anda menyimpannya.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Array vs Tabel Ternormalisasi” gratis?
Ya — teks lengkap “Array vs Tabel Ternormalisasi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus SQL Academy, upgrade ke CoddyKit PRO. Kursus SQL Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Array vs Tabel Ternormalisasi”?
Kapan array menjadi pilihan yang tepat. Kamu berlatih SQL Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai SQL Academy?
Tidak diperlukan pengalaman sebelumnya. SQL Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “Array vs Tabel Ternormalisasi” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran SQL Academy ini?
Ya. Setiap pelajaran SQL Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Dasar-Dasar Kolom Array
- Mencari di Dalam Array
- UNNEST dan Agregasi
- Array vs Tabel Ternormalisasi