Представления

Для пользователя представления выглядят как таблицы: двумерная структура из строк и столбцов, к которой пользователь может писать SELECT и DML запросы. Программист знает правду: представление это всего лишь команда SELECT с именем. Любой SELECT запрос возвращает двумерный набор данных. Когда SELECT запрос сохранен как представление, то когда бы пользователь не читал или обновлял данные в представлении (думая что это таблица) запрос выполняется и результат представляется пользователя как будет это таблица. Команда SELECT на которой базируется представление может быть чем угодно. Объединением таблиц, результатом после аггрегации, сортировки. Абсолютно любой валидный запрос может быть основой для представления.

 

EXAM TIP

Views share the same namespace as tables: anywhere that a table name can be used, a view name is also syntactically correct.

Зачем нужны представления

Возможными причинами могут быть: безопасность, упрощение пользовательских запросов, предотвращение ошибок, улучшение производительности и преобразование данных в более понятный вид. Таблица и название столбцов обычно имеют длинные и неонпятные названия. Представление и его столбцы могут быть более понятными.

Представления для безопасности

Иногда пользователь должен видеть только определённые строки или столбцы таблицы. Доступно несколько способов для достижения этой цели, но создание представления обычно наиболее лёгкий. К примеру таблица HR.EMPLOYEES содержит личную информацию которая не должна быть видна никому кроме отдела персонала. Но финансовый отдел должен видеть информацию о затратах. Такое представление может убрать личную информацию

create view hr.emp_fin as select hire_date,job_id,salary,commission_pct,department_id from hr.employees;

 

Обратите внимание на название схемы для таблицы источника и схемы представления: представления это объекты схемы и могут получать данные из таблицы той же схемы, или другой. Если схема не указана явно используется текущая схема.

Финансовый отдел может получить доступ к представлению но не к таблице и тогда сотрудники смогут выполнять запросы вида

 

select * from emp_fin where department_id=50;

 

Будет доступно всего пять столбцов вместо всех столбцов таблицы EMPLOYEES. Представление можно объединять с другими таблицами или использовать функции аггрегация как будто это таблица

 

select department_name, sum(salary) from departments natural join emp_fin group by department_name;

 

Хорошо продуманный набор представлений может реализовывать всю систему безопасности в БД, предоставляя пользователям доступ к данным которые им необходимы и сокрывая всё остальное.

Представления для упрощения запросов

Для пользователя будет гораздо проще выбирать данные если сложная работа (такая как объединения таблиц или группировка данных с аггрегацией) сделано за них в коде запроса который определяет представление. В предыдущем примере сотрудникам финансового отдела необходимо было объединять представление EMP_FIN с таблицей DEPARTMENTS и суммировать зарплату по департаменту. Но можно создать новое представление

 

create view dept_sal as select d.department_name, sum(e.salary) from departments d left outer join employees e on d.department_id=e.department_id group by department_name order by department_name;

 

И тогда сотрудники смогут писать запросы к представлению DEPT_SAL без необходимости знать ою объединениях или о том как сортировать результат

 

select * from dept_sal;

 

В частности, пользователям даже не надо знать как убедиться что все департаменты отображены, даже в которых нет сотрудников. Представление созданное в примере выше отобразит все департаменты.

Представления для предотвращения ошибок

Пользователи всегда допускают ошибки, но хорошо-спроектированные представления могут предотвратить некоторые из них, возникающие из-за отсустствия понимания как надо понимать данные. В прерыдущем примере мы посмотрели пример когда представление отображает все департаменты, даже в которых нет сотрудников.

Представление помогает представить данные в недвусмысленном виде. Например многие приложения в реальности не удаляют данные. Рассмотрим таблицу

 

create table emp(empno number constraint emp_empno_pk primary key,ename varchar2(10),deptno number,active varchar2(1) default ‘Y’);

 

Столбец ACTIVE это флаг показывающий нанят ли сотрудник в текущий момент и при добавлении строки будет выставлен в ‘Y’. Когда пользователь, через пользовательский интерфейс “удалит” сотрудника, на самом деле выполнится запрос который обновит значение ACTIVE в ‘N’. Если пользователь не знает о структуре таблицы и такой особенности то результат “удаления” будет не очень понятен. Поэтому лучше дать пользователю доступ к представлению

 

create view current_staff as select * from emp where active=’Y’;

 

Запросы к такому представлению не отображат “удалённых” сотрудников.

Представления чтобы сделать данные понятными

Структуры базы данных это нормализованные таблицы. Нет смысла ожидать от пользователя понимания нормализованных данных. Таблицы связываются между собой первчиными ключами и вторичными ключами, но ключи ограничений обычно не видны пользователю, значения ключей генерируются автоматически из сиквенсов. Пользователю нет нужды знать как объединять родительские таблицы с дочерними, он хочет видеть данные в окнах приложения или отчёты содержащие понятную ему информацию. Для этого можно использовать представления.

Помимо удобства предоставления данных пользователю, использование представлений добавляет уровень абстракции между объектами пользователя и объектами БД что может быть полезно при разработке и поддержке. Возможно изменить структуру данных без переписывания приложения. Если изменились таблицы достаточно просто изменить определение таблицы без изменений кода SQL или PL/SQL. Также представления можно использовать для добавления приложению совместимости между разными базами данных.

Представления для производительности

