تغییرات اخیر

در اینجا اطلاعیه‌ها، نسخه‌ها و تغییرات جدید لیارا فهرست می‌شوند.

چگونه از Viewها در SQL استفاده کنیم؟


۲۱ شهریور ۱۴۰۴

وقتی از SQL برای مدیریت داده‌ها استفاده می‌کنیم، جداول اولین چیزی هستند که به ذهن می‌رسند. اما جدول‌ها همیشه پاسخ‌گو نیستند: نمی‌توانیم دسترسی کاربران را فقط به چند ستون محدود کنیم، یا داده‌های ترکیبی از چند جدول را بدون تکرار و پیچیدگی نگه داریم. اینجاست که View ها وارد عمل می‌شوند.

ویوها در واقع جدول‌های مجازی هستند که بر اساس نتیجه‌ی یک کوئری ساخته می‌شوند. بدون اینکه داده‌ای جداگانه ذخیره کنند، امکان ترکیب اطلاعات، ساده‌سازی پرس‌وجوهای پیچیده و حتی مدیریت سطح دسترسی را برای ما فراهم می‌کنند. در این راهنما با مفهوم ویو، کاربردهای آن و نحوه ایجاد و مدیریت آن‌ها در SQL آشنا می‌شویم.

در ادامه خواهید خواند:

  • پیش نیاز
  • درک و ایجاد Viewها
  • تغییر و حذف Viewها
  • جمع بندی
Viewها در SQL

پیش نیاز

برای دنبال کردن این راهنما، شما به یک کامپیوتر نیاز دارید که روی آن سیستم مدیریت پایگاه داده رابطه‌ای (RDBMS) نصب شده باشد و از SQL پشتیبانی کند. دستورات و مثال‌های این راهنما در محیط زیر بررسی شده‌اند:

  • یک سرور با سیستم عامل Ubuntu، با کاربر غیر ریشه که دسترسی sudo دارد و فایروال UFW روی آن پیکربندی شده است.
  • نصب و ایمن‌سازی MySQL روی سرور.

توجه: بسیاری از RDBMS‌ها پیاده‌سازی‌های خاص خود از SQL را دارند. اگرچه دستورات این آموزش در بیشتر RDBMSها کار می‌کنند، اما سینتکس یا خروجی دقیق ممکن است در سیستم‌های غیر از MySQL متفاوت باشد.

همچنین شما به یک پایگاه داده با چند جدول حاوی داده نمونه نیاز دارید تا بتوانید تمرین ایجاد و کار View ها را انجام دهید.

با سرور مجازی Ubuntu لیارا، زیرساخت پروژه‌های خود را سریع و امن راه‌اندازی کن.
✅ نصب آسان و آماده استفاده✅ منابع اختصاصی و پایدار✅ دسترسی کامل SSH
خرید و راه‌اندازی سرور Ubuntu

اتصال به MySQL و راه‌اندازی پایگاه داده نمونه

اگر سیستم SQL شما روی یک سرور راه دور اجرا می‌شود، با استفاده از SSH به سرور خود وصل شوید:

ssh sammy@your_server_ip

سپس پنجره MySQL را باز کنید و sammy را با نام کاربر MySQL خود جایگزین کنید:

mysql -u sammy -p

از این پنجره، یک پایگاه داده با نام views_db ایجاد کنید:

CREATE DATABASE views_db;

اگر پایگاه داده با موفقیت ایجاد شد، خروجی مشابه زیر دریافت خواهید کرد:

Output
Query OK, 1 row affected (0.01 sec)

برای انتخاب پایگاه داده views_db دستور زیر را اجرا کنید:

USE views_db;
Output
Database changed

پس از انتخاب views_db، چند جدول درون آن ایجاد کنید.

فرض کنید شما یک سرویس نگهداری سگ در منزل دارید و می‌خواهید اطلاعات سگ‌ها و کارکنانی که از آن‌ها مراقبت می‌کنند را در SQL ذخیره کنید. برای سازمان‌دهی، دو جدول نیاز دارید: یکی برای کارکنان و دیگری برای سگ‌ها.

جدول کارکنان شامل ستون‌های زیر خواهد بود:

  • emp_id: شماره شناسایی هر کارمند، از نوع int. این ستون کلید اصلی جدول خواهد بود و مقدار آن برای هر سطر یکتا است. همچنین روی این ستون UNIQUE اعمال می‌شود.
  • emp_name: نام هر کارمند، از نوع varchar با حداکثر 20 کاراکتر.

