Справочник от Автор24
Поделись лекцией за скидку на Автор24

Индексы

  • 👀 188 просмотров
  • 📌 166 загрузок
Выбери формат для чтения
Загружаем конспект в формате pdf
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
Конспект лекции по дисциплине «Индексы» pdf
ЛЕКЦИЯ № 13 4.3. Индексы.......................................................................1 4.4. Временные таблицы.................................................11 4.5. Представления..........................................................13 4.6. Комментарии к объектам БД...................................24 4.3. ИНДЕКСЫ Одним из структурных элементов физической памяти, присутствующим в большинстве современных реляционных СУБД, является индекс. Индекс – это средство, обеспечивающее быстрый доступ к строкам таблицы на основе значений одного или нескольких ее столбцов [29]. Индекс служит логическим указателем на физическое размещение (адрес) строк в таблице. В индексе хранятся указатели на строки, где данные встречаются, могут храниться и значения самих данных. В каждой конкретной СУБД индексы организованы разными способами. Общая идея индексного доступа проста – помимо таблицы с данными, есть еще структура, содержащая пары "ключ – номер записи" в виде, позволяющем выполнять быстрый поиск по значению ключа [62]. Одна организация индекса отличается от другой главным образом в способе поиска ключа с заданным значением [63]. Рассмотрим подробно организацию индексов в СУБД Firebird, при этом кратко опишем и особенности индексов в других СУБД. В Firebird индекс представляет собой страничное B+-дерево с префиксной компрессией ключей [62]. B+дерево —структура данных, представляющая собой сбалансированное дерево поиска [57]. Схематически B+-дерево представлено на рис. 4.3. Рис. 4.3. Схематическое представление B+-дерева B+-деревья основываются на таких понятиях, как ключ, страница, степень, корень, узел, лист. Ключом называются данные, хранящиеся в определенном формате. 1 Страница – это объект дерева, хранящий определенное количество ключей, а также указатели на дочерние страницы. Степень (n) – это параметр дерева, определяющий, сколько ключей будет храниться на странице. Он может принимать значения от 2 и более. Корень – это первая страница B+-дерева, которая может хранить от 1 до 2n-1 ключей. Узел – это промежуточная страница B-дерева, на которую есть указатели с корневой или родительской страницы, и которая, в свою очередь, имеет указатели на дочерние узлы или листья. В узле может храниться от n-1 до 2n-1 ключей (в случае B+-дерева в узле хранятся только ключи-разделители). Лист – это страница B-дерева, которая не имеет потомков, то есть указатели на дочерние страницы имеют значение NULL. В листе может храниться от n-1 до 2n-1 элементов. Основной особенностью B+-деревьев является то, что все истинные ключи с указанием на данные хранятся в листьях, а в узлах хранятся только копии ключей (ключи-разделители), содержащие диапазон изменения ключей для поддеревьев и помогающие искать нужный лист. Сбалансированность дерева означает, что длина пути от корня дерева к любому его листу одна и та же [63]. С точки зрения физической организации B-дерево представляется как мультисписочная структура страниц внешней памяти, т.е. каждому узлу дерева соответствует блок внешней памяти (страница) [63]. Поиск в B-дереве - это прохождение от корня к листу в соответствии с заданным значением ключа. Рассмотрим алгоритм поиска ключа в B+-дереве, состоящий из следующих шагов. 1. SQL-сервер обращается к корневой странице индекса (её не нужно считывать с диска, так как она уже находится в оперативной памяти). 2. Последовательно сравниваются все ключи корневой страницы с искомым ключом. Ключи сравниваются от меньшего к большему, пока они меньше искомого ключа. 3. Если искомый ключ найден, то в случае узла поиск продолжится в правом поддереве (поскольку в узле хранится лишь копия ключа). В случае листа:  выбирается указатель на строку в основной таблице, и проверяется следующий ключ;  так повторяется, пока не закончатся искомые ключи, после чего поиск завершается;  если последний ключ листа – искомый, то сервер обращается к следующему листу. 4. Если же ключ не найден, поиск продолжается в левом (если искомый ключ меньше текущего) или в правом поддереве (если искомый ключ больше последнего ключа страницы). 5. пп. 2 - 4 повторяются, пока не будет найден ключ, или пока не будет считана и проверена листовая страница индекса. Во втором случае поиск закончится неудачей. 2 Таким образом, при отсутствии индексов SQL-сервер просмотрит все страницы для поиска одной нужной строки, а при наличии индекса SQLсервер просмотрит только количество страниц, равное глубине B+-дерева. Допустим, необходимо осуществить поиск ключа 22 по дереву, представленному на рис. 4.3. При этом выполняются следующие действия: - последовательно сравниваются ключи корневой страницы на совпадение с 22; - точное совпадение ключа не найдено, первый ключ корневой страницы 36 (искомый ключ меньше текущего); - спускаемся к левому дочернему узлу (поддереву). Выполняем последовательное сравнение в дочернем узле, доходим до ключа-разделителя 22 (найдено точное совпадение); - к ключам от 22 и выше ведет правый дочерний указатель. Следует обратить внимание на то, что ключ 22 повторяется в листе, где хранятся соответствующие ему данные. Поскольку все ключи повторяются в листьях, их можно связать для последовательного доступа; - переходим по правому указателю на лист, находим ключ 22 и останавливаемся. Найденный ключ содержит указатель на страницу с данными. Использование B+-деревьев позволяет достичь эффективности при прямом поиске, так как они из-за своей сильной ветвистости обладают небольшой глубиной [64]. Кроме того, B+-деревья сохраняют порядок ключей в листовых блоках иерархии, что позволяет производить последовательное сканирование таблицы в порядке возрастания или убывания значений столбцов, на которых определен индекс. Поиск осуществляется достаточно быстро, поскольку значения в индексе упорядочены, а сам индекс относительно невелик. Хорошо спроектированная система индексов играет важную роль в нaстройке и оптимизации условий эксплуатации приложений [29]. Если индекс не существует, то SQL-сервер не знает, сколько удовлетворяющих критерию поиска значений содержится в таблице, поэтому ему приходится просматривать каждую строку и проверять ее на наличие в указанном поле искомого значения. Использование индекса обычно требует меньшего количества обращений к диску, чем последовательное чтение строк в таблице. При выполнении запроса СУБД сначала определяет список индексов, связанных с данной таблицей. Затем устанавливает, что является более эффективным – просмотреть всю таблицу или для обработки запроса использовать существующий индекс, ведя поиск данных по ключевым значениям в индексе с использованием указателей. Firebird в некоторых областях, в частности в области организации индексов, существенно отличается от других СУБД [65]. Далее перечислены основные особенности организации индексов в Firebird по сравнению с другими СУБД. 3 1. Расположение данных. Организация индексов в Firebird не допускает хранения реальных данных в индексе, хранятся только лишь указатели на данные. Данная особенность является отличием от многих других известных СУБД, которые позволяют создавать кластерные индексы, непосредственно хранящие данные ключа. В Firebird любые индексы, в том числе первичный ключ, не являются кластерными. В связи с этим Firebird не требует большого объема ОЗУ (ОЗУ должно хватать для размещения только индексных страниц) и, как правило, не мешает работе других запущенных приложений [66]. Firebird сохраняет записи на страницах данных, используя самую доступную страницу с достаточным свободным местом [65]. Индексы хранятся на страницах индексов и в узле листа содержат местоположение записи. При добавлении строк в середину таблицы не требуется реорганизация страниц с данными (как в случае с кластерными индексами), может произойти только перестроение индекса, не приводящее к значительному ухудшению производительности. 2. Стратегия доступа индекса. Большинство СУБД читает узел индекса, затем считывает данные - эта техника приводит к "прыжкам" между страницами индекса и данными. Для некластерных индексов эта техника также приводит к перечитыванию страниц данных. Firebird собирает местоположения записей из индекса, строит битовую карту расположения записей и затем читает записи в порядке, в котором они физически хранятся [65]. 3. Отсутствие чистого индексного покрытия. Индексный доступ в Firebird требует чтения как страниц индекса для поиска, так и страниц данных для чтения записей [62]. Неверсионные СУБД выполняют некоторые запросы (например, count) путем чтения только страниц индекса, реализуя так называемое чистое индексное покрытие (index only scan). Но такая схема невозможна в Firebird в связи с его архитектурой - ключ индекса содержит только номер записи без информации о ее версии - следовательно, сервер в любом случае должен прочитать страницу данных для определения, видна ли хоть одна из версий с данным ключом для текущей транзакции. 4. Однонаправленные индексы. По сравнению с другими СУБД в Firebird сканирование индекса всегда однонаправленное, от меньших ключей к большим [62]. Часто из-за этого индекс называют однонаправленным и говорят, что в его узле есть указатели только на следующий узел и нет указателя на предыдущий. Такая структура индексов связана с тем, что все структуры сервера Firebird спроектированы как свободные от взаимных блокировок (deadlock free), действует также правило "аккуратной" записи (careful write) страниц, служащее мгновенному восстановлению после сбоя. Двунаправленные индексы нарушают эти правила. Данная особенность приводит к невозможности использования ASCиндекса для DESC-сортировки или вычисления MAX и наоборот, невозможности использования DESC-индекса для ASC-сортировки или 4 вычисления MIN. Сканированию индекса с целью поиска однонаправленность никак не мешает. СУБД Oracle предоставляет много различных типов индексов для использования. Далее приведён их краткий перечень. 1. Индексы со структурой В+-дерева. Это обычные индексы, которые являются наиболее распространёнными индексами в Oracle. В+Tree-индексы имеют несколько подтипов.  Индекс-таблицы. Это таблицы, хранящиеся в структуре В +Tree. В то время как строки данных в традиционной таблице сохраняются в неорганизованной форме (данные отправляются туда, где есть свободное место), данные в индекс-таблице сохраняются и сортируются по первичному ключу. С точки зрения приложения индекс-таблицы ведут себя как «обычные» таблицы: для доступа к ним используется SQL, как обычно. Индекс-таблицы особенно подходят для информационнопоисковых, пространственных и OLAP-приложений.  Кластерные индексы со структурой В+-дерева. Это небольшая вариация обычных индексов В+Tree. Они применяются для индексации кластерных ключей. Вместо ключа, указывающего на строку, как обычные В +Treeиндексы, эти индексы имеют кластерные ключи, указывающие на блок, который содержит строки, объединённые по кластерному ключу.  Индексы, упорядоченные по убыванию. Эти индексы позволяют данным быть отсортированными в порядке от больших к меньшим (по убыванию) в отличие от порядка от меньших к большим (по возрастанию), принятого в индексной структуре.  Индексы по реверсированным ключам. Это В+Tree-индексы, в которых байты ключа обращены. Индексы по реверсированным ключам могут применяться для достижения более равномерного распределения элементов в индексах, которые наполняются в порядке возрастания. Например, если для генерации первичного ключа используется последовательность, то получаются значения вроде 987500, 987501, 987502 и т.д. Значения последовательности являются монотонными, поэтому в случае применения обычного индекса В +Tree они имеют тенденцию поступать в один и тот же правосторонний блок, таким образом увеличивая его содержимое. При использовании индекса с реверсированным ключом СУБД Oracle логически индексирует вместо них значения 205789, 105789, 005789 и т.п. СУБД Oracle реверсирует байты сохраняемых данных перед помещением их в индекс, так что значения, которые до обращения следовали бы в индексе друг за другом, оказываются разбросанными. Обращение байтов индекса рассеивает вставляемые ключи по множеству блоков. 2. Битовые индексы. Обычно в В+Tree существует отношение «один к одному» между элементом индекса и строкой: элемент (запись) индекса указывает на строку. В битовых индексах элемент индекса использует битовую карту для указания на множество строк одновременно. Они подходят для данных с высокой повторяемостью (данных с небольшим 5 количеством возможных различных значений по сравнению с общим количеством строк в таблице), которые в основном доступны только для чтения. Рассмотрим столбец, который принимает три возможных значения – Y, N и NULL – в таблице из миллиона строк. Этот столбец может быть подходящим кандидатом для построения битового индекса, если, к примеру, нужно часто определять количество строк, имеющих в этом столбце значение Y. Это не значит, что битовый индекс по столбцу из 100 различных значений в той же таблице является недопустимым – он вполне имеет право на существование. Битовые индексы не должны применяться в базе данных OLTP для решения проблем, связанных с параллелизмом. Следует учесть, что битовые индексы требуют версий Enterprise Edition или Personal Edition СУБД Oracle. 3. Индексы на основе функций. Это индексы В +Tree или битовые, которые хранят вычисленный результат функции по значению столбца (столбцов), а не само значение столбца. Их можно рассматривать как индексы по виртуальному (или производному) столбцу – другими словами, по столбцу, который не хранится физически в таблице. 4. Индексы предметной области. Эти индексы можно строить и сохранять самостоятельно – либо в СУБД Oracle, либо даже за её пределами. Следует отметить, что индекс, созданный подобным образом, не использует традиционную структуру индекса. Индексы в MS SQL Server создаются для таблиц и представлений в виде особых упорядоченных структур на отдельных страницах базы данных [23]. В MS SQL Server существуют следующие виды индексов. 1. Обычные индексы (реляционные). Такие индексы могут быть кластерными и некластерными. Разница между индексами двух типов состоит в том, что кластерный индекс непосредственно хранит данные, представляет собой настоящую таблицу, т.е. нижний уровень такого индекса содержит реальные строки индексируемой таблицы, включая все столбцы, а некластерный индекс содержит только указатели на данные. В одном конкретном объекте БД может существовать только один кластерный индекс. По умолчанию для первичного ключа таблицы создается именно кластерный индекс. Следовательно, все остальные создаваемые индексы не могут быть кластерными. Кластерный индекс, с одной стороны, делает поиск по первичному ключу очень эффективным, с другой – индекс становится очень громоздким и неплотным, может привести к низкой заполненности страниц или переполнению. Если кластерный индекс создается для таблицы, в которой уже существует большое количество строк, то сам процесс создания такого индекса может потребовать немалого времени. Рекомендуется кластерный индекс создавать прежде, чем будут создаваться другие индексы. В противном случае это потребует немалых затрат на пересоздание всех остальных индексов. 2. Индексы columnstore. Индексы columnstore появились в версии SQL Server 2012. Основное отличие таких индексов от обычных, "реляционных", классических (rowstore) заключается в способе формирования и в форме 6 хранения. При создании обычного индекса группируются и сохраняются данные для строк. Для индекса columnstore выполняется группировка и сохранение данных для столбцов. При этом выполняется сжатие данных. Для некоторых типов запросов к базе такая структура индекса может сильно повысить производительность. Подобные запросы часто используются при работе с так называемыми хранилищами данных. Индекс columnstore может создаваться только для таблиц, но не для представлений. Данные таблицы, для которой создан индекс columnstore, не могут быть изменены. 3. Индексы XML. Столбцы с типом данных XML могут присутствовать в составе и обычного индекса. Для столбцов с этим типом данных можно создать специальные индексы XML. В составе такого индекса может присутствовать только один столбец. Существование индексов XML может сильно повысить производительность системы, если в запросах на выборку данных часто задаются условия поиска, связанные со столбцом XML. Данные в таком столбце могут занимать до 2 Гбайт памяти. При наличии индекса в процессе поиска нет необходимости выполнять синтаксический анализ большого объема данных каждого столбца XML. Такой анализ выполняется один раз при создании индекса и каждый раз при модификации данных XML. Наличие индексов XML может снизить производительность системы, если выполняется частая модификация соответствующих данных. Пространственные индексы. Для столбцов таблиц типа данных GEOMETRY и GEOGRAPHY можно создавать пространственные индексы. В состав пространственного индекса может включаться только один столбец. Хотя использование индексов дает несомненные преимущества по скорости обращения к данным, тем не менее, индексирование оправданно далеко не всегда. Следует помнить, что при всяком обновлении данных должны обновляться и индексы – платой за быстрый поиск является увеличение затрат времени на обновление данных. Кроме этого, сами индексы после большого числа обновлений становятся несбалансированными, вследствие чего время поиска по ним возрастает. В этих условиях при проектировании БД необходимо находить компромисс между требованиями по ускорению поиска данных и по скорости их обновления. Использование индексов, например, для небольших по объему таблиц вообще не оправданно. Если имеется индекс по группе столбцов, то поиск по первому из столбцов группы может прямо использовать этот индекс, следовательно, нет смысла делать по нему отдельный индекс. Если поиск по каким-либо столбцам редок, то построение по ним индекса неэффективно. Следует также иметь в виду, что индексы занимают определенное место в БД. В то же время индексирование может дать существенный эффект при работе с данными, которые часто используются, но редко меняются, например в таблицах-справочниках. Если часто используются запросы, требующие соединения таблиц по какому-либо полю или группе столбцов, то 7 от индексирования таблиц по этим столбцам может быть получен значительный эффект. Кроме этого, индекс может быть полезен, если часто выполняется сортировка данных по столбцу или группе столбцов. Можно сказать, что оптимальный выбор состава и количества индексов зависит и от структуры БД, и от характера ее использования. В СУБД Firebird автоматически создаются индексы по первичным, внешним ключам таблиц и UNIQUE-ограничениям, и их дополнительно создавать не нужно. Такие индексы для ограничений без имени по умолчанию имеют название наподобие RDB$PRIMARY8, RDB$FOREIGN13, RDB$10 и т. д., а для ограничений с именем название индекса совпадает с названием ограничения. Данные в таких индексах по умолчанию располагаются в возрастающем порядке. Рекомендуется создавать индекс для столбцов, которые часто используются в условиях поиска. В SQL индекс для таких столбцов создается запросом CREATE INDEX. В Firebird запрос имеет следующий формат: CREATE [UNIQUE] [ASC | DESC] INDEX имя_индекса ON базовая_таблица {(<список_столбцов>) | COMPUTED BY (<выражение>)};, где имя_индекса задает имя, под которым создаваемый индекс будет определен в БД; базовая_таблица и список_столбцов определяют соответственно имена базовой таблицы и индексируемого(ых) столбца (ов). Необязательные параметры запроса CREATE INDEX:  UNIQUE предотвращает вставку или обновление повторяющихся значений в индексируемые столбцы;  ASC сортирует столбцы в возрастающем порядке (используется по умолчанию);  DESC сортирует столбцы в убывающем порядке. Например, для создания отсортированного по убыванию индекса с именем Month_Index по полю NachislMonth таблицы NachislSumma необходимо применить запрос: CREATE DESC INDEX Month_Index ON NachislSumma (NachislMonth); Если для какой-либо таблицы требуются и возрастающий, и убывающий индексы по одному и тому же столбцу, то нужно создать 2 индекса. В некоторых случаях удобно создать составной индекс, т. е. индекс для нескольких столбцов в таблице. Например, если требуется часто осуществлять поиск и сортировку по адресам абонентов, то можно создать составной индекс для столбцов StreetCD, HouseNo и FlatNo таблицы Abonent. Запрос на создание такого индекса: CREATE INDEX Adres_Index ON Abonent (StreetCD, HouseNo, FlatNo); Результатом выполнения данного запроса будет создание отсортированного по возрастанию индекса Adres_Index, который обеспечит ускорение поиска по адресу абонента. Существует возможность проиндексировать выражения, часто применяемые в запросах. Индекс для выражения создается с помощью секции: 8 COMPUTED BY (<выражение>) запроса CREATE INDEX. Например, можно создать индекс для таблицы Request по выражению, извлекающему значение месяца из столбца IncomingDate, с помощью запроса: CREATE INDEX Ind_1 ON Request COMPUTED BY (EXTRACT(MONTH FROM IncomingDate)); Данный индекс будет доступен для любого запроса с поиском или сортировкой, если они включают выражение EXTRACT(MONTH FROM IncomingDate). Индексы для выражений имеют точно такие же характеристики, как и индексы для столбцов, за исключением того, что они не могут быть составными. После описания ограничения таблицы в Firebird может быть указана следующая конструкция: [USING [ASC[ENDING] | DESC[ENDING]] INDEX имя_индекса]. С помощью такой конструкции можно изменить имя индекса, создаваемого по первичному, внешнему или уникальному ключу таблицы, с системного на пользовательское имя и указать нужный порядок расположения данных в индексе, т. е. можно осуществить переименование автоматически создаваемого индекса и изменение, если требуется, порядка данных в нем. Например, определить в ранее созданной таблице Days столбец Number как первичный ключ, задав для связанного с ним индекса имя Pk_Number и порядок данных по убыванию, можно таким образом: ALTER TABLE Days ADD PRIMARY KEY (Number) USING DESC INDEX Pk_Number; При изменении порядка сортировки данных в индексах следует помнить, что FOREIGN KEY и соответствующий ему PRIMARY KEY должны использовать одинаковый порядок сортировки в связанных с ними индексах. Поиск в индексе осуществляется очень быстро, так как индекс отсортирован и его строки очень короткие. К недостаткам индекса относится то, что он занимает дополнительное дисковое пространство, и то, что индекс необходимо обновлять каждый раз, когда в таблицу добавляется строка или обновляется проиндексированный столбец таблицы. Наличие или отсутствие индекса совершенно незаметно для пользователя, обращающегося к таблице. Если для какого-либо столбца создан индекс, то СУБД будет автоматически его использовать. Чтобы при выполнении запросов деактивизировать или, наоборот, активизировать использование определенного индекса, необходимо воспользоваться запросом ALTER INDEX: ALTER INDEX имя_индекса {ACTIVE | INACTIVE}; При создании любой индекс (как по столбцам ограничений, так и по другим столбцам) автоматически активен. Запрос ALTER INDEX может быть применен для отключения индекса перед добавлением или изменением большого количества строк и устранения при этом дополнительных затрат 9 для поддержки индексов в процессе длительной операции. После этой операции индексирование может быть восстановлено и индексы будут пересозданы. Удаление индекса с заданным именем производится с помощью запроса DROP INDEX: DROP INDEX имя_индекса; В СУБД Oracle для создания индексов используется запрос CREATE INDEX в формате CREATE [UNIQUE|BITMAP] INDEX имя_индекса ON базовая_таблица (<столбец1> [ASC | DESC], [<столбец2> [ASC | DESC], …]); Например, приведенный выше запрос для создания отсортированного по убыванию индекса с именем Month_Index по полю NachislMonth таблицы NachislSumma в Oracle будет выглядеть так: CREATE INDEX Month_Index ON NachislSumma (NachislMonth DESC); Ключевое слово BITMAP указывается, если необходимо создать битовый индекс в Oracle. Запрос ALTER INDEX в Oracle имеет формат: ALTER INDEX имя_индекса {ENABLE|DISABLE};, где опции ENABLE и DISABLE служат для включения и отключения индекса соответственно. СУБД MS SQL Server использует запрос CREATE INDEX для создания обычного индекса, т. е. индекса для столбцов, имеющих "классические" типы данных. Упрощенный формат запроса: CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX имя индекса ON { базовая_таблица | представление } (<столбец1> [ ASC | DESC ] [, <столбец2> [ ASC | DESC ]]...) [ INCLUDE (<столбец1> [, <столбец2>]...) ] [ WHERE <условие фильтра> ] [ WITH (<параметр индекса> [, <параметр индекса>]...) ] ; Индекс создается для одной таблицы или одного представления (такие представления называются индексированными представлениями). Может быть определен как кластеризованный (CLUSTERED) или некластеризованный (NONCLUSTERED). В необязательной секции INCLUDE можно перечислить имена неключевых столбцов (только столбцов, не входящих в состав никаких ключей или индексов), значения которых будут размещаться на уровне листьев (элементов самого нижнего уровня) создаваемого некластерного индекса. Получается как бы суррогат кластерного индекса. Только на нижнем уровне индексной иерархии размещаются не все данные одной строки таблицы, а только отдельные ее столбцы, указанные в этой секции. В запросе создания индекса может присутствовать секция WHERE, которая определяет создание "фильтрованного" индекса – индекса, в состав которого включаются не все строки таблицы, а только те, которые отвечают условиям, заданным в этой секции. Такой фильтрованный индекс не может быть кластерным. 10 Для создания нереляционных индексов в MS SQL Server используются такие запросы, как CREATE COLUMNSTORE INDEX (индексы columnstore), CREATE FULLTEXT INDEX (полнотекстовые индексы), CREATE XML INDEX (индексы XML), CREATE SPATIAL INDEX (пространственные индексы). Подробно с синтаксисом данных запросов можно ознакомиться в [23]. 4.4. ВРЕМЕННЫЕ ТАБЛИЦЫ Ранее были описаны запросы DDL применительно к постоянным (базовым) таблицам, которые характеризуются тем, что их определение и содержимое существуют в БД до тех пор, пока они не будут удалены явно с помощью соответствующих запросов. Часто в процессе работы возникает необходимость сохранения временных данных (например, промежуточных результатов вычислений в хранимых процедурах). Если хранить такие временные данные в обычных таблицах, то требуются постоянное слежение за содержимым таблиц, а также специфическая организация работы с данными. Удобнее в таком случае использовать временные таблицы. Рассмотрим, что представляют собой временные таблицы в Firebird. Они, на самом деле, постоянные, т. е. при их создании информация сохраняется в системной таблице RDB$RELATIONS так же, как и для обычных таблиц. Определение временной таблицы может быть удалено только явно, однако ее содержимое может удаляться или становиться невидимым (недостижимым) автоматически при достижении определенных условий. Временная таблица определяется синтаксисом: CREATE GLOBAL TEMPORARY TABLE имя_временной_таблицы (<определение_столбца1> [, <определение_столбца2> | <ограничение_таблицы>]) [ON COMMIT {DELETE | PRESERVE} ROWS]; Данный синтаксис отличается от синтаксиса создания обычных таблиц фразой GLOBAL TEMPORARY и секцией ON COMMIT. Глобальные временные таблицы могут быть двух типов: с данными, хранимыми в течение текущего соединения (сессии), и с данными, хранимыми только на протяжении выполнения транзакции, использующей временную таблицу. Данные, созданные в разных подключениях (транзакциях), изолированы друг от друга, но метаданные глобальной временной таблицы доступны во всех соединениях и транзакциях. Тип временной таблицы устанавливается с помощью секции ON COMMIT. Если используется ON COMMIT DELETE ROWS, то данные из временной таблицы будут удаляться из БД сразу же после окончания транзакции. Таким образом, таблицы GLOBAL TEMPORARY … DELETE хранят строки только до ближайшей команды COMMIT или ROLLBACK, причем не только транзакции, которая их создала, но и любой другой транзакции в этом же подключении. При этом созданные в таблице строки не видны нигде, кроме текущей транзакции. После использования как ROLLBACK, так и COMMIT, строки во временных таблицах «исчезнут», 11 однако в случае COMMIT все изменения, произведенные над обычными таблицами, будут подтверждены. Следует отметить, что ON COMMIT DELETE ROWS принимается по умолчанию, если секция ON COMMIT не задана. Если создать временную таблицу с помощью запроса: CREATE GLOBAL TEMPORARY TABLE TmpTrans (Id INTEGER NOT NULL, Name VARCHAR (20), CONSTRAINT PK_TmpTrans PRIMARY KEY (Id) ) ON COMMIT DELETE ROWS;, а затем добавить в нее строку INSERT INTO TmpTrans VALUES (1, 'Строка №1');, то после вставки не следует подтверждать транзакцию, иначе строки пропадут. Если теперь выполнить запрос: SELECT * FROM TmpTrans;, ID NAME то в результате можно получить 1 Строка №1 строки, внесенные во временную таблицу (рис. 4.4). Рис. 4.4. Результат выборки данных из временной таблицы После выполнения COMMIT повтор последнего запроса вернет в качестве результата пустую таблицу. Если используется ON COMMIT PRESERVE ROWS, то данные во временной таблице после окончания транзакции остаются в БД до конца соединения, т. е. таблицы GLOBAL TEMPORARY … PRESERVE хранят строки до отсоединения подключения, в котором они были добавлены, причем их видимость ограничена только этим подключением. Например, если создать временную таблицу с помощью запроса: CREATE GLOBAL TEMPORARY TABLE TmpConn (Id INTEGER NOT NULL, Name VARCHAR (35), CONSTRAINT PK_TmpConn PRIMARY KEY (Id) ) ON COMMIT PRESERVE ROWS;, затем добавить в нее строку, например, используя запрос: INSERT INTO TmpConn VALUES (1, 'Запись №1 для текущего соединения');, и подтвердить транзакцию (COMMIT), то в рамках текущего подключения данная строка будет видна из разных транзакций. Если выполнить еще одно подключение к этой же БД (например, запустив еще 1 экземпляр IBExpert) и выполнить тот же самый запрос INSERT, то ошибки «PRIMARY or UNUQIE key constraint» (повтор значения первичного ключа) не возникнет. Как только текущее соединение будет закрыто, вставленные данные пропадут. Временная таблица, так же как и обычная таблица, может иметь индексы, триггеры, ограничения на уровне столбца и на уровне таблицы. Временные таблицы могут быть связаны между собой отношением родитель-потомок (с помощью задания внешнего ключа). Однако следует учитывать ограничения: 12 1) ссылки (ограничения внешнего ключа REFERENCES) между постоянной и временной таблицами запрещены; 2) временная таблица с ON COMMIT PRESERVE ROWS не может иметь ссылку на временную таблицу с ON COMMIT DELETE ROWS. Для просмотра списка всех таблиц БД (постоянных, временных в пределах текущей транзакции и временных в пределах текущего соединения) можно использовать запрос [44]: SELECT R.RDB$RELATION_NAME, T.RDB$TYPE_NAME FROM RDB$RELATIONS R JOIN RDB$TYPES T ON R.RDB$RELATION_TYPE=T.RDB$TYPE WHERE T.RDB$FIELD_NAME = 'RDB$RELATION_TYPE' AND COALESCE(R.RDB$SYSTEM_FLAG, 0) = 0; В заключение можно сказать, что временные таблицы могут быть достаточно полезны для приложений, которые формируют сложные отчеты или производят промежуточные вычисления на сервере. Однако использование временных таблиц может замедлять подключение к БД (использовались таблицы GLOBAL TEMPORARY … DELETE) и отключение от нее (использовались таблицы GLOBAL TEMPORARY … PRESERVE) из-за очистки жесткого диска от версий удаленных строк из таблицы. В Oracle и MS SQL Server также поддерживаются временные таблицы. В Oracle синтаксис создания таких таблиц идентичен приведенному выше. Однако нельзя задавать требования целостности ссылок – временные таблицы не могут быть целевыми для внешнего ключа, и для них нельзя задавать требование внешнего ключа. В MS SQL Server временные таблицы отличаются от постоянных только тем, что хранятся в базе данных tempdb и автоматически удаляются, когда необходимость в них отпадает. Существует два вида временных таблиц: локальные и глобальные. Два типа временных таблиц отличаются друг от друга своими именами, своей видимостью и своей доступностью. Локальные временные таблицы имеют префикс в имени в виде символа #, они видны только в текущем соединении пользователя и удаляются после того, как пользователь отсоединится от экземпляра SQL Server. Глобальные временные таблицы имеют префикс имени в виде двойного символа #, они видны для любого пользователя после их создания и удаляются тогда, когда все пользователи, ссылающиеся на таблицу, отсоединятся от SQL Server. Следует учесть, что временные таблицы создаются в базе данных tempdb и создают дополнительную нагрузку на SQL Server, иногда снижая общую производительность. 4.5. ПРЕДСТАВЛЕНИЯ Представление – это виртуальная таблица, созданная на основе запроса из базовой таблицы. Представление, как и реальная (базовая) таблица, имеет имя, содержит строки и столбцы данных, но данные, видимые в представлении, на самом деле являются результатами запроса. 13 Одной из операций над представлениями является их непосредственное использование с запросами модификации DML: INSERT, UPDATE и DELETE. Если к представлению могут быть успешно применены данные запросы, то оно называется модифицируемым (обновляемым). В противном случае представление является представлением только для чтения. Обновление представлений будет подробно рассмотрено после изучения языка манипулирования данными (см. разд. 5.6). В запросах SELECT, INSERT, DELETE и UPDATE на представление можно ссылаться, как на обычную таблицу. Это дает возможность определять подмножество данных, необходимых конкретному пользователю (группе пользователей), в дополнение к ограничению доступа к остальной части данных. Представления используются по нескольким причинам:  они позволяют сделать так, что разные пользователи БД будут видеть ее по-разному;  с их помощью можно ограничить доступ к данным, разрешая пользователям видеть только некоторые из строк и столбцов таблицы;  они упрощают доступ к БД, показывая каждому пользователю структуру хранимых данных в наиболее подходящей для него форме. Практически все реляционные СУБД поддерживают представления. Рассмотрим подробно создание представлений в СУБД Firebird, затем кратко остановимся на особенностях определения представлений в Oracle и MS SQL Server. В SQL представления создаются запросом CREATE VIEW. В Firebird запрос создания представления имеет следующий формат: CREATE VIEW имя_представления [( столбец1_представления [, столбец2_представления …])] AS <запрос_SELECT> [WITH CHECK OPTION]; Данный запрос создает представление с именем имя_представления. Запрос_SELECT представляет собой обычный запрос на выборку данных. Поэтому представление можно считать именованным запросом на выборку данных, хранящимся в БД. Параметр WITH CHECK OPTION предотвращает INSERT- или UPDATE- операции над обновляемым представлением, если они нарушают условие отбора строк, определенное в секции WHERE запроса SELECT (запрос_SELECT), используемого при определении данного представления. При необходимости в запросе CREATE VIEW можно задать имя для каждого столбца создаваемого представления, обозначаемое как столбец_представления. Если указывается список имен столбцов, то он должен соответствовать порядку и количеству столбцов, возвращаемых запросом. Задаются только имена столбцов. Тип данных, длина и другие характеристики берутся из определения столбца в исходной таблице. Если список имен столбцов в запросе CREATE VIEW отсутствует, то каждый 14 столбец представления получает имя соответствующего столбца запроса. Если в запрос входят вычисляемые столбцы или 2 столбца с одинаковыми именами, то использование списка имен столбцов является обязательным. Физически представление в БД хранится в виде его определения, т. е. текста того запроса CREATE VIEW, который был использован при создании представления. Когда СУБД встречает в SQL-запросе ссылку на представление, она отыскивает его определение, сохраненное в БД. Затем преобразует пользовательский запрос, ссылающийся на представление, в эквивалентный запрос к исходным таблицам представления (заданным в запросе SELECT представления) и выполняет этот запрос. Таким образом, СУБД создает иллюзию существования представления в виде отдельной таблицы и в то же время сохраняет целостность исходных данных. Например, для создания представления Sred_Summ со столбцами Month и Summa, показывающего среднее значение начислений за каждый месяц, следует выполнить запрос: CREATE VIEW Sred_Summ (Mes, Summa) AS SELECT NachislMonth, AVG (NachislSum) FROM NachislSumma GROUP BY 1; MES SUMMA Результат выполнения 1 120,29 запроса 2 150,14 SELECT * FROM Sred_Summ; 3 208,68 к представлению Sred_Summ приведен на рис. 4.5. 4 146,97 Пример создания 5 143,28 представления с именем 6 252,56 Date_Abonent, которое должно 7 246,24 показывать ФИО абонентов и 8 91,36 дату подачи ими ремонтных 9 167,71 заявок: 10 255,66 CREATE VIEW Date_Abonent 11 179,36 (Abonent_Name, Data) 12 44,23 AS SELECT Fio, IncomingDate FROM Рис. 4.5. Результат Abonent, Request запроса WHERE Abonent.AccountCD = к представлению Request. AccountCD; Sred_Summ В СУБД Firebird представления могут использовать все конструкции, допустимые для обычного запроса SELECT. Таким образом, возможно использование конструкций FIRST/SKIP, ROWS, UNION, ORDER BY. Например, для создания представления Max_Pay с столбцами AccountCD, Big_Sum и PayDate, показывающего 5 максимальных значений оплат, необходимо выполнить запрос: CREATE VIEW Max_Pay (AccountCD, Big_Sum, PayDate) AS SELECT FIRST 5 AccountCD, PaySum, PayDate 15 FROM PaySumma ORDER BY PaySum DESC; Результат выполнения запроса (рис. 4.6) SELECT * FROM Max_Pay; ACCOUNTCD BIG_SUM PAYDATE 015527 611,30 03.11.2013 015527 580,10 08.08.2012 115705 553,85 02.02.2012 136169 528,44 26.11.2013 443690 485,00 05.09.2011 Рис. 4.6. Результат запроса к представлению Max_Pay Представление может служить неким «окном» для просмотра данных. Любые изменения в исходных данных (в данных таблиц, на основе которых создано представление) будут автоматически и мгновенно отображаться в представлении, и наоборот, все изменения, вносимые в данные представления, будут автоматически вноситься в исходные данные и соответственно отображаться в представлении. По типу запроса, используемого представлением, различают следующие виды представлений:  горизонтальные;  вертикальные;  смешанные;  сгруппированные;  соединенные;  объединенные. Горизонтальное представление представляет собой горизонтальное подмножество строк одиночной таблицы и предназначено для ограничения доступа к строкам таблицы. Запрос в таком представлении выбирает все столбцы заданной таблицы, но ограничивает выбор строк указанием условия поиска в секции WHERE запроса SELECT. Например, для создания представления, показывающего все ремонтные заявки по неисправности с кодом, равным 1, следует выполнить запрос: CREATE VIEW Failure_Req AS SELECT * FROM Request WHERE FailureCD = 1; При выполнении запроса SELECT * FROM Failure_Req; из таблицы Request будут выбраны все ремонтные заявки с кодом неисправности газового оборудования, равным 1. Результат запроса представлен на рис. 4.7. 16 REQUE ACCOU EXECUT FAILUR INCOMIN EXECUTION EXECUTE STCD NTCD ORCD ECD GDATE DATE D 1 005488 1 1 17.12.2011 20.12.2011 True 2 115705 3 1 07.08.2011 12.08.2011 True 5 080270 4 1 31.12.2011 NULL False 9 136169 2 1 06.11.2011 08.11.2011 True Рис. 4.7. Результат выполнения запроса к представлению Failure_Req Вертикальное представление представляет собой вертикальное подмножество строк одиночной таблицы и предназначено для ограничения доступа к столбцам таблицы. Запрос в таком представлении выбирает из таблицы требуемые столбцы, а ограничение на выбор строк отсутствует. Например, если необходимо создать представление Abonent_Phone, которое должно содержать ФИО абонента и его телефыон, нужно выполнить запрос: CREATE VIEW Abonent_Phone (Abon_Fio, Abon_Phone) AS SELECT Fio, Phone FROM Abonent; В этом примере Abon_Fio и Abon_Phone – имена столбцов представления. Если не указывать обозначение имен в скобках после имени представления, то столбцы представления получат соответственно имена Fio и Phone. Запрос SELECT * FROM Abonent_Phone; даст результат, представленный на рис. 4.8. ABON_FIO Аксенов С.А. ABON_PHONE 556893 Мищенко Е.В. 769975 Конюхов В.С. 761699 Тулупова М.И. 214833 Свирина З.А. NULL Стародубцев Е.В. 683014 Шмаков С.В. NULL Маркова В.П. 683301 Денисова Е.К. 680305 Лукашина Р.М. 254417 Шубина Т. П. 257842 Тимошкина Н.Г. 321002 17 Рис. 4.8. Результат выполнения запроса к представлению Abonent_Phone Смешанное представление – это подмножество строк и столбцов одиночной таблицы. Оно является представлением, разделяющим исходную таблицу как в горизонтальном, так и в вертикальном направлениях. Пусть необходимо создать представление Nachisl_Service, отображающее номера лицевых счетов абонентов и начисленные им суммы за услугу с кодом, равным 3. Для решения этой задачи следует выполнить запрос: CREATE VIEW Nachisl_Service AS SELECT AccountCD, ServiceCD, NachislSum FROM NachislSumma WHERE ServiceCD = 3; Сгруппированное представление основано на запросе, содержащем секцию GROUP BY и, как следствие, использующем агрегатные функции. Оно выполняет ту же функцию, что и запросы с группировкой определенных столбцов. В них родственные строки данных объединяются в группы, и для каждой группы в НД создается одна строка, содержащая итоговые данные по этой группе. С помощью сгруппированного представления запрос с группировкой превращается в виртуальную таблицу, к которой в дальнейшем можно обращаться. В отличие от горизонтальных и вертикальных представлений каждой строке сгруппированного представления не соответствует какая-то одна строка исходной таблицы. Сгруппированное представление не является просто фильтром исходной таблицы. Оно в силу использования агрегатных функций отображает исходную таблицу в виде суммарной информации и требует от СУБД значительного объема вычислений. Например, если необходимо создать представление Abonent_All_Pay с столбцами AccountCD и All_Pay, показывающее общую сумму оплат для каждого абонента, то следует выполнить запрос: CREATE VIEW Abonent_All_Pay (AccountCD, All_Pay) AS SELECT AccountCD, Sum (PaySum) FROM PaySumma GROUP BY AccountCD; Результат выполнения запроса (рис. 4.9): SELECT * FROM Abonent_All_Pay; Соединенное представление – это подмножество строк и столбцов из нескольких таблиц. Задавая в определении представления, например, двух- или многотабличный запрос, можно создать 18 виртуальную таблицу, данные в которую считываются соответственно из двух или нескольких различных таблиц. После создания такого представления к нему можно обращаться с помощью однотабличного запроса. ACCOUNTCD ALL_PAY 005488 759,70 015527 1626,40 080047 528,48 080270 1840,60 080613 869,51 115705 1301,80 126112 656,00 136159 966,11 136160 550,00 136169 1384,47 443069 1106,24 443690 819,47 Рис. 4.9. Результат выполнения запроса к представлению Abonent_All_Pay Например, необходимо создать представление с именем Abonent_Executor, в котором будут содержаться ФИО абонентов и назначенных по их ремонтным заявкам исполнителей. Для решения данной задачи подойдет запрос CREATE VIEW Abonent_Executor (Abonent_Name, Executor_Name) AS SELECT A.Fio, E.Fio FROM Abonent A, Executor E, Request R WHERE R. AccountCD = A.AccountCD AND R.ExecutorCD = E. ExecutorCD; Результат выполнения запроса: SELECT FIRST 10 * FROM Abonent_Executor; представлен на рис. 4.10. ABONENT_NAME Аксенов С.А. Конюхов В.С. Лукашина Р.М. Шмаков С.В. Мищенко Е.В. Стародубцев Е.В. Шмаков С.В. Денисова Е.К. Мищенко Е.В. Мищенко Е.В. EXECUTOR_NAME Стародубцев Е.М. Стародубцев Е.М. Стародубцев Е.М. Стародубцев Е.М. Стародубцев Е.М. Стародубцев Е.М. Стародубцев Е.М. Булгаков Т.И. Булгаков Т.И. Шубин В.Г. 19 Рис. 4.10. Результат выполнения запроса к представлению Abonent_Executor Объединенное представление основано на запросах, объединенных оператором UNION, например CREATE VIEW Abon_Exec AS SELECT Fio AS AbonentFio FROM Abonent WHERE Fio LIKE 'Ш%' UNION SELECT Fio FROM Executor WHERE Fio LIKE 'Ш%'; Если представление не используется другими объектами БД, то его можно удалить запросом DROP VIEW, который имеет формат: DROP VIEW представление; Если требуется заново создать представление со старым именем, то в Firebird используется запрос RECREATE VIEW. Синтаксис этого запроса такой же, как и запроса CREATE VIEW. Если представление не существует перед использованием запроса, то его использование эквивалентно применению CREATE VIEW. Если представление уже существует, то запрос RECREATE VIEW пытается удалить его и создать полностью новый объект (не будет выполнено, если представление используется другим объектом). Например, заново создать горизонтальное представление Failure_Req так, чтобы оно содержало только погашенные заявки по неисправности с кодом, равным 1, можно с помощью запроса: RECREATE VIEW Failure_Req AS SELECT * FROM Request WHERE FailureCD = 1 AND Executed; Результат выполнения запроса (рис. 4.11): SELECT * FROM Failure_Req; REQUE ACCOU EXECUT FAILUR INCOMIN EXECUTI EXECUTED STCD NTCD ORCD ECD GDATE ONDATE 1 005488 1 1 17.12.2011 20.12.2011 True 2 115705 3 1 07.08.2011 12.08.2011 True 9 136169 2 1 06.11.2011 08.11.2011 True Рис. 4.11. Результат выполнения запроса к представлению Failure_Req В Firebird 2.5 введены запросы ALTER VIEW и CREATE OR ALTER VIEW соответственно для обновления и/или создания представления. Запрос ALTER VIEW предназначен для обновления определения представлений, а запрос CREATE OR ALTER VIEW – для обновления представления, если оно существует, или создания представления, если его нет. Синтаксис: CREATE [OR ALTER] | ALTER } VIEW имя_представления [( столбец1_представления [, столбец2_представления …])] AS <запрос_SELECT> [WITH CHECK OPTION]; 20 Примером создания и последующего представления могут быть запросы: CREATE VIEW Abonent_View (AccountCD, Fio) AS SELECT AccountCD, Fio FROM Abonent; изменения определения ALTER VIEW Abonent_View (AccountCD, Fio) AS SELECT AccountCD, Fio FROM Abonent WHERE AccountCD >= '200000' WITH CHECK OPTION; В СУБД Oracle представления создаются запросом CREATE VIEW следующего формата: CREATE [FORCE | NOFORSE] VIEW имя_представления [( столбец1_представления [, столбец2_представления …])] AS <запрос_SELECT> [WITH CHECK OPTION [CONSTRAINT имя_ограничения]] [WITH READ ONLY]; Опция FORCE позволяет создавать представление на основе ещё не существующей базовой таблицы. NOFORSE (значение по умолчанию) означает, что представление нельзя создать, если фигурирующая в нем таблица на текущий момент не существует. Аргумент имя_ограничения в запросе задает имя ограничения WITH CHECK OPTION. Опция WITH READ ONLY указывает, что представление позволяет только считывать строки (обновление, удаление или вставка строк не разрешается). Например, в Oracle создать представление Max_Pay, показывающее 5 максимальных значений оплат (рис. 4.6), можно с помощью запроса: CREATE VIEW Max_Pay (AccountCD, Big_Sum, PayDate) AS SELECT * FROM (SELECT AccountCD, PaySum, PayDate FROM PaySumma ORDER BY PaySum DESC) WHERE ROWNUM <=5 ORDER BY PAYSUM DESC; Запросы RECREATE VIEW и ALTER VIEW в Oracle не поддерживаются, для изменения определения представления служит запрос CREATE OR REPLACE VIEW. Запрос предназначен для обновления представления, если оно существует, или создания представления, если его нет, и имеет синтаксис: CREATE [OR REPLACE] VIEW имя_представления [( столбец1_представления [, столбец2_представления …])] AS <запрос_SELECT> [WITH CHECK OPTION] [CONSTRAINT имя_ограничения]] [WITH READ ONLY]; Помимо создания обычных представлений, Oracle, начиная с версии Oracle8i, предоставляет возможность создания материализованных представлений. Материализованное представление – это специальный вид представления, которое физически существует в БД. Для создания материализованного представления используется запрос CREATE MATERIALIZED VIEW. 21 В определении материализованного представления могут использоваться и таблицы, и представления. В определение могут быть включены функции агрегирования, одна или несколько объединенных таблиц и операция GROUP BY. Оно может быть индексировано и секционировано, к нему могут быть применены основные операции DDL типа CREATE, ALTER и DROP. Поскольку материализованное представление является объектом базы данных, во многих отношениях оно ведет себя как индекс, так как:  поставленная перед материализованным представлением задача состоит в том, чтобы увеличить производительность выполнения запроса;  существование материализованного представления прозрачно для прикладных SQL-запросов, и можно создавать или удалять материализованные представления, не затрагивая прикладного SQL;  материализованное представление занимает (дисковую) память и должно обновляться после каждого изменения основообразующих таблиц фактов. Материализованные представления создаются для улучшения времени выполнения запроса путем предварительного вычисления дорогостоящих соединений и операций агрегирования еще до их выполнения в реальном запросе. Подробнее с созданием материализованных представлений можно ознакомиться в [24, 46]. В СУБД MS SQL Server базовый синтаксис создания и изменения представлений аналогичен синтаксису, приведенному для Firebird. При этом запрос SELECT, используемый при определении представления, не может включать следующие элементы [37]:  секцию ORDER BY, если только в списке выбора запроса SELECT нет также конструкции TOP; 1. Примечание. Секция ORDER BY используется исключительно для определения строк, возвращаемых конструкциями TOP или OFFSET в определении представления, и не гарантирует упорядочивания результатов при запросе к представлению, если оно не указано в самом запросе.  ключевое слово INTO;  секцию OPTION;  ссылку на временную таблицу или табличную переменную. Перечислим преимущества использования представлений. Обеспечение логической независимости. Одна из основных задач, которую позволяют решать представления, – обеспечение логической независимости прикладных программ от изменений в структуре БД. При изменении структуры изменяются запросы в определениях соответствующих представлений. При этом никаких изменений в программы, работающие с такими представлениями, вносить не нужно. Прикладной взгляд на данные. Представления дают возможность пользователям по-разному видеть одни и те же данные. Это особенно ценно при работе различных категорий пользователей с единой интегрированной 22 БД. Пользователям предоставляются только интересующие их данные в наиболее удобной для них форме или формате. Защита данных. Представления дают дополнительный уровень защиты данных в таблицах. От определенных пользователей могут быть скрыты некоторые данные, невидимые через предложенное им представление. Скрытие сложности. Пользователь работает с представлением как с обычной таблицей, обращаясь к нему по имени, хотя на самом деле оно может представлять собой сложный запрос. Актуальность. Изменения в любой из таблиц БД, указанных в определяющем запросе, немедленно отображаются на содержимом представления. Однако имеются и недостатки использования представлений [28]. Снижение производительности. Представление – это виртуальная таблица, и, следовательно, при каждом обращении к нему происходит обработка запроса, затем возврат результата. Выполнение сложных вычислений или наличие множества соединений может приводить к снижению скорости работы. Структурные ограничения. Структура представления устанавливается в момент его создания. Поэтому после изменения определения столбцов исходной таблицы, на которые ссылается запрос в данном представлении, представление должно быть пересоздано. Ограниченные возможности обновления. В некоторых случаях представления не позволяют вносить изменения в данные, содержащиеся в таблицах (см. п. 5.6). 4.6. КОММЕНТАРИИ К ОБЪЕКТАМ БД Для сохранения в БД пояснений, относящихся к ней, ее базовым объектам, к столбцам таблиц и представлений, а также параметрам процедур, используются комментарии к объектам БД. Для создания такого комментария в Firebird используется запрос COMMENT ON, который имеет формат: COMMENT ON {DATABASE IS { 'текст' | NULL} | <базовый_объект> имя_объекта IS { 'текст' | NULL} | COLUMN {базовая_таблица | представление}. столбец IS { 'текст' | NULL} | PARAMETER имя_процедуры.имя_параметра IS { 'текст' | NULL} }, где <базовый_объект>:: = {DOMAIN | TABLE | VIEW | PROCEDURE | TRIGGER | EXCEPTION | GENERATOR | SEQUENCE | INDEX | ROLE};, 'текст' – пояснения к объекту БД. Указание пустой строки в качестве текста эквивалентно использованию NULL. В результате действия запроса COMMENT ON в системном каталоге появится комментарий к описанию объекта БД. Комментарий на саму БД хранится в столбце RDB$DESCRIPTION системной таблицы 23 RDB$DATABASE. Например, можно добавить комментарий к учебной БД с помощью запроса: COMMENT ON DATABASE IS 'Учебная БД Абонент'; Следующий запрос добавляет комментарий к домену PKField: COMMENT ON DOMAIN PKField IS 'Домен предназначен для определения первичных ключей таблиц'; Точно так же можно создать комментарии и для других объектов БД и просмотреть их, извлекая нужный столбец из системной таблицы с помощью запроса SELECT или открывая необходимую системную таблицу в IBExpert и закладку «Данные» в ней. Так же, открыв эту закладку, можно изменить созданный комментарий непосредственно в RDB$DESCRIPTION (при щелчке в области данных этого столбца) в выпадающем поле для ввода. Для подтверждения изменений следует нажать «OK» и . Чтобы изменить комментарий, можно просто ввести новый запрос COMMENT ON для того же объекта. Новый комментарий будет записан поверх старого. Если необходимо удалить комментарий, то следует записать поверх него пустой комментарий COMMENT ON ... IS ' '. В СУБД Oracle запрос для создания комментария имеет формат: COMMENT ON { TABLE имя_объекта IS { 'текст' | NULL} | COLUMN базовая_таблица. столбец IS { 'текст' | NULL}; Например, можно добавить комментарий к таблице с помощью запроса COMMENT ON TABLE Abonent IS 'Содержит персональные данные абонентов'; Чтобы отобразить комментарии на экране, необходимо выполнить запрос: SELECT TABLE_NAME, COMMENTS FROM user_Tab_comments WHERE table_name = 'ABONENT'; Также добавим комментарий к столбцу: COMMENT ON COLUMN Abonent.Fio IS 'Содержит фамилии и инициалы абонентов'; Просмотрим добавленный комментарий с помощью запроса SELECT * FROM user_col_comments WHERE table_name = 'ABONENT'; Также комментарии к столбцам таблиц можно просмотреть, открыв соответствующую таблицу в dbForge Studio и щелкнув вкладку «Данные». В MS SQL Server для создания комментариев к объектам БД не существует специального запроса, комментарии можно задать только через расширенные свойства (extended properties) объектов БД [37]. Расширенные свойства можно создать и настроить либо из графической утилиты для работы с БД, либо из кода Transact-SQL при помощи системных хранимых процедур sp_addextendedproperty, sp_updateextendedproperty, sp_dropextendedproperty. 24
«Индексы» 👇
Готовые курсовые работы и рефераты
Купить от 250 ₽
Решение задач от ИИ за 2 минуты
Решить задачу
Найди решение своей задачи среди 1 000 000 ответов
Найти
Найди решение своей задачи среди 1 000 000 ответов
Крупнейшая русскоязычная библиотека студенческих решенных задач

Тебе могут подойти лекции

Смотреть все 588 лекций
Все самое важное и интересное в Telegram

Все сервисы Справочника в твоем телефоне! Просто напиши Боту, что ты ищешь и он быстро найдет нужную статью, лекцию или пособие для тебя!

Перейти в Telegram Bot