Bila Hendak Guna Postgres Materialized Views (MV) ? Bahagian 1
Antara View dan Materialized View. Yang mana pilihan hati?
Sebenarnya jarang sekali saya pakai Materialized View
dalam kerjaya saya jika dibandingkan dengan View
. Dalam rencana ini saya jelaskan kenapa ia berlaku.
Apa itu Materialized View?
Sebelum mendalami lebih lanjut tajuk ini, terlebih dahulu mari kita mulakan dengan memahami apa itu objek Materialized View. Materialize View adalah sebuah objek database mempunyai kelebihan untuk menyimpan data seperti sebuah table. Namun pada yang sama ada fleksibiliti seperti sebuah View.
Persoalan utama yang bermain dalam fikiran saya sebelum ini adalah
Bilakan situasi yang sesuai untuk menggunakan Materialized View berbanding View?
Sebelum kita menentukan perkara itu, mungkin perkara pertama yang kita perlu lakukan adalah memahami apakah ciri-ciri Materialized View ini.
Seperti biasa, kita create table yang asas. Boleh rujuk definisi table dalam rencana yang lepas.
Postgres Window Function: FIRST_VALUE vs LAST_VALUE
Hari ini kita akan buat analisa menu makanan dalam sebuah kedai makan. Matlamat analisa kita kali ini adalah:
Skrip yang sama saya gunakan.
CREATE TABLE menu (
menuid VARCHAR(256) PRIMARY KEY,
nama_menu VARCHAR(100),
harga_menu numeric,
kategori_menu VARCHAR(100)
);
Dan masukkan data
INSERT INTO menu (menuid, nama_menu, harga_menu, kategori_menu) VALUES
(uuid_generate_v4(), 'Nasi Lemak', 3.25, 'Malaysian'),
(uuid_generate_v4(), 'Roti Canai', 1.50, 'Malaysian'),
(uuid_generate_v4(), 'Satay', 0.90, 'Malaysian'),
(uuid_generate_v4(), 'Char Kway Teow', 2.50, 'Malaysian'),
(uuid_generate_v4(), 'Laksa', 3.00, 'Malaysian'),
(uuid_generate_v4(), 'Chicken Rice', 4.00, 'Malaysian'),
(uuid_generate_v4(), 'Hainanese Chicken Rice', 4.50, 'Malaysian'),
(uuid_generate_v4(), 'Beef Rendang', 5.00, 'Malaysian'),
(uuid_generate_v4(), 'Nasi Goreng', 3.75, 'Malaysian'),
(uuid_generate_v4(), 'Mee Goreng', 2.75, 'Malaysian'),
(uuid_generate_v4(), 'Tom Yum', 4.25, 'Thai'),
(uuid_generate_v4(), 'Pad Thai', 3.75, 'Thai'),
(uuid_generate_v4(), 'Green Curry', 5.50, 'Thai'),
(uuid_generate_v4(), 'Red Curry', 5.50, 'Thai'),
(uuid_generate_v4(), 'Massaman Curry', 6.00, 'Thai'),
(uuid_generate_v4(), 'Som Tum', 2.50, 'Thai'),
(uuid_generate_v4(), 'Spring Rolls', 1.25, 'Thai'),
(uuid_generate_v4(), 'Pho', 4.50, 'Vietnamese'),
(uuid_generate_v4(), 'Banh Mi', 3.00, 'Vietnamese'),
(uuid_generate_v4(), 'Bun Cha', 4.00, 'Vietnamese'),
(uuid_generate_v4(), 'Goi Cuon', 2.00, 'Vietnamese'),
(uuid_generate_v4(), 'Cao Lau', 4.25, 'Vietnamese'),
(uuid_generate_v4(), 'Banh Xeo', 3.75, 'Vietnamese'),
(uuid_generate_v4(), 'Bibimbap', 5.00, 'Korean'),
(uuid_generate_v4(), 'Kimchi', 1.50, 'Korean'),
(uuid_generate_v4(), 'Bulgogi', 6.00, 'Korean'),
(uuid_generate_v4(), 'Japchae', 4.00, 'Korean'),
(uuid_generate_v4(), 'Tteokbokki', 3.00, 'Korean'),
(uuid_generate_v4(), 'Samgyeopsal', 7.00, 'Korean'),
(uuid_generate_v4(), 'Kimchi Stew', 3.50, 'Korean'),
(uuid_generate_v4(), 'Sushi', 2.75, 'Japanese'),
(uuid_generate_v4(), 'Ramen', 5.50, 'Japanese'),
(uuid_generate_v4(), 'Tempura', 4.00, 'Japanese'),
(uuid_generate_v4(), 'Udon', 3.75, 'Japanese'),
(uuid_generate_v4(), 'Sashimi', 5.25, 'Japanese'),
(uuid_generate_v4(), 'Yakitori', 3.00, 'Japanese'),
(uuid_generate_v4(), 'Tonkatsu', 4.50, 'Japanese'),
(uuid_generate_v4(), 'Okonomiyaki', 3.75, 'Japanese'),
(uuid_generate_v4(), 'Takoyaki', 3.25, 'Japanese'),
(uuid_generate_v4(), 'Miso Soup', 1.50, 'Japanese'),
(uuid_generate_v4(), 'Pasta Carbonara', 5.00, 'Italian'),
(uuid_generate_v4(), 'Margherita Pizza', 4.75, 'Italian'),
(uuid_generate_v4(), 'Lasagna', 5.25, 'Italian'),
(uuid_generate_v4(), 'Risotto', 6.00, 'Italian'),
(uuid_generate_v4(), 'Tiramisu', 3.50, 'Italian'),
(uuid_generate_v4(), 'Bruschetta', 2.50, 'Italian'),
(uuid_generate_v4(), 'Gelato', 2.75, 'Italian'),
(uuid_generate_v4(), 'Panini', 3.50, 'Italian'),
(uuid_generate_v4(), 'Gnocchi', 4.00, 'Italian'),
(uuid_generate_v4(), 'Focaccia', 2.00, 'Italian'),
(uuid_generate_v4(), 'Fish and Chips', 4.00, 'British'),
(uuid_generate_v4(), 'Bangers and Mash', 4.50, 'British'),
(uuid_generate_v4(), 'Yorkshire Pudding', 2.50, 'British'),
(uuid_generate_v4(), 'Beef Wellington', 6.75, 'British'),
(uuid_generate_v4(), 'Cornish Pasty', 3.25, 'British'),
(uuid_generate_v4(), 'Full English Breakfast', 7.00, 'British'),
(uuid_generate_v4(), 'Scotch Egg', 2.75, 'British'),
(uuid_generate_v4(), 'Chicken Tikka Masala', 5.00, 'Indian'),
(uuid_generate_v4(), 'Butter Chicken', 4.50, 'Indian'),
(uuid_generate_v4(), 'Rogan Josh', 5.50, 'Indian'),
(uuid_generate_v4(), 'Palak Paneer', 4.00, 'Indian'),
(uuid_generate_v4(), 'Chole Bhature', 3.25, 'Indian'),
(uuid_generate_v4(), 'Biryani', 5.00, 'Indian'),
(uuid_generate_v4(), 'Samosa', 1.25, 'Indian'),
(uuid_generate_v4(), 'Aloo Gobi', 3.50, 'Indian'),
(uuid_generate_v4(), 'Paneer Tikka', 4.00, 'Indian'),
(uuid_generate_v4(), 'Naan', 1.75, 'Indian'),
(uuid_generate_v4(), 'Kebab', 3.50, 'Middle Eastern'),
(uuid_generate_v4(), 'Falafel', 2.75, 'Middle Eastern'),
(uuid_generate_v4(), 'Hummus', 2.50, 'Middle Eastern'),
(uuid_generate_v4(), 'Shawarma', 4.50, 'Middle Eastern'),
(uuid_generate_v4(), 'Tabbouleh', 2.00, 'Middle Eastern'),
(uuid_generate_v4(), 'Baba Ganoush', 2.50, 'Middle Eastern'),
(uuid_generate_v4(), 'Baklava', 3.00, 'Middle Eastern'),
(uuid_generate_v4(), 'Fattoush', 2.75, 'Middle Eastern'),
(uuid_generate_v4(), 'Pita Bread', 1.25, 'Middle Eastern'),
(uuid_generate_v4(), 'Shakshuka', 3.75, 'Middle Eastern'),
(uuid_generate_v4(), 'Empanada', 2.00, 'Latin American'),
(uuid_generate_v4(), 'Taco', 2.50, 'Latin American'),
(uuid_generate_v4(), 'Burrito', 4.00, 'Latin American'),
(uuid_generate_v4(), 'Ceviche', 4.50, 'Latin American'),
(uuid_generate_v4(), 'Arepa', 3.00, 'Latin American'),
(uuid_generate_v4(), 'Feijoada', 5.00, 'Latin American'),
(uuid_generate_v4(), 'Tostada', 2.25, 'Latin American'),
(uuid_generate_v4(), 'Quesadilla', 3.75, 'Latin American'),
(uuid_generate_v4(), 'Tamale', 2.50, 'Latin American'),
(uuid_generate_v4(), 'Churro', 1.50, 'Latin American');
Mari kita create view untuk makanan Indian menggunakan script di bawah.
create or replace view menu_indian as
select menuid, nama_menu, harga_menu, kategori_menu
from menu
where kategori_menu='Indian';
Mari kita kira jumlah baris data
select count(*) from menu_indian;
Result:
10
Materialized View pula:
create MATERIALIZED view mv_menu_indian as
select menuid, nama_menu, harga_menu, kategori_menu
from menu
where kategori_menu='Indian';
Kira juga
select count(*) from mv_menu_indian;
Result:
10
Sekarang kita masukkan data baru pula
INSERT INTO menu (menuid, nama_menu, harga_menu, kategori_menu) VALUES
(uuid_generate_v4(), 'Capati', 3.25, 'Indian'),
(uuid_generate_v4(), 'Vada Pav', 1.50, 'Indian');
Dan select count(*) view dan materialized view (MV) pula:
select count(*) from menu_indian;
Result:
12
select count(*) from mv_menu_indian;
Result:
10
Aik? Tentu anda bertanya kenapa ada dua hasil yang berbeza bukan?
Ini disebabkan MV menyimpana snapshoot data pada ketika ia dibina. Pada contoh di atas row pada masa ia dibina, jumlah baris data adalah masih 10. Jadi penambahan baris data selepas itu tidak memberikan impak.
Untuk memastikan MV mendapat data yang terbaru and perlu menyegarkan (refresh) MV tersebut dengan menggunakan command ini:
REFRESH MATERIALIZED VIEW mv_menu_indian;
Jika kita query semula data anda akan dapat 12 baris data
select count(*) from mv_menu_indian;
Result:
12
Setakat itu sahaja untuk kali ini. Nanti bahagian 2 saya akan menunjukkan kelebihan dan kekurang MV. Ini akan menjadi faktor-faktor yang akan menentukan kesuaian penggunaan MV
Jangan lupa subscribe