Команда SELECT являющаяся основой для представления может быть оптимизирована программистами, и пользователям не надо переживать об оптимизации кода. Существует много способов получения одного и того же результата, но некоторые способы гораздо медленнее чем другие. Например при объединении двух таблиц обычно происходи выбор между nested loop объединением и hash join объединением. Nested loop использует индекса для поиска конкретной строки, hash join считывает всю таблицу в память. Выбор между методами основывается на данных и необходимых ресурсах.

Теоретически кто-то всегда полагается на результат работы оптимизатора Oracle, но иногда оптимизатор совершает ошибки. Если программист понимает какой метод лучше использовать в конкретном случае то можно дать необходимые иснтрукции оптимизатору. Например этот запрос заставит использовать hash join

 

create view dept_emp as select /*+USE_HASH (employees departments)*/ department_name, last_name from departments natural join employees;

 

Когда бы пользователь не выполнил запрос к представлению DEPT_EMP объединение будет осуществляться поиском совпадений в подсоединяемой таблице в памяти (hash join). Пользователям не нужно знать как заставить базу использовать метод объединения. Мы тоже не будем детально обсуждать оптимизацию но необходимо знать принцип оптимизации при помощи представлений.

Простые и сложные представления

С практической точки зрения, классификация между простыми и сложными представлениями основана на возможности выполнять DML команды к представлению: простые представления могут (обычно) выполнять DML запросы; сложные – не могут. Определим какие представления простые, а какие сложные

  • Простые представления используют данные из одной таблицы, без использваония функций и аггрегации
  • Сложные представления могут использовать объединениям, функции и аггрегацию.

Согласно этим определениями первое и третье представления из прошлой подглавы являютяс простыми, а второе и четвертое сложные.

Команды INSERT, UPDATE  или DELETE нельзя выполнить к сложным представлениям. Соотношение строк в представлении к исходной таблице неможет всегда быть один-к-одному, что необходимо для DML операций. Обычно возможно выполнять DML команды к простым представлениям, но не всегда. Например если представление не включает в себя столбец с ограничением обязательности, тогда INSERT к представление не выполнится успешно (выполнится если у столбца есть значение по умолчанию). Выполнение такого запроса вернет странную ошибку так как ошибка ссылается на таблицу и столбец которого нет в запросе, как показано на примере в рисунке 7-5.

85

Превое представление RNAME_V на рисунке удовлетворяет определению простого представления, однаго команда INSERT не может быть выполена так как отсутствует значение для обязательного поля. Второе представление RUPPERNAME_V – сложное представление так как основано на результате выполнения функции. Это делает невозможным вставку значений, так как нет способа БД узнать что действительно необходимо вставить в таблицу. Однако команда DELETE может быть выполнена, так как нет зависимости от использования функции.

Создание, изменение и удаление представлений

Синтаксис создания представления

 

CREATE [OR REPLACE] [FORCE | NOFORCE] VIEW

[schema.]viewname [(alias [,alias]…]

AS subquery

[WITH CHECK OPTION [CONSTRAINT constraintname]]

[WITH READ ONLY [CONSTRAINT constraintname]] ;

 

Помним что представление это объект схемы. Нет причин не создавать представления владельцем которых является один пользователь, таблицы-основания которых принадлежат другому пользователю. По умолчанию представление будет создано в текущей схеме. Дополнительные директивы которые ещё не использовались в примерах выше это

OR REPLACE – если представление уже существует оно будет удалено перед созданием нового

FORCE или NOFORCE – Использование FORCE приведёт к созданию представления даже если базовые таблицы не существуют. NOFORCE значение по умолчанию и если таблицы не существуют команды выполняется с ошибкой

WITH CHECK OPTION – эта директива влияет на DML команды. Если подзапрос включает условие WHERE, тогда эта директива предотвратит возможность вставки стро которые не видно в представлении, или совершать обновления данных которое приведёт к пропаже данных из представления. По умолчанию эта директива отключена что может приводить к неожидаемым результатам выполнения запросов

WITH READ ONLY – отключения возможности использование DML команд к представлению

CONSTRAINT constraintname – позволяет назначить имя ограничениям WITH CHECK OPTION и WITH READ ONLY и сообщения об ошибке станут более понятными

Набор псевдонимов позволяет назначать новые имена столбцам представления. Если псевдоним не указан, столбец будет иметь такое же имя как в таблице или будет использоваться псевдоним из подзапроса.

Команда ALTER VIEW в основном используется для компиляции представления. Представление должно быть успешно скомпилированно перед использованием. Когда преставление создаётся, Oracle проверяет что все столбцы и таблицы существуют. Если они не существуют компиляция происходит неудачно и представление не будет создано – но будет создано если вы используете директиву FORCE. В этом случае представление создастся, но будет недоступно для использования пока не будут созданы таблицы и столбцы используемые в подзапросе и не будет заново скомпилировано. Когда выполняется запрос к нескомпилированному представлению – Oracle попробует скомпилировать его автоматически. Если компиляция будет успешна (вы устранили проблемы) – то пользователи даже не узнает что что-то не работало – единственное отличие будет в том что запрос будет выполняться чуть дольше. Вам следует самим вручную компилировать представления чтобы убедиться что компиляция прошла успешно, вместо того чтобы позволять пользователям обнаружить ошибку.

Невозможно изменить определения столбцов после создания представления так как это делается для таблицы. Представление должно быть удалено и затем создано новое. Синтаксис команды DROP

 

DROP VIEW [schema.]viewname ;

Использование директивы OR REPLACE  в команде CREATE VIEW приведёт к автоматическому удаление представления (если оно существует) перед созданием.

Добавить комментарий