Материал: Using_MySql,_MS_SQL_Server_and_Oracle

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Пример 27: выборка данных с использованием кэширующих представлений и таблиц

Удалим информацию о выдаче с идентификатором 62 (книга по этой выдаче ещё не возвращена):

 

MS SQL

Решение 3.1.2.а (проверка реакции на удаление выдачи с не возвращённой книгой)

 

1..........

DELETE .............................................

 

FROM

 

[Subscriptions]............................................

 

 

2

WHERE [sb id] = 62

 

 

 

 

 

 

 

 

total

given

rest

 

Было

51

5

46

 

Стало

51

4

47

 

Наконец, удалим все книги (что также приведёт к каскадному удалению всех выдач):

 

MS SQL

 

 

Решение 3.1.2.a (проверка реакции на удаление всех книг)

|

 

1

DELETE

FROM [books]

 

 

 

 

 

 

 

 

 

 

 

 

 

total

 

given

rest

 

 

 

Было

51

 

4

47

 

 

 

Стало

0

 

0

0

 

 

Итак, все операции модификации данных в таблицах books и subscriptions вызывают соответствующие изменения в агрегирующей таблице books_statistics, которая в MS SQL Server выступает в роли кэширующего представления.

Переходим к решению для Oracle.

Oracle — единственная СУБД, в которой данная задача полноценно решается с использованием материализованных представлений. Если бы мы использовали более новую или коммерческую версию Oracle, мы могли бы реализовать самый элегантный вариант — REFRESH FAST ON COMMIT, указывающий СУБД опти-

мальным образом обновлять данные в материализованном представлении каждый раз, когда завершается очередная транзакция, затрагивающая таблицы, из которых собираются данные. Но в Oracle 11gR2 Express Edition эта опция нам недоступна, и

вместо неё мы используем REFRESH FORCE START WITH (SYSDATE) NEXT

(SYSDATE + 1/1440), т.е. будем принудительно обновлять данные в представлении раз в минуту.

Oracle і Решение 3.1.2.a [

1-- Удаление старой версии материализованного представления

2-- (удобно при разработке и отладке):

3DROP MATERIALIZED VIEW "books_statistics" 4

5-- Создание материализованного представления:

6CREATE MATERIALIZED VIEW "books_statistics"

7BUILD IMMEDIATE

8REFRESH FORCE

9START WITH (SYSDATE) NEXT (SYSDATE + 1/1440)

10AS

11SELECT "total",

12"given",

13"total" - "given" AS "rest"

14

FROM

(SELECT SUM("b_quantity") AS "total"

15FROM "books")

16JOIN (SELECT COUNT("sb_book") AS "given"

17

FROM

"subscriptions"

18

WHERE

"sb_is_active" = 'Y')

19

ON 1 = 1

 

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 240/545

Пример 27: выборка данных с использованием кэширующих представлений и таблиц

Выражение BUILD IMMEDIATE в строке 7 предписывает СУБД немедленно инициализировать материализованное представление данными.

Выражения в строках 8-9 описывают способ обновления данных в материализованном представлении (REFRESH FORCE — СУБД сама выбирает оптимальный способ из доступных — либо быстрое обновление, либо полное) и периодичность этой операции (START WITH (SYSDATE) NEXT (SYSDATE + 1/1440) — начать

немедленно и повторять каждую 1/1440-ю часть суток, т.е. каждую минуту).

Запрос в строках 11-19 по здравому смыслу должен быть идентичен запросам, которые мы использовали в MySQL и MS SQL Server для инициализации данных в агрегирующей таблице. Но Oracle не позволяет в материализованных представлениях использовать запросы с подзапросами в секции FROM, а вот объединять

данные из двух подзапросов позволяет.

Поэтому мы сформировали два подзапроса (вычисляющий общее количество книг — строки 14-15 и вычисляющий количество выданных читателям книг — строки 16-18), а затем объединили их результаты (каждый подзапрос возвращает просто по одному числу) с применением гарантированно выполняющегося условия

1 = 1.

 

Результат работы SQL-кода в строках 14-15 таков:

total given

зз 15

~

Остаётся только выбрать из него значения полей "total" и "given" и вычислить на их основе значение поля "rest", что и происходит в строках 11-13.

Снова (как и в случае с MySQL и MS SQL Server) проверим, как работает то, что мы создали. Будем модифицировать данные в таблицах books и subscriptions и выбирать данные из материализованного представления books_statistics. Обратите внимание, что после каждого запроса явно выполняется подтверждение транзакции (COMMIT), чтобы исключить ситуацию, в которой Oracle будет

ждать этого события и не обновит материализованное представление. Добавим две книги с количеством экземпляров 5 и 10:

Oracle Решение 3.1.2.a (проверка реакции на добавление книг)

1INSERT ALL

2INTO "books" ("b name",

3

"b_quantity",

4

"b_year")

5

VALUES (К'Новая книга 1',

6

5,

7

2001)

8

INTO "books" ("b name",

9

"b_quantity",

10

"b_year")

11

VALUES Щ'Новая книга 2',

12

10

13

2002)

14SELECT 1 FROM "DUAL";

15COMMIT; -- И подождать минуту.

 

total

given

rest

Было

33

5

28

Стало

48

5

43

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 241/545

Пример 27: выборка данных с использованием кэширующих представлений и таблиц

Увеличим на пять единиц количество экземпляров книги, которой сейчас в библиотеке зарегистрировано 10 экземпляров (такая книга у нас одна):

 

Oracle

 

Решение 3.1.2.a

 

на изменение количества

 

1

UPDATE "books"

 

 

 

2

SET

"b_quantity" = "b_quantity" + 5

 

3

WHERE

"b_quantity" = 10;

 

