Вы находитесь на странице: 1из 29

Лекция 03.11.2020 г.

по дисциплине:
«Базы данных»

Ссылочная целостность данных.


Внешние ключи. Индексирование.

Поток ИКПИ-81-85, ИКВТ-81,82


План лекции
1. Понятие ссылочной целостности
данных.Терминология.
2. Понятие внешнего ключа.
3. Синтаксис объявления внешнего ключа.
4. Понятие индекса.
5. Как определить для каких полей нужно
создавать индексы?
6. Типы индексов и индексирование таблиц.
7. Синтаксис операторов создания и
удаления индексов.
8. Преимущества и недостатки
индексирования.
9. Вопросы для самопроверки
Понятие ссылочной целостности данных
В самом общем виде понятие целостности БД подразумевает соответствие
имеющейся в ней информации внутренней структуре БД, ее логике.

Например, у нас есть таблица сотрудников, где указаны их имена и табельные


номера.

Логично, что для поля табельных номеров мы установим числовой тип.

Это будет означать, что ничего кроме числового типа в это поле попасть не может.

Еще пример — для поля с именами сотрудников, кроме задания его символьного
типа, мы также задаем его длину.

Это будет означать, что строки больше заданной длины будут обрезаться
сервером и в таблицу попадет строка длиной не больше определенного
максимума.

Всё это правила, называющиеся правилами ограничения целостности, которые


помогают поддерживать указанное выше соответствие.
Задача!
Создадим БД городов мира.
В этой БД мы будем хранить название города
и название страны, в которой находится
город.
Id города Название города Страна
001 Москва Россия
002 Санкт-Петербург Россия
003 Казань Россия
004 Киев Украина
005 Минск Беларусь
Такая структура порождает т.н. избыточность, которая в
свою очередь может повлечь за собой нарушение
целостности данных.

Чтобы избежать этой ситуации существует нормализация


БД, включающая в себя нормальные формы.

Как раз вторая нормальная форма относительно


придуманной нами таблицы, говорит о необходимости
создания дополнительной таблицы.

В новой таблице будут храниться названия стран с их


идентификаторами, и эти идентификаторы стран будут
использоваться в изначальной таблице возле
соответствующего города.
Решение!
Id города Название города Страна
001 Москва 7
002 Санкт-Петербург 7 Таблица городов
003 Казань 7
004 Киев 10380
005 Минск 4311

Id страны Название страны


7 Россия

Таблица стран 10380 Украина


4311 Беларусь
1218 Ангола
1520 Уругвай
Теперь, если у страны изменится название, то мы меняем его
только в таблице стран, а таблицу городов не трогаем
вообще, поскольку в ней нет названий стран.

Согласитесь, удобно.

Фактически мы получили ситуацию, когда идентификатор


страны из справочника (родительская таблица)
используется в другой таблице (дочерней).

Это как раз и есть внешний ключ, который связывает поле


дочерней таблицы с полем родителя.
Но пока что эта связь только у нас в уме. Для сервера ее нет. Соответственно,
никаких ограничений такая связь не накладывает.

Что нам мешает сейчас добавить в таблицу городов город с идентификатором


страны 3?

Т.е. это страна, не представленная в таблице стран. Абсолютно ничего не


мешает.

Добавив указанную запись в таблицу городов мы как раз нарушаем


целостность данных.

К примеру, мы выводим список стран и выводим список городов этой страны.

Наш «блудный» город без страны, таким образом, никогда выведен не будет.

Получается, что это «лишняя», «болтающаяся» запись.


Чтобы избежать этого мы можем указать
серверу связь внешнего ключа с
родительским полем в таблице.

Для того, чтобы реализовать это, следует знать


определенные правила, при которых такая
связь вообще возможна.
Терминология.
Понятие внешнего ключа.

Поле в таблице, ссылающееся на поле другой таблицы


называется внешним ключом.

А поле, на которое оно ссылается, называется


родительским или первичным ключом.

Таблицу, которая имеет внешний ключ (ссылку на запись


другой таблицы) нередко называют дочерней, а таблицу с
родительским ключом - родительской.

Еще в определении связей говорят, что родитель может