برای ایجاد جدول کارکنان، دستور زیر را اجرا کنید:

CREATE TABLE employees (
emp_id int UNIQUE,
emp_name varchar(20),
PRIMARY KEY (emp_id)
);

جدول سگ‌ها شامل ستون‌های زیر خواهد بود:

  • dog_id: شماره شناسایی هر سگ، از نوع int و کلید اصلی جدول
  • dog_name: نام سگ، از نوع varchar با حداکثر 20 کاراکتر
  • walker: شماره شناسایی کارمندی که مسئول مراقبت از سگ است
  • walk_distance: مسافتی که سگ باید پیاده‌روی کند، از نوع decimal(3,2)
  • meals_perday: تعداد وعده غذایی هر سگ در روز، از نوع int
  • cups_permeal: تعداد فنجان‌های غذای خشک هر وعده، از نوع decimal(3,2)

برای اطمینان از اینکه ستون walker فقط شامل مقادیر معتبر باشد، یک کلید خارجی (FOREIGN KEY) روی آن اعمال می‌کنیم که به ستون emp_ID جدول employees ارجاع می‌دهد.

جدول سگ‌ها را با دستور زیر ایجاد کنید:

CREATE TABLE dogs (
dog_id int UNIQUE,
dog_name varchar(20),
walker int,
walk_distance decimal(3,2),
meals_perday int,
cups_permeal decimal(3,2),
PRIMARY KEY (dog_id),
FOREIGN KEY (walker)
REFERENCES employees(emp_ID)
);

اکنون می‌توانید داده‌ای نمونه را در هر دو جدول وارد کنید. ابتدا سه سطر برای کارکنان:

INSERT INTO employees
VALUES
(1, 'Peter'),
(2, 'Paul'),
(3, 'Mary');

سپس هفت سطر برای جدول سگ‌ها:

INSERT INTO dogs
VALUES
(1, 'Dottie', 1, 5, 3, 1),
(2, 'Bronx', 3, 6.5, 3, 1.25),
(3, 'Harlem', 3, 1.25, 2, 0.25),
(4, 'Link', 2, 2.75, 2, 0.75),
(5, 'Otto', 1, 4.5, 3, 2),
(6, 'Juno', 1, 4.5, 3, 2),
(7, 'Zephyr', 3, 3, 2, 1.5);

با این کار آماده هستید تا ادامه راهنما را دنبال کرده و نحوه استفاده از View ها در SQL را یاد بگیرید.

با هاست ابری MySQL لیارا، دیتابیس خودت را سریع و امن راه‌اندازی کن.
✅ منابع اختصاصی ✅ شبکه خصوصی ✅ پشتیبان‌گیری خودکار
خرید و راه‌اندازی هاست ابری MySQL

درک و ایجاد Viewها

بسته به شرایط، کوئری‌های SQL می‌توانند به‌طور شگفت‌آوری پیچیده شوند. در واقع، یکی از مزایای اصلی SQL این است که گزینه‌ها و عبارت‌های متعددی ارائه می‌دهد که به شما امکان می‌دهند داده‌ها را با سطح بالایی از جزئیات و دقت فیلتر کنید. اگر کوئری‌های پیچیده‌ای دارید که باید مرتباً اجرا شوند، نوشتن مداوم آن‌ها می‌تواند سریعا خسته‌کننده شود. یکی از راه‌ها برای حل این مشکل، استفاده از Viewها است.

همان‌طور که در مقدمه ذکر شد، Viewها جدول‌های مجازی هستند. این بدان معناست که اگرچه یک View از نظر عملکردی شبیه جدول است، اما نوع ساختار متفاوتی دارد زیرا خود View داده‌ای نگه نمی‌دارد. در عوض، داده‌ها را از یک یا چند جدول پایه (Base Table) که داده‌ها را نگه می‌دارند، می‌گیرد. تنها اطلاعاتی که سیستم مدیریت پایگاه داده (DBMS) درباره یک View ذخیره می‌کند، ساختار آن است. Viewها گاهی اوقات کوئری‌های ذخیره شده (Saved Queries) نامیده می‌شوند، زیرا اساساً همانند کوئری‌هایی هستند که تحت یک نام خاص ذخیره شده‌اند تا دسترسی به آن‌ها راحت‌تر باشد.