4

COMMIT

-- И подождать минуту.

 

 

 

 

 

 

 

 

 

 

 

total

 

given

rest

 

Было

 

48

 

5

43

 

Стало

 

53

 

5

48

 

Удалим книгу, оба экземпляра которой сейчас находится на руках у читателей (книга с идентификатором 1).

Oracle

Решение 3.1.2.а (проверка реакции на удаление книги)

1

DELETE FROM "books"

2WHERE "b_id" = 1

3COMMIT; -- И подождать минуту.

 

total

given

rest

Было

53

5

48

Стало

51

3

48

Отметим, что по выдаче с идентификатором 3 книга возвращена:

 

Oracle

 

 

Решение 3.1.2.a

 

на

1

UPDATE "subscriptions"

 

 

2

SET

 

"sb_is_active" = 'N'

3

WHERE

"sb_id" = 3;

 

 

4

COMMIT -- И подождать

минуту

 

 

 

 

 

 

 

 

 

total

given

rest

 

 

Было

51

 

3

48

 

 

Стало

51

 

2

49

 

 

Отменим эту операцию (снова отметим книгу как невозвращённую):

 

Oracle

 

Решение 3.1.2.a

 

на

1

UPDATE "subscriptions"

 

 

2

SET

 

"sb_is_active" = 'Y'

3

WHERE

"sb_id" = 3;

 

 

4

COMMIT -- И подождать

минуту

 

 

 

 

 

 

 

 

 

total

given

rest

 

 

Было

51

 

2

49

 

 

Стало

51

 

3

48

 

 

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 242/545

Пример 27: выборка данных с использованием кэширующих представлений и таблиц

 

Добавим в базу данных информацию о том, что читатель с

идентификатором 2 взял в библиотеке книги с идентификаторами 5 и 6:

Oracl

і

Решение 3.1.2.a (проверка реакции на выдачу книг)

|

e

 

 

 

1

INSERT ALL

 

 

2

INTO "subscriptions" ("sb subscriber"

 

3

 

"sb book",

 

4

 

"sb start"

 

5

 

"sb finish"

 

6

 

"sb is active"

 

7

 

VALUES (2,

 

8

 

5,

 

9

 

TO DATE '2016-01-10', 'YYYY-MM-DD'),

10

 

TO DATE '2016-02-10', 'YYYY-MM-DD'),

11

 

'Y')

 

12

INTO "subscriptions" ("sb subscriber"

 

13

 

"sb book",

 

14

 

"sb start",

 

15

 

"sb finish"

 

16

 

"sb is active"

 

17

 

VALUES (2,

 

18

 

6,

 

19

 

TO DATE '2016-01-10', 'YYYY-MM-DD'),

20

 

TO DATE '2016-02-10', 'YYYY-MM-DD'),

21

 

'Y')

 

22

SELECT 1 FROM "DUAL";

 

23

COMMIT; -- И подождать минуту.

 

 

total

given

rest

Было

51

3

48

Стало

51

5

46

Удалим информацию о выдаче с идентификатором 42 (книга по этой выдаче уже возвращена):

Oracle

Решение 3.1.2.а (проверка реакции на удаление выдачи с возвращённой книгой)

1 DELETE FROM "subscriptions"

2WHERE "sb_id" = 42

3COMMIT; -- И подождать минуту.

 

total

given

rest

Было

51

5

46

Стало

51

5

46

Удалим информацию о выдаче с идентификатором 62 (книга по этой выдаче ещё не возвращена):

Oracle Решение 3.1.2.а (проверка реакции на удаление выдачи с не возвращённой книгой)

1 DELETE FROM "subscriptions"

2WHERE "sb_id" = 62

3COMMIT; -- И подождать минуту.

 

total

given

rest

Было

51

5

46

Стало

51

4

47

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 243/545

Пример 27: выборка данных с использованием кэширующих представлений и таблиц

Наконец, удалим все книги (что также приведёт к каскадному удалению всех выдач):

Oracle

Решение 3.1.2.a

на

всех

1DELETE FROM "books";

2COMMIT; -- И подождать минуту.

 

total

given

rest

Было

51

4

47

Стало

0

0

0

Итак, все операции модификации данных в таблицах books и subscriptions вызывают соответствующие изменения в материализованном представле-

нии books statistics.

^W15, Решение 3.1.2.b{215}.

Если вы пропустили решение{216} задачи 3.1.2.a{215}, настоятельно рекомендуется ознакомиться с ним перед тем, как продолжить чтение, т.к. многие неочевидные моменты, которые встретят в данном решении, были рассмотрены ранее.

По сравнению с предыдущей задачей{215} здесь всё будет намного проще, т.к. запрос, формирующий необходимый набор данных, не содержит выражений, подпадающих под ограничения индексированных представлений MS SQL Server и материализованных представлений Oracle.

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

Создадим кэширующую таблицу (именно кэширующую, а не агрегирующую, как в задаче 3.1.2.a{215}, т.к. здесь мы ничего не агрегируем, а лишь сохраняем готовый результат). Код её создания можно почти полностью взять из кода создания таблицы subscritions, а для полей sb_subscriber и sb_book взять их определения из таблицы subscribers и books.

1CREATE TABLE 'subscriptions_ready'

2(

'sb_id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT

4'sb_subscriber' VARCHAR(150) NOT NULL,

5'sb_book' VARCHAR(150) NOT NULL,

6'sb_start' DATE NOT NULL,

7'sb_finish' DATE NOT NULL,

8'sb_is_active' ENUM ('Y', 'N') NOT NULL,

9CONSTRAINT 'PK_subscriptions' PRIMARY KEY ('sb_id')

10)

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 244/545

Источник: https://studfile.net/preview/16420333/