иметь только одну уникальную запись, на которую могут
ссылаться несколько записей дочерней таблицы.
Условия обеспечения целостности данных
1. Для использования ограничений внешнего ключа типы
обоих таблиц должны быть одинаковы.

2. Типы родительского и дочернего полей должны быть


абсолютно идентичными.

3. Связь по внешнему ключу опирается на индексы,


поэтому и родительское, и дочернее поля должны содержать
индексы.

4. Связь по внешнему ключу должна опираться на поле с


ограничениями в родительской таблице, т.е. это поле должно
содержать ограничения PRIMARY KEY или UNIQUE.
Рассмотрим практический пример:

Создаем таблицу городов:


Рассмотрим практический пример:

Создаем таблицу стран:


Теперь давайте разберем указанные правила с
учетом запросов.

Поле с внешним ключом — это «city.country_id»


(для того, чтобы не запутаться, перед названием поля
мы указали через точку имя таблицы).

Родительское поле (на которое ссылается внешний


ключ) — это «country.country_id»
1. Для использования ограничений внешнего ключа типы обеих таблиц должны быть одинаковые.

Как видим, для обеих таблиц указан одинаковый тип — «ENGINE=InnoDB».

2. Типы родительского и дочернего полей должны быть абсолютно идентичными.

Это правило также выполняется.

Тип дочернего поля «city.country_id» — «TINYINT UNSIGNED». Тип родителя «country.country_id» —


также «TINYINT UNSIGNED».

3. Связь по внешнему ключу опирается на индексы, поэтому и родительское, и дочернее поля должны
содержать индексы.

Здесь также все ок.

Дочернее поле мы индексируем, добавляя индекс в запросе — «INDEX ixCity (country_id)». Родитель
индексируется автоматически. Дело в том, что для родителя мы имеем PRIMARY KEY, что как раз и
предусматривает автоматический индекс для него.

4. Связь по внешнему ключу должна опираться на поле с ограничениями в родительской таблице, т.е. это
поле должно содержать ограничения PRIMARY KEY или UNIQUE.

И здесь все выполняется: «country.country_id» — «PRIMARY KEY (country_id)».


Отлично!
Таблицы созданы и связь установлена.
Теперь мы не сможем добавить город с
идентификатором страны, которая не
представлена в справочнике.
Кстати, существует и обратная зависимость.
По умолчанию мы не сможем также удалить и
страну из справочника, если для нее в дочерней
таблице есть города, что, в принципе, логично.
Синтаксис объявления внешнего ключа

Для создания ограничения внешнего ключа после


FOREIGN KEY указывается столбец таблицы, который
будет представляет внешний ключ. А после ключевого
слова REFERENCES указывается имя связанной таблицы,
а затем в скобках имя связанного столбца, на который будет
указывать внешний ключ. После выражения REFERENCES
идут выражения ON DELETE и ON UPDATE, которые
задают действие при удалении и обновлении строки из
главной таблицы соответственно.
Практический пример:

Теперь, если мы удалим из справочника страну, то из дочерней таблицы без


всяких дополнительных запросов будут удалены все города этой страны.

Удобно, не правда ли?

И не нарушается целостность данных.


От правильно составленной структуры
базы данных очень сильно зависит
скорость работы всего проекта.

Еще одним инструментом, позволяющим


значительно сократить время отклика
базы, являются индексы БД MySQL.

Перед тем, как рассматривать различные


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

MySQL index представляет из себя структуру, в которой


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

Так как для хранения индексов чаще всего используются


бинарные деревья, поиск среди них занимает чрезвычайно
мало места.
Как определить, для каких полей нужно
создавать индексы?
Индексы, прежде всего, нужно создавать по тем полям, которые
часто попадают в условие «where» ваших sql-запросов.

Например, таблица с товарами имеет следующую структуру:

Для формирования страниц, к примеру, вам часто приходится


делать запросы для поиска товаров одной категории:

SELECT id, product_name FROM products WHERE cat_id = '5'


Принцип работы индексов очень прост.
Для примера рассмотрим запрос:

SELECT Name FROM Persons WHERE Points < 10

У нас имеется таблица Persons, в которой есть два поля: Name и Points.
При поиске в неиндексированной таблице, система последовательно
перебирает все строки и сравнивает их с 10.

При выполнении условия – выводит их.