برای درک بهتر Viewها، به مثال زیر توجه کنید. تصور کنید کسب‌وکار مراقبت از سگ شما خوب پیش می‌رود و نیاز دارید برنامه روزانه کارکنان خود را چاپ کنید. این برنامه باید شامل نام هر سگ تحت مراقبت، نام کارمندی که مسئول مراقبت از آن است، مسافتی که هر سگ باید روزانه پیاده‌روی کند، تعداد وعده‌های غذایی هر سگ در روز و مقدار غذای هر وعده باشد.

با استفاده از مهارت‌های SQL خود، یک کوئری ایجاد می‌کنید تا با داده‌های نمونه، تمام این اطلاعات را برای برنامه استخراج کنید. توجه داشته باشید که این کوئری شامل سینتکس JOIN است تا داده‌ها را از هر دو جدول employees و dogs دریافت کند:

SELECT emp_name, dog_name, walk_distance, meals_perday, cups_permeal
FROM employees JOIN dogs ON emp_ID = walker;
Output
+----------+----------+---------------+--------------+--------------+
| emp_name | dog_name | walk_distance | meals_perday | cups_permeal |
+----------+----------+---------------+--------------+--------------+
| Peter    | Dottie   |          5.00 |            3 |         1.00 |
| Peter    | Otto     |          4.50 |            3 |         2.00 |
| Peter    | Juno     |          4.50 |            3 |         2.00 |
| Paul     | Link     |          2.75 |            2 |         0.75 |
| Mary     | Bronx    |          6.50 |            3 |         1.25 |
| Mary     | Harlem   |          1.25 |            2 |         0.25 |
| Mary     | Zephyr   |          3.00 |            2 |         1.50 |
+----------+----------+---------------+--------------+--------------+
7 rows in set (0.00 sec)

فرض کنید لازم باشد این کوئری را به‌صورت منظم اجرا کنید. نوشتن مکرر آن می‌تواند خسته‌کننده باشد، زمانی که کوئری‌ها طولانی و پیچیده هستند. همچنین اگر بخواهید تغییرات جزئی در کوئری ایجاد کنید یا آن را گسترش دهید، احتمال خطا در سینتکس زیاد است.

در چنین مواردی، یک View مفید است، زیرا View اساساً یک جدول است که از نتایج یک کوئری ایجاد شده است.

برای ایجاد یک View، اکثر RDBMSها از سینتکس زیر استفاده می‌کنند:

CREATE VIEW view_name
AS
SELECT statement;

پس از دستور CREATE VIEW، نامی برای View تعریف می‌کنید که بعداً برای ارجاع به آن استفاده شود. بعد از نام، کلیدواژه AS را وارد می‌کنید و سپس کوئری SELECT را می‌آورید که خروجی آن را می‌خواهید ذخیره کنید. کوئری مورد استفاده برای ایجاد View می‌تواند هر SELECT معتبر باشد و می‌تواند از یک یا چند جدول پایه استفاده کند، به شرط آنکه سینتکس صحیح باشد.

سعی کنید یک View با استفاده از کوئری مثال قبلی ایجاد کنید. این عملیات CREATE VIEW نام View را walking_schedule قرار می‌دهد:

CREATE VIEW walking_schedule
AS
SELECT emp_name, dog_name, walk_distance, meals_perday, cups_permeal 
FROM employees JOIN dogs
ON emp_ID = walker;

پس از آن، می‌توانید از این View استفاده کرده و با آن همانند یک جدول معمولی تعامل داشته باشید. به‌عنوان مثال، می‌توانید تمام داده‌های موجود در View را بازیابی کنید:

SELECT * FROM walking_schedule;
Output
+----------+----------+---------------+--------------+--------------+
| emp_name | dog_name | walk_distance | meals_perday | cups_permeal |
+----------+----------+---------------+--------------+--------------+
| Peter    | Dottie   |          5.00 |            3 |         1.00 |
| Peter    | Otto     |          4.50 |            3 |         2.00 |
| Peter    | Juno     |          4.50 |            3 |         2.00 |
| Paul     | Link     |          2.75 |            2 |         0.75 |
| Mary     | Bronx    |          6.50 |            3 |         1.25 |
| Mary     | Harlem   |          1.25 |            2 |         0.25 |
| Mary     | Zephyr   |          3.00 |            2 |         1.50 |
+----------+----------+---------------+--------------+--------------+
7 rows in set (0.00 sec)

