Materialized View یکی از قابلیتهای قدرتمند PostgreSQL است که امکان ذخیره فیزیکی نتیجه کوئریها و بهروزرسانی دادهها از جداول پایه به صورت دورهای را فراهم میکند. این قابلیت در شرایطی که کوئریهای پیچیده و زمانبر وجود دارند و نیاز به دسترسی سریعتر به دادهها است، انتخاب بهتری نسبت به View معمولی است. در این مقاله، نحوه ایجاد، بهروزرسانی و حذف Materialized Viewها را بررسی خواهیم کرد و مثالی کاربردی ارائه میدهیم.
معرفیMaterialized View
درPostgreSQL، Viewها جداول مجازی هستند که دادههای جداول زیرساختی را نمایش میدهند. در حالی که Viewهای ساده میتوانند قابل بهروزرسانی باشند، Materialized Viewها امکان ذخیرهسازی دادهها به صورت فیزیکی را فراهم میکنند. این قابلیت برای کوئریهای سنگین بسیار مفید است و دسترسی سریع به دادهها را ممکن میسازد.
Materialized Viewها معمولاً در انبارهای داده (Data Warehouse) و برنامههای هوش تجاری (BI) مورد استفاده قرار میگیرند.
نحوه ایجاد Materialized View
برای ایجاد یک Materialized View از دستور زیر استفاده کنید:
CREATE MATERIALIZED VIEW [IF NOT EXISTS] view_name
AS
query
WITH [NO] DATA;
توضیحات:
view_name: نام Materialized View را مشخص میکند.
Query: کوئری که دادهها را از جداول پایه بازیابی میکند.
WITH DATA / WITH NO DATA:
WITH DATA: دادهها را در زمان ایجاد View بارگذاری میکند.
WITH NO DATA: بدون بارگذاری دادهها View را ایجاد میکند و آن را غیرقابل خواندن میسازد تا زمانی که دادهها بارگذاری شوند.
IF NOT EXISTS: تنها در صورتی که View از قبل وجود نداشته باشد، آن را ایجاد میکند.
بهروزرسانی دادهها در Materialized View
برای بارگذاری یا بهروزرسانی دادهها از دستور زیر استفاده کنید:
REFRESH MATERIALIZED VIEW view_name;
هنگام بهروزرسانی، PostgreSQL جداول زیرساختی را قفل میکند، که این امر ممکن است منجر به تأخیر یا ایجاد اختلال در عملکرد سایر فرآیندها شود. برای مدیریت این مشکل، میتوان از گزینه CONCURRENTLY استفاده کرد که به PostgreSQL اجازه میدهد تا دادهها را بدون قفل کردن جداول بهروزرسانی کند. این روش نیازمند وجود یک شاخص یکتا(UNIQUE INDEX) برای Materialized View است و در مواقعی که عملیات همزمان ضروری است، بسیار مفید خواهد بود. برای جلوگیری از این موضوع، میتوانید گزینه CONCURRENTLY را استفاده کنید:
REFRESH MATERIALIZED VIEW CONCURRENTLY view_name;
نکات مهم:
استفاده از گزینه CONCURRENTLY نیازمند وجود یک شاخص یکتا (UNIQUE INDEX) برایMaterialized View است.
گزینهCONCURRENTLY از نسخه 9.4 به بعد PostgreSQL در دسترس است.
حذفMaterialized View
برای حذف یک Materialized View از دستور زیر استفاده کنید:
حذف یکMaterialized View تنها خود View را از بین میبرد و دادههای ذخیره شده در جداول زیرساختی اصلی بدون تغییر باقی میمانند. این بدان معناست که دادههای ذخیره شده به صورت فیزیکی در View حذف میشوند، اما تأثیری بر دادههای اصلی ندارد.
DROP MATERIALIZED VIEW view_name;
در این دستور، view_name نام Materialized View مورد نظر برای حذف است.
مثال عملی
ایجادMaterialized View
در این مثال، Materialized Viewای به نام rental_by_category ایجاد میکنیم که مجموع فروش هر دستهبندی را نمایش میدهد. این سناریو در محیطهای تجاری مانند تحلیل فروشگاههای آنلاین، برای تعیین دستهبندیهای پرفروش یا بررسی روند فروش محصولات در دستههای مختلف، کاربرد دارد:
CREATE MATERIALIZED VIEW rental_by_category
AS
SELECT c.name AS category,
sum(p.amount) AS total_sales
FROM (((((payment p
JOIN rental r ON ((p.rental_id = r.rental_id)))
JOIN inventory i ON ((r.inventory_id = i.inventory_id)))
JOIN film f ON ((i.film_id = f.film_id)))
JOIN film_category fc ON ((f.film_id = fc.film_id)))
JOIN category c ON ((fc.category_id = c.category_id)))
GROUP BY c.name
ORDER BY sum(p.amount) DESC
WITH NO DATA;
با توجه به گزینه WITH NO DATA، دادهها بارگذاری نمیشوند و کوئری گرفتن ازView خطا میدهد. برای بارگذاری دادهها از دستور زیر استفاده کنید:
REFRESH MATERIALIZED VIEW rental_by_category;
بازیابی دادهها از Materialized View
SELECT * FROM rental_by_category;
خروجی:
category | total_sales
-------------+-------------
Sports | 4892.19
Sci-Fi | 4336.01
Animation | 4245.31
Drama | 4118.46
Comedy | 4002.48
New | 3966.38
Action | 3951.84
Foreign | 3934.47
Games | 3922.18
Family | 3830.15
Documentary | 3749.65
Horror | 3401.27
Classics | 3353.38
Children | 3309.39
Travel | 3227.36
Music | 3071.52
بهروزرسانی دادهها با CONCURRENTLY
برای استفاده از این گزینه، ابتدا باید یک شاخص یکتا ایجاد کنید:
CREATE UNIQUE INDEX rental_category
ON rental_by_category (category);
سپس دادهها را بهروزرسانی کنید:
REFRESH MATERIALIZED VIEW CONCURRENTLY rental_by_category;
جمعبندی
· Materialized View دادههای حاصل از کوئریها را به صورت فیزیکی ذخیره میکند.
· از دستورCREATE MATERIALIZED VIEW برای ایجاد، REFRESH MATERIALIZED VIEW برای بهروزرسانی وDROP MATERIALIZED VIEW برای حذف استفاده کنید.
· گزینه CONCURRENTLY امکان بهروزرسانی بدون قفل کردن جداول زیرساختی را فراهم میکند.
Materialized Viewها ابزار مفیدی برای بهبود عملکرد کوئریهای پیچیده و دسترسی سریع به دادهها هستند، اما دارای محدودیتهایی نیز میباشند. برای مثال، دادههای ذخیرهشده در Materialized View بهصورت خودکار بهروزرسانی نمیشوند و نیاز به اجرای دستی یا برنامهریزیشده دستور REFRESH دارند. همچنین، استفاده از فضای دیسک برای ذخیرهسازی دادهها ممکن است چالشبرانگیز باشد. امیدواریم این مقاله راهنمای کاملی برای استفاده از این قابلیت باشد.