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

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

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

MySQL I Решение 3.1.2.b (триггеры для таблицы subscriptions) (продолжение) |

51-- Создание триггера, реагирующего на обновление выдачи книг:

52CREATE TRIGGER 'upd_sbs_rdy_on_subscriptions_upd'

53AFTER UPDATE

54ON 'subscriptions'

55FOR EACH ROW

56BEGIN

57UPDATE 'subscriptions_ready'

58JOIN (SELECT 'sb_id',

59

 

 

' s_name' ,

 

60

 

 

'b_name'

 

 

61

 

FROM

'books'

 

 

62

 

 

JOIN

'subscriptions'

 

63

 

 

ON

'b_id' = 'sb_book'

 

64

 

 

JOIN

'subscribers'

 

65

 

 

ON

'sb_subscriber'

= 's_id'

66

 

WHERE

's_id' = NEW.'sb_subscriber'

 

67

 

AND

'b_id' = NEW.'sb_book'

 

68

 

AND 'sb_id' = NEW.'sb_id') AS 'new_data'

69

SET

'subscriptions_ready' 'sb_id' = NEW.'sb_id',

 

'subscriptions_ready' 'sb_subscriber' = 'new_data' 's_name',

71'subscriptions_ready' 'sb_book' = 'new_data' 'b_name',

72'subscriptions_ready' 'sb_start' = NEW.'sb_start',

73'subscriptions_ready' 'sb_finish' = NEW.'sb_finish',

74'subscriptions_ready' 'sb_is_active' = NEW.'sb_is_active'

75WHERE 'subscriptions_ready' 'sb_id' = OLD.'sb_id';

76END;

77$$

78

79-- Восстановление разделителя завершения запросов:

80DELIMITER ;

Код iNSERT-триггера (строки 12-39) очень похож на код аналогичного триггера на таблице books. Отличие состоит в том, что в данном случае мы знаем идентификаторы читателя и книги, и это избавляет нас от необходимости формировать полную выборку.

Код DELETE-триггера (строки 41-50) получаемся самым компактным: нам нужно просто удалить из таблицы subscriptions_ready записи, идентификаторы которых совпадают с идентификаторами записей, удаляемых из таблицы subscriptions.

Код UPDATE-триггера (строки 51-77) — самый нетривиальный. Сам по себе

синтаксис обновления на основе выборки выглядит непривычно (мы вынуждены объединять результаты выборки из обновляемой таблицы и выборки-источника — строки 57-68).

Условия в строках 66-67 позволяют сократить количество выбираемых рядов, а условие в строке 68 гарантирует, что мы получим данные о новой записи таблицы subscriptions, даже если у неё изменился первичный ключ. Следуя этой же логике, мы не указываем условие объединения ' subscriptions_ready' JOIN

... 'new_data', т.к. единственным здравым условием объединения здесь может быть совпадение значений sb_id, но если первичный ключ записи в таблице subscriptions поменялся, то такого совпадения не будет, т.к. в таблице subscriptions_ready всё ещё хранится старое значение первичного ключа обновляемой записи.

В строках 69-74 новые данные для обновления полей мы берём из двух источников: из явно переданных данных через ключевое слово NEW (все значения, которые мы можем получить напрямую) и из результатов выборки new_data (имя читателя и название книги, т.к. их нет и не может быть в явно переданных данных,

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

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

доступных через ключевое слово NEW).

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

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

Условие в строке 75 гарантирует, что мы обновим нужную запись: здесь необходимо сравнение идентификатора обновляемой записи именно с OLD .' sb_id', а не с NEW.' sb_id', т.к. у обновляемой записи в таблице subscriptions мог поменяться первичный ключ, и нам нужно найти его старое значение в таблице subscriptions_ready (благодаря выражению в строке 69 это значение тоже обновится, если оно изменилось).

Вся логика проверки работы таких триггеров подробно показана в решении{216} задачи 3.1.2.a{215}. Вы можете самостоятельно провести эксперимент, изменяя произвольным образом данные в таблице books, subscribers и subscriptions и отслеживая соответствующие изменения в таблице subscriptions_ready.

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

MS SQL і Решение 3.1.2.b