اگرچه این View از دو جدول دیگر مشتق شده است، نمی‌توانید داده‌های آن جداول را مستقیما از View بخوانید مگر آنکه در View موجود باشند. به‌عنوان مثال، کوئری زیر سعی می‌کند ستون walker را از View بازیابی کند، اما شکست خواهد خورد زیرا این ستون در View وجود ندارد:

SELECT walker FROM walking_schedule;
Output
ERROR 1054 (42S22): Unknown column 'walker' in 'field list'

این خطا به این دلیل رخ می‌دهد که ستون walker بخشی از جدول dogs است اما در View ایجاد شده شما شامل نشده است.

همچنین می‌توانید کوئری‌هایی با توابع تجمعی (Aggregate Functions) روی داده‌های View اجرا کنید. مثال زیر از تابع MAX همراه با GROUP BY برای یافتن بیشترین مسافت پیاده‌روی هر کارمند استفاده می‌کند:

SELECT emp_name, MAX(walk_distance) AS longest_walks
FROM walking_schedule GROUP BY emp_name;
Output
+----------+---------------+
| emp_name | longest_walks |
+----------+---------------+
| Peter    |          5.00 |
| Paul     |          2.75 |
| Mary     |          6.50 |
+----------+---------------+
3 rows in set (0.00 sec)

همان‌طور که قبلا ذکر شد، یکی دیگر از دلایل مفید بودن Viewها این است که می‌توانید دسترسی کاربران پایگاه داده را محدود به یک View کنید، نه کل جدول یا پایگاه داده.

به عنوان مثال، فرض کنید یک مدیر دفتر استخدام می‌کنید تا برنامه را مدیریت کند. می‌خواهید او به اطلاعات برنامه دسترسی داشته باشد، اما به سایر داده‌ها دسترسی نداشته باشد. برای این کار، می‌توانید یک حساب کاربری جدید برای او ایجاد کنید:

CREATE USER 'office_mgr'@'localhost' IDENTIFIED BY 'password';

سپس می‌توانید دسترسی خواندن (SELECT) به View walking_schedule به او بدهید، و فقط به همان View، با دستور GRANT زیر:

GRANT SELECT ON views_db.walking_schedule to 'office_mgr'@'localhost';

پس از آن، هر کسی که به حساب office_mgr دسترسی دارد، تنها قادر به اجرای کوئری‌های SELECT روی View walking_schedule خواهد بود.

نحوه نصب MySQL در اوبونتو (راهنمای گام به گام)
نصب MySQL در اوبونتو

تغییر و حذف Viewها

اگر داده‌ای را به یکی از جداولی که View از آن‌ها مشتق شده اضافه یا تغییر دهید، داده‌ها مرتبط به‌طور خودکار به View اضافه یا در آن به‌روزرسانی می‌شود. دستور زیر را اجرا کنید تا یک ردیف دیگر به جدول dogs اضافه کنید:

INSERT INTO dogs VALUES (8, 'Charlie', 2, 3.5, 3, 1);

سپس دوباره تمام داده‌ها را از walking_schedule بازیابی کنید:

SELECT * FROM walking_schedule;
Output
+----------+----------+---------------+--------------+--------------+
| emp_name | dog_name | walk_distance | meals_perday | cups_permeal |
+----------+----------+---------------+--------------+--------------+
| Peter    | Dottie   |          5.00 |            3 |         1.00 |
| Peter    | Otto     |          4.50 |            3 |         2.00 |
| Peter    | Juno     |          4.50 |            3 |         2.00 |
| Paul     | Link     |          2.75 |            2 |         0.75 |
| Paul     | Charlie  |          3.50 |            3 |         1.00 |
| Mary     | Bronx    |          6.50 |            3 |         1.25 |
| Mary     | Harlem   |          1.25 |            2 |         0.25 |
| Mary     | Zephyr   |          3.00 |            2 |         1.50 |
+----------+----------+---------------+--------------+--------------+
8 rows in set (0.00 sec)

