Программирование >>  Oracle 

1 ... 243 244 245 [ 246 ] 247 248 249 ... 469


1148 Глава 14

Если ключ фрагментации не входит в условие, обеспечить уникальность нельзя по двум причинам. Во-первых, если бы сервер Oracle это разрешал, то были бы сведены на нет преимущества фрагментации. Доступность и масштабируемость были бы потеряны, поскольку требовался бы просмотр всех фрагментов и доступ к ним при любой вставке или изменении данных. Чем больше фрагментов, тем менее доступны данные. Чем больше фрагментов в таблице, тем больше фрагментов индекса приходится просматривать и тем менее масштабируемой становится схема фрагментации. То есть фрагментация ухудшит оба показателя.

Кроме того, серверу Oracle пришлось бы последовательно выполнять вставки и изменения этой таблицы на уровне транзакций. Дело в том, что при добавлении строки со значением ID=1 во фрагмент PART 1, серверу пришлось бы предотвращать вставку строки со значением ID=1 другими сеансами во фрагмент PART 2. Единственный способ добиться этого - запретить изменять фрагмент PART 2, поскольку другого метода заблокировать этот фрагмент просто нет.

В системе ООТ для обеспечения целостности данных требования уникальности должны обеспечиваться системой (сервером Oracle). Это означает, что логическая модель данных будет влиять на физическую. Необходимость поддерживать уникальность либо будет определять схему фрагментации, диктуя выбор ключей фрагментации, либо наличие этих требований приведет к необходимости использования глобально фрагмен-тированных индексов. Рассмотрим глобально фрагментированные индексы более подробно.

Глобально фрагментированные индексы

Глобально фрагментированные индексы разбиваются на фрагменты не так, как базовая таблица. Таблица может быть разбита по значению столбца TIMESTAMP на десять фрагментов, а глобально фрагментированный индекс по этой таблице может быть разбит на пять фрагментов по значению столбца REGION. В отличие от локально фраг-ментированных, есть только один класс глобально фрагментированных индексов - с префиксом. Глобально фрагментированные индексы, ключ которых не начинается с ключа фрагментации, не поддерживаются.

Продолжая предыдущий пример, ниже я представлю простой вариант использования глобально фрагментированного индекса. Вы убедитесь, что глобально фрагменти-рованный индекс обеспечивает уникальность первичного ключа, так что можно использовать фрагментированные индексы, обеспечивающие уникальность, но не включающие ключ фрагментации базовой таблицы. В следующем примере создается таблица, фраг-ментированная по столбцу TIMESTAMP, индекс которой фрагментирован по столбцу ID:

tkyte@TKYTE816> CREATE TABLE partitioned

2 (timestamp date,

3 id int

5 PARTITION BY RANGE (timestamp)

7 PARTITION part l VALUES LESS THAN

8 (to date(01-jan-2000,dd-mon-yyyy)),



Фрагментация 1149

9 PARTITION part 2 VALUES LESS THAN

10 (to date(01-jan-2001,dd-mon-yyyy))

11 )

12 /

Table created.

tkyte@TKYTE816> create index partitioned index

2 on partitioned(id)

3 GLOBAL

4 partition by range(id)

6 partition part l values less than(lOOO),

7 partition part 2 values less than (MAXVALUE)

Index created.

Обратите внимание на использование в этом индексе значения MAXVALUE. Значение MAXVALUE можно использовать в таблицах или индексах, фрагментированных по диапазону. Оно представляет максимально возможное значение. До сих пор в примерах использовались жесткие верхние границы диапазонов (значения, меньшие чем Определенное значение>). Однако для глобально фрагментированного индекса требуется, чтобы фрагмент с наибольшими значениями (последний фрагмент) имел верхний предел MAXVALUE. Это гарантирует, что все строки базовой таблицы можно будет проиндексировать.

Добавим для таблицы первичный ключ:

tkyte@TKYTE816> alter table partitioned add constraint

2 partitioned pk

3 primary key(id)

Table altered.

Пока еще не очевидно, что сервер Oracle использует для поддержки первичного ключа созданный индекс. Доказать это можно с помощью волшебного запроса к словарю данных. Этот запрос необходимо выполнять от имени учетной записи, имеющей привилегию SELECT на базовые таблицы словаря данных или привилегию SELECT ANY TABLE:

tkyte@TKYTE816> select t.name table name

2 , u.name owner

3 , c.name constraint name

4 , i.name index name

5 , decode(bitand(i.flags, 4), 4, Yes,

6 decode(i.name, c.name, Possibly, No)) generated

7 from sys.cdef$ cd

8 , sys.con$ с

9 , sys.obj$ t

10 , sys.obj$ i

11 , sys.user$ u

12 where cd.type# between 2 and 3

13 and cd.con# = c.con#



1150 Глава 14

14 and cd.obj# = t.obj#

15 and cd.enabled = i.obj#

16 and c.owner# = u.user#

17 and c.owner# = uid

18 /

TABLE NAME OWNER CONSTRAINT NAME INDEX NAME GENERATE

PARTITIONED TKYTE PARTITIONED PK PARTITIONED INDEX No

Запрос показывает, какой индекс использовался для поддержки данного требования, и пытается угадать , сгенерировано ли имя индекса автоматически или задано явно. В данном случае он показывает, что для поддержки первичного ключа используется только что созданный индекс PARTITIONED INDEX (имя которого не было сгенерировано автоматически).

Чтобы показать, что сервер Oracle не позволит создать глобальный индекс без префикса, достаточно попробовать:

tkyte@TKYTE816> create index partitionedindex2

2 on partitioned(timestamp,id)

3 GLOBAL

4 partition by range(id)

6 partition part l values less than(1000),

7 partition part 2 values less than(MAXVALUE)

partition by range(id) ERROR at line 4:

ORA-14038: GLOBAL partitioned index must be prefixed

Сообщение об ошибке весьма красноречиво. Глобально фрагментированный индекс должен быть с префиксом.

Итак, когда же надо использовать глобально фрагментированный индекс? Рассмотрим два типа систем - хранилища данных и системы ООТ - и выясним, когда эти индексы могут пригодиться.

Хранилища данных и глобально фрагментированные индексы

Я считаю, что эти две вещи несовместимы. Хранилища данных предполагают определенные особенности; добавляются и удаляются большие объемы данных, высока вероятность сбоя на каком-нибудь из дисков и т.д. В любом хранилище данных, использующем перемещающееся окно, лучше избегать использования глобально фрагменти-рованных индексов. Вот пример того, что я имею в виду под перемещающимся окном, и как на его использование влияет глобально фрагментированный индекс:

tkyte@TKYTE816> CREATE TABLE partitioned

2 (timestamp date,

3 id int

5 PARTITION BY RANGE (timestamp)



1 ... 243 244 245 [ 246 ] 247 248 249 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика