СОЗДАНИЕ ВИДА
Синтаксис
CREATE
[OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW [IF NOT EXISTS] view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
Описание
Оператор CREATE VIEW создаёт новый вид или заменяет существующий, если указан фрагмент OR REPLACE. Если вида не существует, то CREATE OR REPLACE VIEW эквивалентен CREATE VIEW. Если вид существует, то CREATE OR REPLACE VIEW эквивалентен ALTER VIEW.
select_statement — это оператор SELECT, который определяет вид. (При запросе данных из вида фактически используется оператор SELECT.) select_statement может ссылаться на базовые таблицы или другие виды.
Определение вида «замораживается» во время создания, поэтому изменения в подлежащих таблицах после этого не влияют на определение вида. Например, если вид определён как SELECT * из таблицы, новые столбцы, добавленные в таблицу позже, не станут частью вида. SHOW CREATE VIEW демонстрирует, что такие запросы переписываются, и имена столбцов включены в определение вида.
Определение вида должно быть запросом, который не возвращает ошибок во время создания вида. Однако базовые таблицы, используемые видами, могут быть изменены позже, и запрос может больше не быть корректным. В этом случае запрос к виду приведёт к ошибке. CHECK TABLE помогает найти такие проблемы.
Оператор ALGORITHM влияет на то, как MariaDB обрабатывает вид. Операторы DEFINER и SQL SECURITY определяют контекст безопасности, который будет использоваться при проверке разрешений на доступ во время вызова вида. Оператор WITH CHECK OPTION может быть добавлен для ограничения вставки или обновления строк в таблицах, на которые ссылается вид. Эти операторы описаны позже в этом разделе.
Для создания вида требуется право CREATE VIEW для вида и некоторые права для каждого столбца, выбранного оператором SELECT. Для столбцов, используемых в операторе SELECT где-либо ещё, необходимо право SELECT. Если фрагмент OR REPLACE присутствует, необходимо также право DROP для вида.
Вид принадлежит базе данных. По умолчанию новый вид создаётся в базе данных по умолчанию. Чтобы явно создать вид в заданной базе данных, укажите имя в формате db_name.view_name при его создании.
CREATE VIEW test.v AS SELECT * FROM t;
Базовые таблицы и виды делят одно и то же пространство имён внутри базы данных, поэтому база данных не может содержать базовую таблицу и вид с одинаковым именем.
Виды должны иметь уникальные имена столбцов без дубликатов, как и базовые таблицы. По умолчанию используются имена столбцов, полученные из оператора SELECT, для имён столбцов вида. Чтобы определить явные имена для столбцов вида, можно использовать необязательный фрагмент column_list, содержащий список идентификаторов, разделённых запятыми. Количество имён в column_list должно совпадать с количеством столбцов, полученных из оператора SELECT.
До MySQL 5.1.29, при модификации существующего вида, текущее определение вида резервируется и сохраняется. Оно хранится в каталоге базы данных таблицы в подкаталоге arc. Файл резервной копии вида v называется v.frm-00001. Если вид изменяется снова, следующая резервная копия называется v.frm-00002. Хранятся три последние резервные копии определений видов. Резервные копии определений видов не сохраняются командами mysqldump или другими подобными программами, но вы можете сохранить их с помощью операции копирования файлов. Однако они нужны только для создания резервной копии предыдущего определения вида. Безопасно удалять эти резервные копии, но только когда mysqld не работает. Если вы удалите подкаталог arc или его файлы, когда mysqld работает, вы получите ошибку при следующей попытке изменить вид:
MariaDB [test]> ALTER VIEW v AS SELECT * FROM t; ERROR 6 (HY000): Error on delete of '.\test\arc/v.frm-0004' (Errcode: 2)
Столбцы, полученные из оператора SELECT, могут быть простыми ссылками на столбцы таблиц. Они также могут быть выражениями, использующими функции, константные значения, операторы и т. д.
Неквалифицированные имена таблиц или видов в операторе SELECT интерпретируются относительно базы данных по умолчанию. Вид может ссылаться на таблицы или виды в других базах данных путём квалификации имени таблицы или вида с именем соответствующей базы данных.
Вид может быть создан из многих типов операторов SELECT. Он может ссылаться на базовые таблицы или другие виды. Он может использовать соединения, UNION и подзапросы. Оператор SELECT даже не обязательно должен ссылаться на какие-либо таблицы. Следующий пример определяет вид, выбирающий два столбца из другой таблицы, а также выражение, вычисленное из этих столбцов:
CREATE TABLE t (qty INT, price INT); INSERT INTO t VALUES(3, 50); CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t; SELECT * FROM v; +------+-------+-------+ | qty | price | value | +------+-------+-------+ | 3 | 50 | 150 | +------+-------+-------+
Определение вида ограничено следующими условиями:
- Оператор SELECT не может содержать подзапрос в предложении FROM.
- Оператор SELECT не может ссылаться на системные или пользовательские переменные.
- Внутри хранимой программы определение не может ссылаться на параметры программы или локальные переменные.
- Оператор SELECT не может ссылаться на параметры подготовленных запросов.
- Любая таблица или вид, на которые ссылается определение, должна существовать. Однако после создания вида можно удалить таблицу или вид, на которые ссылается определение. В этом случае использование вида приводит к ошибке. Для проверки определения вида на наличие таких проблем используйте оператор CHECK TABLE.
- Определение не может ссылаться на временную таблицу, и вы не можете создать временный вид.
- Любые таблицы, указанные в определении вида, должны существовать во время определения.
- Вы не можете связать триггер с видом.
- Для допустимых идентификаторов, используемых в качестве имён видов, см. Имена идентификаторов.
ORDER BY разрешён в определении вида, но игнорируется, если вы выбираете из вида с помощью оператора, содержащего собственное ORDER BY.
Другие параметры или фрагменты в определении добавляются к параметрам или фрагментам оператора, который ссылается на вид, но их эффект не определён. Например, если определение вида содержит фрагмент LIMIT, и вы выбираете из вида с помощью оператора, содержащего свой фрагмент LIMIT, не определено, какой LIMIT применяется. Этот же принцип относится к параметрам, таким как ALL, DISTINCT или SQL_SMALL_RESULT, которые следуют за ключевым словом SELECT, и к фрагментам, таким как INTO, FOR UPDATE и LOCK IN SHARE MODE.
Фрагмент PROCEDURE не может быть использован в определении вида и не может быть использован, если вид используется в предложении FROM.
Если вы создаёте вид, а затем изменяете среду обработки запросов, изменяя системные переменные, это может повлиять на результаты, которые вы получите из вида:
CREATE VIEW v (mycol) AS SELECT 'abc'; SET sql_mode = ''; SELECT "mycol" FROM v; +-------+ | mycol | +-------+ | mycol | +-------+ SET sql_mode = 'ANSI_QUOTES'; SELECT "mycol" FROM v; +-------+ | mycol | +-------+ | abc | +-------+
Операторы DEFINER и SQL SECURITY определяют учётную запись MariaDB, которая используется при проверке разрешений доступа к виду, когда выполняется оператор, ссылающийся на вид. Они были добавлены в MySQL 5.1.2. Допустимые значения SQL SECURITY — DEFINER и INVOKER. Они указывают, что необходимые права должны принадлежать пользователю, который определил или вызвал вид соответственно. Значение SQL SECURITY по умолчанию — DEFINER.
Если для фрагмента DEFINER задано пользовательское значение, оно должно быть учётной записью MariaDB в формате 'user_name'@'host_name' (тот же формат, что и в операторе GRANT). Значения user_name и host_name оба обязательны. DEFINER также может быть задан как CURRENT_USER или CURRENT_USER(). Значение DEFINER по умолчанию — пользователь, выполняющий оператор CREATE VIEW. Это то же самое, что явно указать DEFINER = CURRENT_USER.
Если вы указали фрагмент DEFINER, эти правила определяют допустимые значения пользователя DEFINER:
- Если у вас нет права SUPER или, начиная с MariaDB 10.5.2, права SET USER, единственным допустимым значением пользователя является ваша собственная учётная запись, указанная явно или с помощью CURRENT_USER. Вы не можете установить DEFINER для другой учётной записи.
- Если у вас есть право SUPER или, начиная с MariaDB 10.5.2, право SET USER, вы можете указать любое синтаксически корректное имя учётной записи. Если учётная запись фактически не существует, генерируется предупреждение.
- Если значение SQL SECURITY — DEFINER, но учётная запись DEFINER не существует, когда ссылаются на вид, возникает ошибка.
Внутри определения вида CURRENT_USER по умолчанию возвращает значение DEFINER вида. Для видов, определённых с характеристикой SQL SECURITY INVOKER, CURRENT_USER возвращает учётную запись вызывающего вида. Сведения о проверке аудита пользователей в рамках видов см. в http://dev.mysql.com/doc/refman/5.1/en/account-activity-auditing.html.
Внутри хранимой процедуры, определённой с характеристикой SQL SECURITY DEFINER, CURRENT_USER возвращает значение DEFINER процедуры. Это также влияет на вид, определённый в такой программе, если определение вида содержит значение DEFINER в виде CURRENT_USER.
Права на вид проверяются следующим образом:
- Во время определения вида создатель вида должен иметь права, необходимые для использования верхнеуровневых объектов, к которым обращается вид. Например, если определение вида ссылается на столбцы таблиц, создатель должен иметь права на эти столбцы, как описано ранее. Если определение ссылается на хранимую функцию, проверяются только права, необходимые для вызова функции. Права, необходимые для выполнения функции, можно проверить только при её выполнении: для разных вызовов функции могут быть использованы различные пути выполнения внутри функции.
- Когда вид используется, права на объекты, к которым обращается вид, проверяются по отношению к правам, имеющимся у создателя или вызывающего пользователя вида, в зависимости от того, является ли характеристика SQL SECURITY DEFINER или INVOKER соответственно.
- Если обращение к виду вызывает выполнение хранимой функции, проверка разрешений для операторов, выполняемых внутри функции, зависит от того, определена ли функция с характеристикой SQL SECURITY DEFINER или INVOKER. Если характеристика безопасности — DEFINER, функция выполняется с правами своего создателя. Если характеристика — INVOKER, функция выполняется с правами, определёнными характеристикой SQL SECURITY вида.
Пример: вид может зависеть от хранимой функции, а эта функция может вызывать другие хранимые процедуры. Например, следующий вид вызывает хранимую функцию f():
CREATE VIEW v AS SELECT * FROM t WHERE t.id = f(t.name); Suppose that f() contains a statement such as this: IF name IS NULL then CALL p1(); ELSE CALL p2(); END IF;
Права, необходимые для выполнения операторов внутри f(), должны быть проверены при выполнении f(). Это может означать, что потребуются права для p1() или p2(), в зависимости от пути выполнения внутри f(). Эти права должны быть проверены во время выполнения, и пользователь, который должен обладать этими правами, определяется значениями SQL SECURITY вида v и функции f().
Фрагменты DEFINER и SQL SECURITY для видов являются расширениями стандартного SQL. В стандартном SQL виды обрабатываются по правилам SQL SECURITY INVOKER.
Если вы вызываете представление, созданное до MySQL 5.1.2, оно обрабатывается так, как будто оно было создано с клаузой SQL SECURITY DEFINER и с значением DEFINER, равным вашему аккаунту. Однако, поскольку фактический определяющий субъект неизвестен, MySQL выдает предупреждение. Чтобы избавиться от предупреждения, достаточно повторно создать представление, чтобы определение представления включало клаузу DEFINER.
Необязательная клауза ALGORITHM является расширением стандартного SQL. Она влияет на то, как MariaDB обрабатывает представление. ALGORITHM принимает три значения: MERGE, TEMPTABLE или UNDEFINED. По умолчанию используется алгоритм UNDEFINED, если клауза ALGORITHM отсутствует. Более подробную информацию см. в разделе Алгоритмы представлений.
Некоторые представления обновляемые. То есть вы можете использовать их в операторах, таких как UPDATE, DELETE или INSERT, для обновления содержимого основной таблицы. Для того, чтобы представление было обновляемым, должна существовать взаимно однозначная связь между строками в представлении и строками в основной таблице. Также есть некоторые другие конструкции, которые делают представление не обновляемым. Подробности см. в разделе Вставка и обновление с помощью представлений.
С опцией проверки
Для обновляемого представления может быть указана клауза WITH CHECK OPTION, чтобы предотвратить вставки или обновления строк, за исключением тех, для которых условие WHERE в select_statement истинно.
В клаузе WITH CHECK OPTION для обновляемого представления ключевые слова LOCAL и CASCADED определяют область проверки при определении представления на основе другого представления. Ключевое слово LOCAL ограничивает опцию проверки только определяемым представлением. CASCADED вызывает проверку и для базовых представлений. Если ни одно ключевое слово не указано, по умолчанию используется CASCADED.
Дополнительную информацию об обновляемых представлениях и клаузе WITH CHECK OPTION см. в разделе Вставка и обновление с помощью представлений.
Если представление не существует
Клауза IF NOT EXISTS была добавлена в MariaDB 10.1.3
При использовании клаузы IF NOT EXISTS MariaDB вернёт предупреждение вместо ошибки, если указанное представление уже существует. Не может быть использована совместно с клаузой OR REPLACE.
Атомарные DDL
MariaDB 10.6.1 поддерживает Атомарные DDL, и CREATE VIEW является атомарным.
Примеры
CREATE TABLE t (a INT, b INT) ENGINE = InnoDB; INSERT INTO t VALUES (1,1), (2,2), (3,3); CREATE VIEW v AS SELECT a, a*2 AS a2 FROM t; SELECT * FROM v; +------+------+ | a | a2 | +------+------+ | 1 | 2 | | 2 | 4 | | 3 | 6 | +------+------+
OR REPLACE и IF NOT EXISTS:
CREATE VIEW v AS SELECT a, a*2 AS a2 FROM t; ERROR 1050 (42S01): Table 'v' already exists CREATE OR REPLACE VIEW v AS SELECT a, a*2 AS a2 FROM t; Query OK, 0 rows affected (0.04 sec) CREATE VIEW IF NOT EXISTS v AS SELECT a, a*2 AS a2 FROM t; Query OK, 0 rows affected, 1 warning (0.01 sec) SHOW WARNINGS; +-------+------+--------------------------+ | Level | Code | Message | +-------+------+--------------------------+ | Note | 1050 | Table 'v' already exists | +-------+------+--------------------------+
См. также
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/create-view/