این بار، یک ردیف دیگر در نتیجه کوئری مشاهده می‌شود که داده‌ اضافه شده به جدول dogs را نشان می‌دهد. با این حال، View هنوز از همان داده‌ها در همان جدول‌های پایه استفاده می‌کند، بنابراین این عملیات View را به‌صورت مستقیم تغییر نداده است.

بسیاری از RDBMSها به شما اجازه می‌دهند ساختار View را پس از ایجاد آن با استفاده از سینتکس CREATE OR REPLACE VIEW به‌روزرسانی کنید:

مثال سینتکس CREATE OR REPLACE VIEW:

CREATE OR REPLACE VIEW view_name
AS
new SELECT statement

با این سینتکس، اگر View با نام view_name قبلاً وجود داشته باشد، سیستم پایگاه داده آن را به‌روزرسانی می‌کند تا داده‌های بازگردانده شده توسط SELECT جدید را نمایش دهد. اگر View با این نام قبلاً وجود نداشته باشد، DBMS یک View جدید ایجاد می‌کند.

فرض کنید می‌خواهید walking_schedule را تغییر دهید تا به جای نمایش تعداد فنجان‌های غذا برای هر وعده، مقدار کل غذایی که هر سگ در طول روز خورده است را نشان دهد. می‌توانید View را با دستور زیر تغییر دهید:

CREATE OR REPLACE VIEW walking_schedule
AS
SELECT emp_name, dog_name, walk_distance, meals_perday, (cups_permeal * meals_perday) AS total_kibble 
FROM employees JOIN dogs ON emp_ID = walker;

اکنون وقتی این View را کوئری می‌کنید، نتیجه منعکس‌کننده داده‌های جدید View خواهد بود:

SELECT * FROM walking_schedule;
Output
+----------+----------+---------------+--------------+--------------+
| emp_name | dog_name | walk_distance | meals_perday | total_kibble |
+----------+----------+---------------+--------------+--------------+
| Peter    | Dottie   |          5.00 |            3 |         3.00 |
| Peter    | Otto     |          4.50 |            3 |         6.00 |
| Peter    | Juno     |          4.50 |            3 |         6.00 |
| Paul     | Link     |          2.75 |            2 |         1.50 |
| Paul     | Charlie  |          3.50 |            3 |         3.00 |
| Mary     | Bronx    |          6.50 |            3 |         3.75 |
| Mary     | Harlem   |          1.25 |            2 |         0.50 |
| Mary     | Zephyr   |          3.00 |            2 |         3.00 |
+----------+----------+---------------+--------------+--------------+
8 rows in set (0.00 sec)

مانند سایر ساختارهایی که می‌توان در SQL ایجاد کرد، می‌توانید Viewها را با استفاده از سینتکس DROP حذف کنید:

مثال سینتکس DROP VIEW:

DROP VIEW view_name;

به‌عنوان مثال، اگر بخواهید View walking_schedule را حذف کنید، دستور زیر را اجرا کنید:

DROP VIEW walking_schedule;

این دستور walking_schedule را از پایگاه داده شما حذف می‌کند، اما هیچ یک از داده‌های View حذف نمی‌شوند مگر اینکه آن‌ها را از جدول‌های پایه نیز حذف کنید.

چگونه یک پایگاه داده ریموت را برای بهینه‌سازی عملکرد سایت با MySQL روی سرور مجازی اوبونتو راه‌اندازی کنیم؟
پایگاه داده ریموت MySQL روی سرور مجازی

جمع بندی

با مطالعه این راهنما، شما با مفهوم View در SQL آشنا شدید و یاد گرفتید چگونه آن‌ها را ایجاد، کوئری، تغییر و حذف کنید. همچنین دانستید که چرا استفاده از Viewها می‌تواند مفید باشد و یک کاربر MySQL ایجاد کردید که فقط قادر به خواندن داده‌ها از View نمونه‌ای بود که در این راهنما ساخته شد.

اگرچه دستورات ارائه شده در مثال‌ها روی اکثر پایگاه‌های داده رابطه‌ای کار می‌کنند، باید توجه داشته باشید که هر پایگاه داده SQL پیاده‌سازی منحصر به‌فرد خود از این زبان را دارد. بنابراین برای درک کامل‌تر هر دستور و مجموعه گزینه‌های آن، بهتر است به مستندات رسمی DBMS خود مراجعه کنید.