Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
БД.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
387.07 Кб
Скачать

1.3.3. Ключи и индексы

Пусть таблица наличия имеет следующее состояние:

Лицо

Предмет

Кол-во

Физ. № записи

. . .

12

5

2

31

3

23

10

32

12

9

5

33

17

5

20

34

3

10

100

35

12

11

3

36

5

7

1

37

5

5

4

38

. . .

И пусть необходимо ответить на следующие запросы: 1) какие предметы есть у лица с условным номером 12; 2) у каких лиц есть предметы с условным номером 5.

Очевидно, что ответы как на один, так и на другой запрос потребуют полного перебора всех записей таблицы наличия. В реальных приложениях эта таблица может иметь большой объем и, соответственно, для обработки запросов потребуются существенные затраты времени. Нет ли какого либо пути для ускорения работы в таких ситуациях?

Определим еще одну таблицу с двумя столбцами, в один из которых скопированы значения из столбца «Лицо» таблицы наличия, а в другой записаны физические номера соответствующих записей в этой таблице. Под физическими номерами записей здесь понимается порядковый номер записи в файле таблицы для локальных БД и номер страницы, где расположена соответствующая строка, для серверных БД. Полученную таблицу отсортируем по значениям в поле «Лицо»:

Лицо

№ записи

. . .

3

32

3

35

5

37

5

38

12

31

12

33

12

36

17

34

. . .

Такая таблица называется индексом таблицы «Наличие» по полю «Лицо».

Теперь для ответа на первый запрос достаточно найти в таблице индекса первую строку с номером лица 12, выбрать все следующие за ней строки со значением 12 в поле «Лицо», а по значениям в поле «№ записи» выбрать необходимые строки из исходной таблицы наличия. Такой подход позволяет значительно ускорить поиск нужных строк, поскольку:

  1. Таблица индекса имеет меньший объем, чем исходная таблица, т.к. содержит только индексируемые поля.

  2. Записи в индексе упорядочены по значениям полей поиска.

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

Аналогично, для ускорения выполнения второго запроса следует построить индекс таблицы наличия по полю «Предмет».

Таким образом, индексы позволяют существенно ускорить операции поиска, а также операции сортировки. С другой стороны, реализация связей между дочерними и родительскими таблицами сводится к выполнению операций поиска (поиск нужной родительской записи или всех соответствующих дочерних записей). Здесь возникает очевидная идея использовать для ускорения операций поиска соответствующие индексы. Именно по этой причине во всех СУБД по определениям первичных и внешних ключей всегда строятся индексы. Причем делается это независимо от желания пользователя.

Такая взаимосвязь между ключами и индексами породила некоторую путаницу при использовании этих понятий. Нередко можно встретить использование термина «ключ» в отношении индекса и наоборот. Во избежание проблем следует запомнить:

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

  2. Индексы – это физический механизм, позволяющий значительно ускорить выполнение операций поиска и сортировки и используемый, в частности, для реализации ключевых взаимодействий.

Индексы, создаваемые по определениям ключей, принято называть первичными. Помимо них для ускорения поиска и сортировки могут создаваться индексы и по неключевым полям. Их называют вторичными. При создании таких индексов следует иметь в виду, что индексы, с одной стороны, ускоряя поиск и сортировку, с другой стороны, замедляют выполнение операций по изменению содержимого индексируемых таблиц. Дело в том, что всякое изменение значений индексных полей требует соответствующих изменений в таблицах индексов. При этом полная перестройка индексных таблиц невозможна из-за неприемлемых временных затрат. Приходится достраивать индексы по определенным правилам, но накопление такого рода достроек приводит к падению эффективности индексного поиска. Рано или поздно наступает ситуация, при которой прямой перебор содержимого таблицы оказывается более выгодным, чем использование «плохого» индекса.

Таким образом, индексы не являются универсальным средством, которое можно использовать везде и всюду для повышения производительности. Кроме того, они требуют специальных мероприятий по поддержанию своей полезности. Необдуманное применение индексов может не только оказаться неэффективным, но и замедлит работу всей БД.

В заключение рассмотрим некоторые разновидности индексов.

Составной индекс – это индекс, построенный по нескольким полям. При этом порядок следования полей в индексе суть важен. Например, индекс таблицы наличия по полям «Лицо» + «Предмет»:

Лицо

Предмет

№ записи

. . .

3

10

32

3

23

35

5

5

37

5

7

38

12

5

31

12

9

33

12

11

36

17

5

34

. . .

может быть использован как для поиска по паре полей «Лицо» + «Предмет», так и для поиска по полю «Лицо», но не может быть использован для поиска по полю «Предмет», поскольку по этому полю он не упорядочен.

Уникальный (Unique) индекс – это индекс, в котором каждому набору значений индексных полей может соответствовать только одна запись. Такого рода индексы строятся, например, по определениям первичных и альтернативных ключей. В нашем примере имеет смысл построить уникальный индекс в таблице предметов по полям «Наименование» + «Цена» с тем, чтобы сделать невозможным добавление одного и того же предмета дважды.

Регистрочувствительный (Case Sensitive) индекс – это индекс, учитывающий регистр букв при сортировке.

Индекс в обратном порядке (Descending) – это индекс, построенный в порядке убывания значений индексных полей (обычный индекс строится в порядке возрастания). Такие индексы часто используются для упорядочения по датам с тем, чтобы вначале располагались более поздние даты. Например, таблицу проводок имеет смысл сортировать в порядке убывания их дат, чтобы в первую очередь видеть более поздние проводки.