(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Об Oracle Database 12c. Часть 1

Том Кайт

Наш эксперт положительно отзывается о значениях по умолчанию, описывает типы больших данных и выбирает (FETCH) их с первого раза.

Обычно я беру три-четыре пользовательских запроса за последние пару месяцев и в своей колонке Ask Tom представляю эти запросы и ответы на них. Однако в ближайших же четырех колонках я буду рассматривать некоторые ключевые возможности в Oracle Database 12  c  . Эти возможности были перечислены в презентации "12 вещей о Oracle Database 12  c " , которую я представил на Oracle OpenWorld 2012 в Сан-Франциско. (Вы можете найти слайды этой презентации на сайте asktom.oracle.com на вкладке Files). Для начала я расскажу о первых трех особенностях Oracle Database 12 c :

  • Усовершенствованное умолчание (Improved defaults);
  • Расширение типов данных (Bigger datatypes);
  • Первые n запросов (Top-n queries)

Усовершенствованное умолчание
(Improved Defaults)

Возможность создания значения столбца по умолчанию существует в SQL уже значительное время. Эта функциональность, однако, была несколько ограничена. Например, были ограничения в использовании объектов SEQUENCE для задания значений по умолчанию. Кроме того, если значение по умолчанию должно было быть вставлено или изменено во всей таблице, нужно было либо использовать ключевое слово DEFAULT в SQL-предложении или полностью исключить этот столбец из предложения INSERT. При этом добавлялся новый столбец, допускавший NULL-значения по умолчанию, был в автономном режиме. В Oracle Database 12  c  эти предельные и функциональные ограничения сняты.

Отменено ограничение: Генерирование значения по умолчанию из SEQUENCE.

В Oracle Database 12  c , теперь можно использовать атрибут последовательности .NEXTVAL для создания значения столбца по умолчанию. Например:

SQL> create sequence s; Sequence created. SQL> create table t 2 ( x int 3 default s.nextval 4 primary key, 5 y varchar2(30) 6 ); Table created. SQL> insert into t (x,y) 2 values ( default, 'hello' ); 1 row created. SQL> insert into t (y) 2 values ( 'world' ); 1 row created. SQL> select * from t; X Y -------- -------- 1 hello 2 world 

этот код показывает, что можно создать значение по умолчанию для столбца первичного ключа, использую значение последовательности и без использования триггера, как было в прошлом. Таким образом, в Oracle Database 12  c , фраза S.NEXTVAL DEFAULT в предложении CREATE TABLE, заменит следующий процедурный код:

SQL> create trigger t 2 before insert on t 3 for each row 4 begin 5 if (:new.x is null) 6 then 7 :new.x := s.nextval; 8 end if; 9 end; 10 / Trigger created. 

В дополнение к использованию ссылки на последовательность для создания значения по умолчанию столбца, альтернативно можно использовать фразу IDENTITY, которая формирует последовательность и связывает эту последовательность с таблицей. Например, это предложение CREATE TABLE:

SQL> create table t 2 ( x int 3 generated as identity 4 primary key, 5 y varchar2(30) 6 ) 7 / Table created. 

Это приведет к тем же данным при загрузке в таблицу T без явного создания последовательности (как вы это сделали бы в предложении CREATE TABLE, в которой явно прописывается DEFAULT S.NEXTVAL). Можно увидеть эту последовательность, если посмотреть на перечень схемных объектов:

SQL> select object_name, object_type 2 from user_objects 3 / OBJECT_NAME OBJECT_TYPE ------------------ ------------- T TABLE ISEQ$$_90241 SEQUENCE SYS_C0010233 INDEX

Но учтите, что если таблицу удалить и вычистить (purge) ее из корзины, то последовательность также будет удалена:

SQL> drop table t purge; Table dropped. SQL> select object_name, object_type 2 from user_objects 3 / no rows selected 

Поскольку сохраняется identity (идентификатор) имеющейся последовательности, можно управлять всеми настройками базовой последовательности. Например, такое предложение CREATE TABLE:

SQL> create table t 2 ( x int 3 generated by default 4 as identity 5 ( start with 42 6 increment by 1000 ) 7 primary key, 8 y varchar2(30) 9 ) 10 / Table created. 

показывает, что можно управлять значениями START WITH и INCREMENT BY. Кроме этого, вместо простого GENERATED, предложением GENERATED BY DEFAULT можно переопределить identity value (значение идентификатора) по умолчанию идентичности. Ниже я это продемонстрирую, вставив значение 1, а потом еще две строки, что позволит сгенерировать идентификаторы как значения по умолчанию:

SQL> insert into t (x,y) 2 values ( 1, 'override' ); 1 row created. SQL> insert into t (x,y) 2 values ( default, 'hello' ); 1 row created. SQL> insert into t (y) 2 values ( 'world' ); 1 row created. SQL> select * from t; X Y ---------- ----------- 1 override 42 hello 1042 world

Улучшенная функциональность: Cоздание значения по умолчанию для NULL-столбца.

В Oracle Database 12  c  теперь можно создавать значение столбца по умолчанию не только при использовании ключевого слова DEFAULT или полностью исключить столбец из предложения INSERT, но и тогда, когда вы явно задаете при установке значение столбца NULL.

В прошлом, если столбец содержал значение по умолчанию, нужно было или использовать ключевое слово DEFAULT в предложениях INSERT/UPDATE или полностью исключить столбец из предложений INSERT/UPDATE. Это означало, что для использования значения по умолчанию в определенные, но не другие, моменты времени, нужно было выполнить, по крайней мере, два предложения INSERT/UPDATE с трудными для понимания конструкциями if/then/else. Например, если столбец X содержал значение по умолчанию, и вы иногда требовалось вставить в него другое значение, а иногда этого делать было не надо, то требовался код, похожий на этот:

if (x is_to_be_defaulted) then insert into t (x, … ) values ( DEFAULT, … ); else insert into t (x, … ) values ( :x, … ); end if;

Конечно, это было может быть вполне терпимо, если значение по умолчанию нужно было создавать для одного столбца, но если у вас таких столбцов было два, три или более? Подумайте, сколько комбинаций INSERTs и UPDATEs вам нужно было бы провести со сложными блоками if/then/else, чтобы обеспечить такую возможность. Теперь в Oracle Database 12  c  можно задавать Значение столбца по умолчанию, когда в нем явно задано значение NULL. Вот пример:

SQL> create table t 2 ( x number 3 generated as identity 4 primary key, 5 y varchar2(30), 6 z number default ON NULL 42 7 ) 8 / Table created.Используя фразу  z number default ON NULL 42 , я определяю, что столбец Z получает значение по умолчанию не только, если я явно устанавливаю для него DEFAULT или исключаю его из предложения INSERT, но и тогда, когда я его явно заявляю NULL, как в данном примере: SQL> insert into t (y) 2 values ( 'just y' ); 1 row created. SQL> insert into t (y,z) 2 values ( 'y with z set to null', null ); 1 row created. SQL> insert into t (y,z) 2 values ( 'y and z', 100 ); 1 row created. SQL> select * from t; X Y Z ---- ---------------------- ---- 1 just y 42 2 y with z set to null 42 3 y and z 100

Как можно видеть, столбец Z теперь в обоих случаях создается со значением по умолчанию 42. Кроме того, при декларировании Z был определен как NOT NULL, хотя я прямо не сказал:

SQL> select column_name, nullable 2 from user_tab_columns 3 where table_name = 'T' 4 order by column_id 5 / COLUMN_NAME N ----------- - X N Y Y Z N

Дальнейшие оперативные операции: Улучшение добавления столбца

В Oracle Database 11g  можно было быстро добавить столбец в таблицу, если он обладал значением по умолчанию и был определен как NOT NULL. (Arup Нанда написал об этом в bit.ly/16tQNCh.) Тем не менее, если вы попытаетесь добавить столбец со значением по умолчанию, и этот столбец допускает null-значения, операция ADD COLUMN может занять значительное количество времени, сгенерировать большое количество undo- и redo- записей, а также заблокировать всю таблицу на время всей операции. В Oracle Database 12  c  это время, объем и блокировка больше не являются составляющими подобного процесса.

Чтобы продемонстрировать это, я копирую представление ALL_OBJECTS в таблицу и измеряю ее пространство (в блоках и байтах), применяя утилиту show_space, находящуюся на сайте asktom.oracle.com:

SQL> create table t 2 as 3 select * 4 from all_objects; Table created. SQL> exec show_space('T') … Full Blocks .... 1,437 Total Blocks........... 1,536 Total Bytes............ 12,582,912 Total MBytes........... 12 … PL/SQL procedure successfully completed

Теперь я добавляю столбец к таблице T, и этот столбец будет содержать большое значение по умолчанию. Так как я добавил столбец CHAR (2000), он всегда будет занимать все 2,000 байтов, поскольку данные типа CHAR всегда фиксированной ширины, при необходимости дополнены пробелами. Таблица T имеет более чем 87,000 записей, так что добавление столбца, разумеется, должно было бы занять значительное количество времени, но как вы увидите, в Oracle Database 12c  это добавление совершается практически мгновенно:

SQL> set timing on SQL> alter table t add (data char(2000) default 'x'); Table altered. Elapsed: 00:00:00.07

Я выполнил идентичную операцию в Oracle Database 11  g  и наблюдал следующие данные:

SQL> set timing on SQL> alter table t add (data char(2000) default 'x'); Table altered. Elapsed: 00:00:28.59

Понятно, что эта значительная разница - время автономной работы. Далее, если я посмотрю на размер таблицы с дополнительным столбцом в Oracle Database 12  c :

SQL> exec show_space('T') … Full Blocks .... 1,437 Total Blocks........... 1,536 Total Bytes............ 12,582,912 Total MBytes........... 12 … PL/SQL procedure successfully completed.

Я увижу, что таблица вообще не разрослась. Однако под управлением Oracle Database 11  g  это же испытание показывает, что таблица разрастается приблизительно от 9 Мб до 192 Мб. Кроме того, в Oracle Database 11  g , почти каждая строка в таблице мигрировала, потому что размер строк существенно изменился. В предыдущих версиях такую таблицу, скорее всего, надо было бы реорганизовать, но не в Oracle Database 12  c .

Расширение типов данных (Bigger Datatypes)

База данных Oracle 8 принесла с собой значительное увеличение размера данных типа VARCHAR - от 255 байт (в Oracle7) до 4000 байт. Теперь версия Oracle Database 12c  увеличивает размер с 4,000 байт до 32К для строковых типов SQL-данных - VARCHAR2, NVARCHAR2 и RAW в соответствии с их PL/SQL-эквивалентами.

По умолчанию, автоматически эта новая возможность не включена, администратор базы данных должен прописать в файле init.ora новый параметр MAX_STRING_SIZE с значением EXTENDED. Как только это сделано, можно выполнять такие предложения, как:

SQL> create table t ( x varchar(32767) ); Table created.

а затем использовать строчные функции, такие как RPAD, LPAD и TRIM:

SQL> insert into t values ( rpad('*',32000,'*') ); 1 row created. SQL> select length(x) from t; LENGTH(X) -------------- 32000

В прошлой версии функции RPAD и в других встроенных строчных функциях можно было бы вернуть лишь 4000 байт, но теперь эти функции возвращают до 32К байтов типа VARCHAR2.

За кулисами Oracle Database 12  c  при использовании больших объектов (LOB) хранятся большие строки и данные raw (сырых) типов. Если вставляемая строка занимает до 4000 байт, база данных будет хранить эти данные в блоке таблицы базы так же, как это происходило с данными унаследованного типа VARCHAR2. Если строка превышает 4,000 байт, база данных прозрачно сохранит ее вне линии в LOB-сегменте и индексе.

Топ-N запросов и разбивка (Top-N Queries and Pagination)

Из многих тысяч вопросов на Ask Tom (asktom.oracle.com), наиболее популярными являются: "Как я могу получить N строк из всех M строк результирующего набора" (Как разбить набор результатов на страницы) и "Как я могу получить первые N записей результирующего набора." На самом деле я написал несколько статей в журнале Oracle на протяжении многих лет, чтобы ответить на эти вопросы ("On Top-N On Top-n and Pagination Queries" и "On ROWNUM and Limiting Results"). Эти статьи демонстрировали, как выполнить эти подвиги, но рассказанные методы были громоздки, неинтуитивны и не всегда портативны.

Oracle Database 12  c  включает в себя поддержку положений ANSI-стандарта FETCH FIRST/NEXT и OFFSET - вместе они называются фразами ограничения записей. Такая фраза легко позволит вам получить первые N записей из результирующего набора или, в качестве альтернативы, первые N записей после пропуска (сдвига на) в наборе записей, что позволяет легко нумеровать страницы набора результатов. На диаграмме на рисунке 1 показан синтаксис фразы ограничения количества записей.

Рисунок 1: Синтаксис фразы ограничения количества записей

Такая фраза ограничения просто добавляется в конце любого SQL SELECT-предложения, чтобы выбрать (fetch) определенное количество записей, и нет необходимости в нескольких уровнях внутренних представлений и фразах WHERE, которые должны быть тщательно позиционированы, как случилось бы с ROWNUM и ROW_NUMBER ().

Например, если у меня есть таблица T:

SQL> create table t 2 as 3 select * from all_objects; Table created. SQL> create index t_idx on t(owner,object_name); Index created.

и я хочу получить первые пять строк после сортировки по OWNER (владелец) и OBJECT_NAME (имя_объекта), нужно только добавить FETCH FIRST N ROWS в запросе SQL, показанном на листинге 1.

Листинг 1: Простой запрос на выборку SELECT, использующий FETCH FIRST

SQL> select owner, object_name, object_id 2 from t 3 order by owner, object_name 4 FETCH FIRST 5 ROWS ONLY; … ------------------------------------------------------------------------------ / Id /Operation / Name/Rows /Bytes /Cost (%CPU)/Time / ------------------------------------------------------------------------------ / 0/SELECT STATEMENT / / 5 / 1450 / 7 (0)/00:00:01/ /* 1/ VIEW / / 5 / 1450 / 7 (0)/00:00:01/ /* 2/ WINDOW NOSORT STOPKEY / / 5 / 180 / 7 (0)/00:00:01/ / 3/ TABLE ACCESS BY INDEX ROWID/T /87310 / 3069K/ 7 (0)/00:00:01/ / 4/ INDEX FULL SCAN /T_IDX/ 5 / / 3 (0)/00:00:01/ ------------------------------------------------------------------------------ Predicate Information (identified by operation id): ----------------------------------------------------------------- 1 - filter("from$_subquery$_003"."rowlimit_$$_rownumber"<=5) 2 - filter(ROW_NUMBER() OVER ( ORDER BY "OWNER","OBJECT_NAME")<=5)

Как можно видеть из информационного предиката в листинге 1, фраза ограничения строки ROW_NUMBER () прозрачно внутри переписывает запрос для использования аналитики. Фраза ограничения строки, короче говоря, делает это намного легче, чем это вы вручную делали в прошлом.

Для нумерации страниц в результирующем наборе - получение разом N строк с конкретной страницы из набора результата - я добавляю фразу OFFSET. В листинге 2 я пропускаю первые пять строк и получаю следующие пять строк из результирующего набора.

Листинг 2: Простой запрос SELECT с OFFSET FETCH

SQL> select owner, object_name, object_id 2 from t 3 order by owner, object_name 4 OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY; … ----------------------------------------------------------------------------- / Id /Operation /Name /Rows /Bytes /Cost (%CPU)/Time / ----------------------------------------------------------------------------- / 0/SELECT STATEMENT / / 5/ 1450 / 7 (0)/00:00:01/ /* 1/ VIEW / / 5/ 1450 / 7 (0)/00:00:01/ /* 2/ WINDOW NOSORT STOPKEY / / 5/ 180 / 7 (0)/00:00:01/ / 3/ TABLE ACCESS BY INDEX ROWID/T /87310/ 3069K/ 7 (0)/00:00:01/ / 4/ INDEX FULL SCAN /T_IDX/ 5/ / 3 (0)/00:00:01/ ----------------------------------------------------------------------------- Predicate Information (identified by operation id): ----------------------------------------------------------------------- 1 - filter("from$_subquery$_003"."rowlimit_$$_rownumber"<=CASE WHEN (5>=0) THEN 5 ELSE 0 END +5 AND "from$_subquery$_003"."rowlimit_$$_rownumber">5) 2 - filter(ROW_NUMBER() OVER ( ORDER BY "OWNER","OBJECT_NAME")<=CASE WHEN (5>=0) THEN 5 ELSE 0 END +5)

Как видно на листинге 2, база данных скрытно переписывает этот запрос для использования встроенных представлений и аналитики, снова автоматически, вместо бывших ранее малопонятных и сложных построений.

Отметим, что в реальной жизни вы должны использовать переменные связывания, а не жестко заданные константы, поэтому вместо числа 5, как я сделал, нужно было бы применить связываемую переменную 5.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 08.09.2014 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Oracle Database Standard Edition 2 Named User Plus License
Oracle Database Standard Edition 2 Processor License
Oracle Database Personal Edition Named User Plus Software Update License & Support
Oracle Database Personal Edition Named User Plus License
ABBYY FineReader Pro для Mac, электронный ключ
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
СУБД Oracle "с нуля"
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100