SQLГлава 20. Представление. ВведениеПРЕДСТАВЛЕНИЕ (VIEW) это объект данных, который не содержит никаких данных его владельца. Это тип таблицы, чьё содержание выбирается из других таблиц с помощью выполнения запроса. По мере изменения значений в таблицах, эти изменения автоматически отражаются представлением. В этой главе вы узнаете, что такое представления, как они создаются, и немного о их возможностях и ограничениях. Использование представлений, основанных на улучшенных средствах запросов, таких как объединение и подзапрос, разработанных очень тщательно, в некоторых случаях даст больший выигрыш по сравнению с запросами. Что такое представление?Таблицы, с которыми вы имели дело до сих пор, назывались базовыми таблицами. Это таблицы, которые содержат данные. Однако имеется другой вид таблиц - представления. Представления это таблицы, чьё содержание выбирается или получается из других таблиц. Они работают в запросах и операторах DML точно так же, как и основные таблицы, но не содержат никаких собственных данных. Представления подобны окнам, через которые вы просматриваете информацию (как она есть, или в другой форме, как вы потом увидите), которая реально хранится в базовой таблице. Представление это фактически запрос, который выполняется всякий раз, когда представление становится темой команды. Вывод запроса при этом в каждый момент становится содержанием представления. Команда CREATE VIEW
Вы создаёте представление командой CREATE VIEW Londonstaff AS SELECT * FROM Salespeople WHERE city = 'London';
Теперь у вас есть представление Давайте сделаем запрос представления (вывод показан на Рисунке 20.1): SELECT * FROM Londonstaff; =============== SQL Execution Log ============ | | | SELECT * | | FROM Londonstaff; | | | | ==============================================| | snum sname city comm | | ------ ---------- ----------- ------- | | 1001 Peel London 0.1200 | | 1004 Motika London 0.1100 | | | =============================================== Рисунок 20.1 Представление Londonstaff
Когда вы приказываете SQL выбрать ( Преимущество использования представления, по сравнению с основной таблицей, в том, что представление будет модифицировано автоматически всякий раз, когда изменится таблица, лежащая в его основе. Содержание представления не фиксировано и переназначается каждый раз, когда вы ссылаетесь на представление в команде. Если вы добавите завтра другого живущего в Лондоне продавца, он автоматически появится в представлении. Представления значительно расширяют управление вашими данными. Это превосходный способ дать публичный доступ к некоторой, но не всей, информации в таблице. Если вы хотите, чтобы ваш продавец был показан в таблице Продавцов, но при этом не были показаны комиссионные других продавцов, вы могли бы создать представление с использованием следующего оператора (вывод показан на Рисунке 20.2): CREATE VIEW Salesown AS SELECT snum, sname, city FROM Salespeople; =============== SQL Execution Log ============ | | | SELECT * | | FROM Salesown; | | | | ==============================================| | snum sname city | | ------ ---------- ----------- | | 1001 Peel London | | 1002 Serres San Jose | | 1004 Motika London | | 1007 Rifkin Barcelona | | 1003 Axelrod New York | =============================================== Рисунок 20.2 Представление Salesown Другими словами, это представление - такое же, как для таблицы Продавцов, за исключением того что поле comm не упоминалось в запросе и, следовательно, не было включено в представление. Модифицирование представленийПредставление может теперь изменяться командами модификации DML, но модификация не будет воздействовать на само представление. Команды будут на самом деле перенаправлены в базовую таблицу: UPDATE Salesown SET city = 'Palo Alto' WHERE snum = 1004; Его действие идентично выполнению той же команды в таблице Продавцов. Однако, если значение комиссионных продавца будет обработано командой UPDATE UPDATE Salesown SET comm = 0.20 WHERE snum = 1004; она будет отвергнута, так как поле comm отсутствует в представлении Salesown. Это важное замечание, показывающее, что не все представления могут быть модифицированы. Мы будем исследовать проблемы модификации представлений в Главе 21. Именование столбцовВ нашем примере поля наших представлений имеют свои имена, полученные прямо из имён полей основной таблицы. Это удобно. Однако вам нужно снабдить ваши столбцы новыми именами:
Имена, которые могут стать именами полей, даются в круглых скобках () после имени таблицы. Они не будут запрошены, если совпадают с именами полей запрашиваемой таблицы. Тип данных и размер этих полей будут отличаться от запрашиваемых полей, которые "передаются" в них. Обычно вы не указываете новых имен полей, но если вы всё-таки сделали это, вы должны делать это для каждого поля в представлении. Комбинирование предикатов представление и основных запросов в представлениях
Когда вы делаете запрос представления, вы, собственно, выполняете запрос. Основной способ для SQL обойти это - объединить предикаты двух запросов в один. Давайте посмотрим ещё раз на наше представление CREATE VIEW Londonstaff AS SELECT * FROM Salespeople WHERE city = 'London'; Если мы выполняем следующий запрос в этом представлении SELECT * FROM Londonstaff WHERE comm > 0.12; он будет такой же, как если бы мы выполнили следующее в таблице Продавцов: SELECT * FROM Salespeople WHERE city = 'London' AND comm > 0.12;
Это прекрасно, за исключением того что появляется возможная проблема с представлением. Имеется возможность комбинации из двух полностью допустимых предикатов и получения предиката, который не будет работать. Например, предположим, что мы создаем ( CREATE VIEW Ratingcount (rating, number) AS SELECT rating, COUNT (*) FROM Customers GROUP BY rating;
Это даёт нам число заказчиков, которое мы имеем для каждого уровня оценки ( SELECT * FROM Ratingcount WHERE number = 3; Посмотрим, что случится если мы скомбинируем два предиката: SELECT rating, COUNT (*) FROM Customers WHERE COUNT (*) = 3 GROUP BY rating;
Это недопустимый запрос. Агрегатные функции, такие как SELECT rating, COUNT (*) FROM Customers GROUP BY rating; HAVING COUNT (*) = 3;
Но SQL может не выполнить превращения. Может ли равноценный запрос вместо запроса Если команда допустима, вы можете использовать представления, чтобы установить некоторые ограничения SQL в синтаксисе запроса. Групповые представления
Групповые представления это представления, наподобие запроса Групповые представления могут стать превосходным способом непрерывной обработки полученной информации. Предположим, что каждый день вы должны следить за порядком номеров заказчиков, номерами продавцов принимающих заказы, номерами заказов, средним количеством заказов и общей суммой приобретений в заказах. Чем конструировать каждый раз сложный запрос, вы можете просто создать следующее представление: CREATE VIEW Totalforday AS SELECT odate, COUNT (DISTINCT cnum), COUNT (DISTINCT snum), COUNT (onum), AVG (amt), SUM (amt) FROM Orders GROUP BY odate; Теперь вы сможете увидеть всю эту информацию с помощью простого запроса: SELECT * FROM Totalforday; Как мы видели, SQL-запросы могут дать вам полный комплекс возможностей, так что представления обеспечивают вас чрезвычайно гибким и мощным инструментом чтобы определить точно, как ваши данные могут быть использованы. Они могут также делать вашу работу более простой, переформатируя данные удобным для вас способом и исключив двойную работу. Представления и объединенияПредставления не требуют, чтобы их вывод осуществлялся из одной базовой таблицы. Так как почти любой допустимый запрос SQL может быть использован в представлении, оно может выводить информацию из любого числа базовых таблиц или из других представлений. Мы можем, например, создать представление, которое показывало бы заказы продавца и заказчика по имени: CREATE VIEW Nameorders AS SELECT onum, amt, a.snum, sname, cname FROM Orders a, Customers b, Salespeople c WHERE a.cnum = b.cnum AND a.snum = c.snum;
Теперь вы можете выбрать (
Например, чтобы увидеть все заказы продавца SELECT * FROM Nameorders WHERE sname = 'Rifkin'; =============== SQL Execution Log ============== | | | SELECT * | | FROM Nameorders | | WHERE sname = 'Rifkin'; | | =============================================== | | onum amt snum sname cname | | ------ -------- ----- ------- ------- | | 3001 18.69 1007 Rifkin Cisneros | | 3006 1098.16 1007 Rifkin Cisneros | | | ================================================= Рисунок 20.3 Заказы Rifkin, показанные в Nameorders
Вы можете также объединять представления с другими таблицами, базовыми таблицами или представлениями, поэтому вы можете увидеть все заказы продавца SELECT a.sname, cname, amt comm FROM Nameorders a, Salespeople b WHERE a.sname = 'Axelrod' AND b.snum = a.snum; Вывод для этого запроса показан на Рисунке 20.4. В предикате мы могли бы написать: WHERE a.sname = 'Axelrod' AND b.sname = 'Axelrod' но предикат, который мы использовали здесь, более общеупотребителен. Кроме того, поле snum это первичный ключ таблицы Продавцов, и, следовательно, должно, по определению, быть уникальным. =============== SQL Execution Log ============== | | | SELECT a.sname, cname, amt * comm | | FROM Nameorders a, Salespeople b | | WHERE a.sname = 'Axelrod' | | AND b.snum = a.snum; | | =============================================== | | onum amt snum sname cname | | ------ -------- ----- ------- ------- | | 3001 18.69 1007 Rifkin Cisneros | | 3006 1098.16 1007 Rifkin Cisneros | | | ================================================= Рисунок 20.4 Объединение основной таблицы с представлением
Если бы там, например, было два Представления и подзапросыПредставления могут также использовать и подзапросы, включая соотнесённые подзапросы. Предположим, ваша компания предусматривает премию для тех продавцов, которые имеют заказчика с самым высоким заказом для любой указанной даты. Вы можете проследить эту информацию с помощью представления: CREATE VIEW Elitesalesforce AS SELECT b.odate, a.snum, a.sname, FROM Salespeople a, Orders b WHERE a.snum = b.snum AND b.amt = (SELECT MAX (amt) FROM Orders c WHERE c.odate = b.odate); Если, с другой стороны, премия будет назначаться только продавцу, который имел самый высокий заказ за последние десять лет, вам необходимо будет проследить их в другом представлении, основанном на первом: CREATE VIEW Bonus AS SELECT DISTINCT snum, sname FROM Elitesalesforce a WHERE 10 <= (SELECT COUNT (*) FROM Elitesalestorce b WHERE a.snum = b.snum); Извлечение из этой таблицы продавца, который будет получать премию, выполняется простым запросом: SELECT * FROM Bonus; Теперь мы видим истинную мощность SQL. Извлечение той же полученной информации программами RPG или COBOL будет более длительной процедурой. В SQL это - только вопрос из двух комплексных команд, сохранённых как представление совместно с простым запросом. При самостоятельном запросе мы должны заботится об этом каждый день, потому что информация которую извлекает запрос, непрерывно меняется, чтобы отражать текущее состояние базы данных. Что не могут делать представления?Имеется большое количество типов представлений (включая многие из наших примеров в этой главе), которые являются доступными только для чтения. Это означает, что их можно запрашивать, но они не могут подвергаться действиям команд модификации. (Мы будем рассматривать эту тему в Главе 21.) Имеются также некоторые виды запросов, которые недопустимы в определениях представлений.
Вывод запроса формирует содержание представления, которое напоминает базовую таблицу и является - по определению - неупорядоченным. Удаление представленийСинтаксис удаления представления из базы данных подобен синтаксису удаления базовых таблиц: DROP VIEW <имя_представления> В этом нет необходимости, потому что содержимое представления не является созданным и сохраняется на период действия определенной команды. Базовая таблица, из которой представление выводится, не задействуется, когда представление удалено. Помните, вы должны являться владельцем представления, чтобы иметь возможность удалить его. РезюмеТеперь, когда вы можете использовать представления, ваша способность отслеживать и обрабатывать содержание БД значительно расширилась. Всё, что вы можете создать запросом, вы всегда сможете определить как представление. Запросы этих представлений это, фактически, запрос запроса. Использование представлений и для удобства, и для защиты также удобно, как и многие возможности представлений для форматирования и получения значений из постоянно меняющегося содержания вашей БД. Имеется один главный вывод относительно представлений: это способность к модификации. Как показано, вы можете модифицировать представления так же, как и базовую таблицу, с помощью изменений, применяемых к таблице, из которой получается представление, но это не всегда возможно. Работа с SQL1. Создайте представление, которое показывало бы всех заказчиков, имеющих самые высокие рейтинги. 2. Создайте представление, которое показывало бы номер продавца в каждом городе. 3. Создайте представление, которое показывало бы усреднённый и общий заказы для каждого продавца после его имени. Предполагается, что все имена уникальны. 4. Создайте представление, которое показывало бы каждого продавца с несколькими заказчиками. (См. ответы в Приложении A.) |
||