Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

MySQL 뷰(View)의 일관성 문제와 WITH CHECK OPTION으로 해결하는 방법

MySQL에서 업데이트 가능한 뷰(Updateable View)를 사용할 때 한 가지 주의해야 할 점이 있습니다. 뷰는 원래 테이블의 일부 데이터만 보여주기 위해 만드는 것이기 때문에, 뷰를 통해서는 보이지 않는 데이터까지 수정하거나 삽입할 수 있는 상황이 발생할 수 있습니다. 이런 경우 뷰와 실제 테이블 사이에 불일치가 생기면서 뷰의 일관성이 깨지게 됩니다.

WITH CHECK OPTION이란?

뷰의 일관성을 보장하는 가장 확실한 방법은 뷰를 생성하거나 수정할 때 WITH CHECK OPTION 절을 사용하는 것입니다. 이 절은 CREATE VIEW 문에서 선택 사항이지만, 뷰의 일관성을 유지하는 데 매우 유용하게 활용됩니다.

WITH CHECK OPTION 절은 기본적으로 뷰를 통해 보이지 않는 행(row)을 삽입하거나 수정하는 것을 차단합니다. 쉽게 말해, 이 옵션을 적용하면 MySQL이 모든 INSERT 또는 UPDATE 작업이 뷰의 정의 조건에 부합하는지 검증하도록 강제합니다.

문법(Syntax)

CREATE OR REPLACE VIEW view_name AS Select_statement WITH CHECK OPTION;

예제로 살펴보기

개념을 이해하기 위해 다음과 같은 'student_info' 테이블의 데이터를 사용해 보겠습니다.

mysql> Select * from student_info;
+------+---------+------------+------------+
| id   | Name    | Address    | Subject    |
+------+---------+------------+------------+
| 101  | YashPal | Amritsar   | History    |
| 105  | Gaurav  | Chandigarh | Literature |
| 125  | Raman   | Shimla     | Computers  |
| 130  | Ram     | Jhansi     | Computers  |
+------+---------+------------+------------+
4 rows in set (0.08 sec)

1. WITH CHECK OPTION 없이 뷰 생성

먼저 아래 쿼리로 'Info'라는 이름의 뷰를 생성합니다. 이때는 WITH CHECK OPTION을 사용하지 않습니다.

mysql> Create OR Replace VIEW Info AS Select Id, Name, Address, Subject from student_info WHERE Subject = 'Computers';
Query OK, 0 rows affected (0.46 sec)

mysql> Select * from info;
+------+-------+---------+-----------+
| Id   | Name  | Address | Subject   |
+------+-------+---------+-----------+
| 125  | Raman | Shimla  | Computers |
| 130  | Ram   | Jhansi  | Computers |
+------+-------+---------+-----------+
2 rows in set (0.00 sec)

WITH CHECK OPTION을 사용하지 않았기 때문에, 뷰의 정의 조건('Computers' 과목)과 맞지 않더라도 새로운 행을 삽입하거나 기존 행을 수정할 수 있습니다. 아래 예시를 통해 확인해 보겠습니다.

mysql> INSERT INTO Info(Id, Name, Address, Subject) values(132, 'Shyam','Chandigarh', 'Economics');
Query OK, 1 row affected (0.37 sec)

mysql> Select * from student_info;
+------+---------+------------+------------+
| id   | Name    | Address    | Subject    |
+------+---------+------------+------------+
| 101  | YashPal | Amritsar   | History    |
| 105  | Gaurav  | Chandigarh | Literature |
| 125  | Raman   | Shimla     | Computers  |
| 130  | Ram     | Jhansi     | Computers  |
| 132  | Shyam   | Chandigarh | Economics  |
+------+---------+------------+------------+
5 rows in set (0.00 sec)

mysql> Select * from info;
+------+-------+---------+-----------+
| Id   | Name  | Address | Subject   |
+------+-------+---------+-----------+
| 125  | Raman | Shimla  | Computers |
| 130  | Ram   | Jhansi  | Computers |
+------+-------+---------+-----------+
2 rows in set (0.00 sec)

결과를 보면, 새로 삽입된 행(Shyam, Economics)은 'Info' 뷰의 정의 조건과 일치하지 않기 때문에 뷰에는 나타나지 않지만, 실제 테이블에는 그대로 추가되어 있습니다. 이것이 바로 뷰의 일관성이 깨진 상황입니다.

2. WITH CHECK OPTION을 적용하여 뷰 재생성

이번에는 동일한 'Info' 뷰를 WITH CHECK OPTION을 붙여서 다시 생성해 보겠습니다.

mysql> Create OR Replace VIEW Info AS Select Id, Name, Address, Subject from student_info WHERE Subject = 'Computers' WITH CHECK OPTION;
Query OK, 0 rows affected (0.06 sec)

이제 뷰의 정의 조건에 맞는 행을 삽입하려고 하면 MySQL은 정상적으로 허용합니다.

mysql> INSERT INTO Info(Id, Name, Address, Subject) values(133, 'Mohan','Delhi','Computers');
Query OK, 1 row affected (0.07 sec)

mysql> Select * from info;
+------+-------+---------+-----------+
| Id   | Name  | Address | Subject   |
+------+-------+---------+-----------+
| 125  | Raman | Shimla  | Computers |
| 130  | Ram   | Jhansi  | Computers |
| 133  | Mohan | Delhi   | Computers |
+------+-------+---------+-----------+
3 rows in set (0.00 sec)

반대로 뷰의 정의 조건에 맞지 않는 행을 삽입하려고 시도하면, MySQL은 이를 허용하지 않고 오류를 반환합니다.

mysql> INSERT INTO Info(Id, Name, Address, Subject) values(134, 'Charanjeet','Amritsar','Geophysics');
ERROR 1369 (HY000): CHECK OPTION failed

정리

WITH CHECK OPTION은 업데이트 가능한 뷰를 통해 수행되는 모든 데이터 변경 작업이 뷰의 WHERE 조건을 만족하도록 강제하는 안전장치입니다. 뷰를 통해 특정 조건의 데이터만 노출하고자 할 때는 반드시 이 옵션을 함께 사용하는 것이 좋으며, 이를 통해 뷰와 기본 테이블 간의 데이터 불일치 문제를 효과적으로 방지할 수 있습니다.