Даже при наличии в таблице всего 1000 записей, такой запрос может
оказаться ресурсоемким, если одновременно поступит от 100 абонентов.

Индексирование таблиц MySQL позволяет сократить число операций.

Если поле Points будет проиндексировано, поиск будет проводиться по


самому индексу, без перебора всех строк таблицы.
Типы индексов и индексирование таблиц

Простые. Одному полю таблицы соответствует один индекс.

Составные. Один индекс соответствует нескольким полям таблицы.

Покрывающие. Этот вид индексов создается специально под определенный


запрос и включает в себя все поля таблицы, фигурирующие в запросе.

Индексировать есть смысл только определенные поля таблицы.

Использование одного составного индекса вместо нескольких односоставных


для ускорения наиболее активно использующихся запросов также ускорит
скорость работы с БД.

Покрывающие индексы позволяют получать результат вообще без обращения к


таблице БД. Иногда добавление дополнительного проиндексированного поля
позволяет существенно сократить время обработки запросов.
Синтаксис оператора создания индекса
Для операции создания индекса MySQL предусматривает такой синтаксис:

CREATE [UNIQUE | FULLTEXT] INDEX <уникальное имя индекса> ON <имя


таблицы> (<имя столбца> [(length)],... )

где:

[UNIQUE | FULLTEXT] – определяет, будет ли индекс содержать только


уникальные значения (UNIQUE), или в нем будут присутствовать и
повторяющиеся значения (FULLTEXT). По умолчанию используется режим
FULLTEXT.

Length – определяет длину символов поля для индексирования. Если Length


оставить пустым, то в индекс попадет поле целиком вне зависимости от длины.
<имя столбца> - уникальный идентификатор индекса. Если это поле не
определено, ему будет присвоено имя первого подлежащего индексации столбца.
Синтаксис оператора удаления индекса

Удалить индекс можно при помощи такого


оператора:

DROP INDEX <Имя индекса> ON <Имя


таблицы>
Преимущества и недостатки
индексирования
В процессе индексирования MySQL создает дополнительные
таблицы, в которых хранятся отсортированные данные.
Однако, в большинстве случаев выгоды от быстродействия
более ощутимы, чем издержки физической памяти.

Запросы на вставку данных в таблицу выполняются чуть


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

В целом, как вы можете видеть, достоинства от


использования индексов значительно перевешивают
небольшое количество недостатков. На больших и
посещаемых проектах без использования индексов не
обойтись.
Практический пример:

Например, у вас таблица называется test, где хранятся данные по


городам России с улицами вида Город, Улица, Дом.

Понятно, что строк в таблице будет много.

Если вы часто делаете выборку по определенному городу, например:


select * from test where city = 'Омск'

то, чтобы этот запрос отработал быстрее обычного, следует добавить


индекс по правилу: create index city_index on test (city)

Тогда тот же самый запрос


select * from test where city = 'Омск'

отработает гораздо быстрее, если столбец city будет проиндексирован.


Вопросы для самопроверки
1 Что такое индекс? объект базы данных, объект базы данных, объект базы данных, объект базы данных,
создаваемый с целью создаваемый с целью создаваемый с целью создаваемый с целью
повышения повышения повышения повышения
производительности производительности производительности производительности
поиска данных поиска данных поиска данных поиска данных

2 Количество индексов на 16 32 31 64
одну таблицу My Isam в My
SQL составляет:

3 Может ли индекс типа может не может может, только для таблиц Верны варианты
PRIMARY KEY содержать My Isam ответа а и с
пустые значения?

4 Удаление индексов DROP TABLE ALTER TABLE UPDATE INDEX Верны варианты
производится оператором: ответа а и b

5 Какие запросы в БД запросы на изменение запросы на добавление запросы на удаление запросы на


замедляются при данных данных данных обновление таблицы
использовании индексов?
Вопросы для самопроверки

6 Ссылочная целостность индексных файлов комбинирования согласованности данных нет правильных


поддерживается в базе первичного ключа и вариантов ответа
данных за счет: внешнего ключа

7 Какое поле можно считать поле, значения в которомполе, которое носит поле, значения в котором поле, значение
уникальным? не могут, повторятся уникальное имя повторяются которого имеют
свойство наращивания

Вам также может понравиться