Индексы играют большую роль в базах данных, т. к. это основной способ ускорения их работы. Обычно записи в таблице располагаются в хаотическом порядке (рис. 5.1). Для того чтобы найти нужную запись, необходимо сканировать всю таблицу, на что уходит большое количество времени. Идея индексов состоит в том, чтобы создать для столбца копию, которая постоянно будет поддерживаться в отсортированном состоянии. Это позволяет очень быстро осуществлять поиск по такому столбцу, т. к. заранее известно, где необходимо искать значение.
Обратной стороной медали является то, что добавление или удаление записи требует дополнительного времени на сортировку столбца, кроме того, создание копии увеличивает объем памяти, необходимый для размещения таблицы на жестком диске.
Существует несколько видов индексов.
Индексы могут иметь как свои собственные имена, так и имена индексируемых столбцов. Один индекс может охватывать один или несколько столбцов, причем тип столбца может быть любым, за исключением enum и set.
Так как записи в реляционной таблице не упорядочены, нельзя выбрать строку по ее номеру (как в массиве), поэтому для идентификации записи в таблицу вводится так называемый первичный ключ. Первичный ключ является главным индексом таблицы и объявляется при помощи ключевого слова primary key, у таблицы может быть только один первичный ключ. Значение первичного ключа должно быть уникально и не повторяться в пределах таблицы. Кроме того, столбцы, помеченные атрибутом-primary key, не могут принимать значение null. Для пометки поля таблицы в качестве первичного ключа достаточно поместить это ключевое слово primary key в определение столбца. В листинге 5.1 приведено определение таблицы catalogs (см. листинг 4.24), где в качестве первичного ключа назначен столбец id_catalog.
Просмотр структуры таблицы catalogs при помощи оператора describe показывает, что в четвертой колонке результирующей таблицы напротив поля id_catalog появился флаг pri, который отмечает поле первичного ключа (листинг 5.2)
Существует альтернативный способ объявления первичного ключа, представленный в листинге 5.3.
Как видно из листинга 5.3, объявление первичного ключа производится после объявления основных столбцов.
В качестве первичного ключа может выступать не только целочисленный столбец, но и текстовые данные. В этом случае необходимо обязательно добавить в круглых скобках число символов, входящих в индекс
Как видно из листинга 5.4, первичный ключ создается по первым 10 символам столбца name. Можно индексировать от 1 до 1000 символов текстового столбца. Следует помнить, что индексирование по одному символу приведет к тому, что уникальные символы быстро исчерпаются, и будет невозможно добавить новую запись в таблицу. Индексирование по большому числу символов приведет к резкому увеличению объема жесткого диска, необходимого для хранения таблицы.
Индекс необязательно должен быть объявлен по одному столбцу, вполне допустимо объявление индекса сразу по двум или более (до 16) столбцам (листинг 5.5).
Просмотр структуры таблицы catalogs при помощи оператора describe показывает, что в четвертой колонке результирующей таблицы оба поля: и id_catalog, и name имеют флаг pri, который отмечает первичный ключ (листинг 5.6)
В качестве первичного ключа часто выступает столбец типа int или bigint. В таблицах учебной базы данных shop, созданных в главе 4, все поля, начинающиеся с префикса id_, предназначены для первичного ключа. Такой выбор связан с тем, что целочисленные типы данных обрабатываются быстрее всех и занимают небольшой объем данных. Другой причиной выбора целочисленного столбца является тот факт, что только данный тип столбца может быть снабжен атрибутом auto_increment, который обеспечивает автоматическое создание уникального индекса. Передача столбцу, снабженному этим атрибутом, значения null или 0 приводит к автоматическому присвоению ему максимального значения столбца плюс 1. Данный механизм является достаточно удобным и позволяет не заботиться о генерации уникального значения средствами прикладной программы, работающей с СУБД MySQL. В листинге 5.7 приводится пример использования ключевого слова autoincrement.
Просматривая структуру вновь созданной таблицы catalogs при помощи оператора describe (листинг 5.8), можно заметить, что для столбца id_catalog в шестой колонке Extra результирующей таблицы появилась запись auto_increment, сообщающая, что столбец снабжен этим атрибутом.
Как видно из листинга 5.8, для столбца id_catalog в качестве значения по умолчанию выставлено null, однако само поле не может принимать значение null. Передача null приведет к генерации уникального числа, которое и будет занесено в id_catalog. Если в таблице нет ни одного значения, то первое уникальное значение будет равным 1. Точно так же, как и в таблице может быть только один первичный ключ, столбцов, снабженных атрибутом auto_increment, также не должно быть больше одного.
К атрибуту auto__increment мы еще вернемся в главе 6 при рассмотрении оператора insert — вставки данных в таблицу.