[

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

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

3DROP VIEW [subscriptions_ready]; 4

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

6CREATE VIEW [subscriptions_ready]

7WITH SCHEMABINDING

8AS

9SELECT [sb_id],

10[s_name] AS [sb_subscriber],

11[b_name] AS[sb_book]

12[sb_start],

13[sb_finish],

14[sb_is_active]

15FROM [dbo] [books]

16

JOIN

[dbo]

[subscriptions]

17

ON

[b_id]

= [sb_book]

18

JOIN

[dbo]

[subscribers]

19

ON [sb_subscriber] = [s_id]

 

20

 

 

 

 

21-- Создание уникального кластерного индекса на представлении.

22-- Именно эта операция "включает" автоматическое обновление

23-- представления при изменении данных в таблицах,

24-- на которых оно построено:

25CREATE UNIQUE CLUSTERED INDEX [idx_subscriptions_ready]

26ON [subscriptions ready] ( [sb id] ;

Чтобы данные в представлении subscriptions_ready обновлялись автоматически, его нужно сделать индексированным, т.е. создать на нём уникальный кластерный индекс (строки 25-26).

Необходимым условием создания такого индекса на представлении является привязка представления к схеме базы данных (строка 7), указывающая СУБД на необходимость установить и отслеживать соответствие между использованием в коде представления объектов базы данных и реальным состоянием таких объектов (их существованием, доступностью и т.д.) не только в момент создания представления, но и в момент любой модификации объектов базы данных, на которые ссылается представление.

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

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

Решение данной задачи для Oracle ещё проще: берётся запрос на выборку, позволяющий получить желаемые данные, и используется как тело материализованного представления. СУБД будет автоматически обновлять данные в этом представлении раз в минуту (логика такого поведения и остальные особенности создания материализованных представлений в Oracle была рассмотрена в решении{216} задачи 3.1.2. a{215}.).

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

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

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

3DROP MATERIALIZED VIEW "subscriptions_ready" 4

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

6CREATE MATERIALIZED VIEW "subscriptions_ready"

7BUILD IMMEDIATE

8REFRESH FORCE

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

10AS

11SELECT "sb_id",

12"s_name" AS "sb_subscriber"

13"b_name" AS "sb_book",

14"sb_start",

15"sb_fini sh",

16"sb_i s_active"

17FROM "books"

18

JOIN

"subscriptions"

 

19

ON "b_id" = "sb_book"

 

20

JOIN

"subscribers"

 

21

ON

"sb subscriber"

= "s id";

Задание 3.1.2.TSK.A: проверить корректность обновления кэширующей таблицы и представлений из решения задачи 3.1.2.b{215}.

Задание 3.1.2.TSK.B: создать кэширующее представление, позволяющее получать список всех книг и их жанров (две колонки: первая — название книги, вторая — жанры книги, перечисленные через запятую).

Задание 3.1.2.TSK.C: создать кэширующее представление, позволяющее получать список всех авторов и их книг (две колонки: первая — имя автора, вторая — написанные автором книги, перечисленные через запятую).

Задание 3.1.2.TSK.D: доработать решение{246} задачи 3.1.2.a{215} для MySQL таким образом, чтобы оно учитывало изменения в таблице sub-

scriptions, вызванные операцией каскадного удаления (при удалении читателей). Убедиться, что решения для MS SQL Server и Oracle не тре-

буют такой доработки.

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

Пример 28: использование представлений для сокрытия значений и структур данных

3.1.3.Пример 28: использование представлений для сокрытия значений и структур данных

Задача 3.1.3.a{242}: создать представление, через которое невозможно получить информацию о том, какой конкретно читатель взял ту или иную книгу.

Задача 3.1.3.b{243}: создать представление, возвращающее всю информацию из таблицы subscriptions, преобразуя даты из полей sb_start и sb_finish в формат UNIXTIME.

Ожидаемый результат 3.1.3.a.

Выполнение запроса вида SELECT * FROM {представление}

позволяет получить результат следующего вида:

sb_id

sb_book

sb_start

sb_finish

sb_is_active

2

1

2011-01-12

2011-02-12

N

3

3

2012-05-17

2012-07-17

Y

42

2

2012-06-11

2012-08-11

N

57

5

2012-06-11

2012-08-11

N

61

7

2014-08-03

2014-10-03

N

62

5

2014-08-03

2014-10-03

Y

86

1

2014-08-03

2014-09-03

Y

91

1

2015-10-07

2015-03-07

Y

95

4

2015-10-07

2015-11-07

N

99

4

2015-10-08

2025-11-08

Y

100

3

2011-01-12

2011-02-12

N

Ожидаемый результат 3.1.3.b.

Выполнение запроса вида SELECT * FROM {представление} позволяет получить результат следующего вида:

sb_id

sb_subscriber

sb_book

sb_start

sb_finish

sb_is_active

2

1

1

1294779600

1297458000

N

3

3

3

1337202000

1342472400

Y

42

1

2

1339362000

1344632400

N

57

4

5

1339362000

1344632400

N

61

1

7

1407013200

1412283600

N

62

3

5

1407013200

1412283600

Y

86

3

1

1407013200

1409691600

Y

91

4

1

1444165200

1425675600

Y

95

1

4

1444165200

1446843600

N

99

4

4

1444251600

1762549200

Y

100

1

3

1294779600

1297458000

N

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

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