#mysql #sql #views
#mysql #sql #Вид
Вопрос:
У меня есть пара вопросов, касающихся опции проверки в MySQL:
1) Я знаю, что with check option
не добавляет записи, которые не удовлетворяют WHERE
предложению в запросе subselect, используемом для определения представления, но что произойдет, если with check option
не выбрано? Зачем добавлять строки, которые не удовлетворяют WHERE
предложению?
2) В чем разница между LOCAL
/ CASCADED
with check option
?
Комментарии:
1. какой сервер вы используете? MSSQL, PostgreSQL, Oracle?
Ответ №1:
Подумайте об этом подробнее, когда будете выполнять ОБНОВЛЕНИЕ. Когда вы выполняете ОБНОВЛЕНИЕ для базовой таблицы и впоследствии выполняете SELECT, строки, которые вы только что обновили, все еще там.
Теперь представьте представление, которое выбирает строки из базовой таблицы на основе их идентификатора от 2 до 5, и пользователь выполняет эти запросы:
SELECT * from View
UPDATE View set ID = ID 3
SELECT * from View
Теперь, внезапно, строки исчезли.
Ответ №2:
Без WITH CHECK OPTION
обновления ( INSERT
/ UPDATE
/ MERGE
/ DELETE
WHERE
и т.д.) просматриваемой таблицы приведет к обновлению базовых таблиц, лежащих в ее основе, независимо от VIEW
предложения в, , (при условии, что СУБД считает представление обновляемым). Если вы INSERT
добавите строку в a, VIEW
которая не удовлетворяет WHERE
предложению, а затем обновите VIEW
, то вновь вставленная строка не будет видна в VIEW
. WITH CHECK OPTION
Предотвратило бы возникновение такой «странной» ситуации, но дело не только в этом.
Рассмотрим VIEW
, созданное для того, чтобы разрешить определенному пользователю (группе пользователей, приложению и т.д.) Просматривать только подмножество строк в таблице, Например, Чтобы разрешить им просматривать данные для персонала, не позволяя им просматривать сведения о руководящих сотрудниках: отмените права на чтение в базовой таблице для этого пользователя и вместо этого предоставьте их в представлении. WITH CHECK OPTION
Позволяет вам сделать то же самое для прав на запись, в этом случае это предотвратило бы INSERT
доступ к представлению, если бы это создало строку executive employee.
Аналогичные методы могут быть использованы для обеспечения соблюдения ограничений на уровне строк, например, что в компании может быть только один президент, принудительно используя предложение INSERT
via a, VIEW
чье WHERE
позволяет использовать только одного сотрудника на компанию.
как вы можете определить условие, что «у компании может быть только один президент»
Вот простой пример (без FKS и т.д.) С использованием стандартного SQL:
CREATE TABLE Employees
( company_id CHAR(8) NOT NULL,
employee CHAR(10) NOT NULL UNIQUE,
job_title VARCHAR(20) NOT NULL );
CREATE VIEW Presidents
AS
SELECT *
FROM Employees
WHERE job_title = 'president'
AND 1 >= ( SELECT COUNT(*)
FROM Employees e
WHERE e.job_title = 'president'
GROUP
BY e.company_id )
WITH CHECK OPTION;
INSERT INTO Employees VALUES ( 'Acme', '1', 'president' );
INSERT INTO Employees VALUES ( 'Acme', '2', 'president' );
Вторая вставка завершается неудачно, потому что это привело бы к тому, что количество президентов для company Acme
было бы больше единицы, поэтому часть запроса «подзапрос» привела бы к удалению нового президента из результирующего набора представления, и транзакция фактически была бы откатана.
Комментарии:
1. можете ли вы привести пример того, что вы сказали в последнем абзаце? Обновляемое представление имеет некоторые ограничения, т.е. не имеет
group by
,having
aggrgate function
и т.д. Тогда как вы можете определить условие, что «у компании может быть только один президент»?2. Это неверный пример. MySQL не позволит вам создать это определение представления в первую очередь. Я попытался выполнить то же самое в MySQL и получил ошибку при создании представления — «ПРОВЕРИТЬ ПАРАМЕТР для необновляемого представления»
3. @anurag честно говоря, я сказал, что это стандартный SQL, а не диалект MySQL. Я бы надеялся, что за 11 лет, прошедших с момента моего ответа, продукт MySQL догнал бы версию стандарта SQL 1992 года!