Лекция 13. Первичные ключи
При создании таблицы могут быть использованы различные «ограничения» (constraints), которые содержат правила, указывающие, какие данные представлены в ней. Одним из самых используемых ограничений является первичный ключ (primarykeyconstraint), который гарантирует, что каждая строка таблицы должна содержать уникальное значение. Первичный ключ может состоять из одного или нескольких столбцов. Первичные ключ, состоящие из нескольких столбцов, также называются «составными» (composite).
Правильным считается наличие первичного ключа во всех таблицах базы данных. При этом существует два варианта первичных ключей: искусственный (surrogateprimarykey) и естественный (naturalprimarykey).
Первый вариант обычно представляет собой целочисленный идентификатор. Применяется там где нет возможности использовать натуральный первичный ключ. Позволяют решать те же практические задачи, что и естественные: улучшение производительности памяти и индексов при операциях обновления.
Второй же вариант представляет собой данные, которые уже присутствуют в описываемой предметной области. Например, почтовые индексы могут быть использованы как естественные первичные ключи без дополнительной обработки. Их использование, если, конечно, оно возможно, считается более правильным, чем искусственных.
Пример создания первичного ключа:
CREATE TABLE employee(
emp_id INTEGER,
emp_name VARCHAR(30),
dep_id INTEGER,
PRIMARYKEY(emp_id)
)
Лекция 14. Внешние ключи
В то время как одна таблица имеет первичный ключ, другая таблица может иметь ограничение, описывающее, что её строки ссылаются на гарантированно существующие строки в первой таблице. Это реализуется через создание в «удалённой» таблице («потомке») столбца (может быть и несколько), значениями которого являются значения первичного ключа из «локальной» таблицы («родителя»). Вместе наборы этих столбцов составляют внешний ключ (foreignkeyconstraint), который является механизмом базы данных, гарантирующим что значения в «удалённых» столбцах присутствуют как первичные ключи в «локальных». Это ограничение контролирует все операции на этих таблицах: добавление / изменение данных в «удалённой» таблице; удаление / изменение данных в «родительской» таблице. Внешний ключ проверяет, чтобы данные корректно присутствовали в обоих таблицах. Иначе операции будут отменены.
Внешние ключи могут быть составными, если входящие в них первичные ключи являются таковыми.
В примере представлена таблица «department», которая связана с таблицей «employee» через отношение столбцов «employee.dep_id» и «department.dep_id»:
Представленная на рисунке связь может быть описана через DDL следующим образом:
CREATETABLEdepartment(
dep_idINTEGER,
dep_nameVARCHAR(30),
PRIMARYKEY(dep_id)
)
CREATETABLEemployee(
emp_idINTEGER,
emp_nameVARCHAR(30),
dep_idINTEGER,
PRIMARYKEY(emp_id),
FOREIGNKEY(dep_id)
REFERENCESdepartment(dep_id)
)
Нормализация
Реляционная модель базируется на реляционной алгебре, одним из ключевых понятий которой является нормализация.
Основной идея нормализации в исключении повторяющихся данных так, чтобы конкретная часть данных была представлена только в одном месте. Этот подход позволяет упростить данные до максимально атомарного вида, с которым намного проще работать: искать, производить какие-либо операции.
Классический пример денормализованных данных:
-
EmployeeLanguage
|
name
|
language
|
department
|
Dilbert
|
C++
|
Systems
|
Dilbert
|
Java
|
Systems
|
Wally
|
Python
|
Engineering
|
Wendy
|
Scala
|
Engineering
|
Wendy
|
Java
|
Engineering
|
Строки в этой таблице могут быть уникально идентифицированы по столбцам «name» и «language», которые являются потенциальным ключом. По теории нормализации таблица из примера нарушает вторую нормальную форму. Потому как неосновной атрибут «department» логически связан только со столбцом «name». Правильная нормализация в данном случае выглядит следующим образом:
-
EmployeeDepartment
|
name
|
department
|
Dilbert
|
Systems
|
Wally
|
Engineering
|
Wendy
|
Engineering
|
EmployeeLanguage
|
name
|
language
|
Dilbert
|
C++
|
Dilbert
|
Java
|
Wally
|
Python
|
Wendy
|
Scala
|
Wendy
|
Java
|
Теперь наглядно видно, как вторая форма улучшила структуру данных. Изначально пример содержал повторы связок полей «name» и «department» так часто, как часто встречался уникальный для данного имени «язык». Улучшенный же вариант сделал связки «name/department» и «name/language» независимыми друг от друга.
Ограничения данных, такие как первичные и внешние ключи, предназначены как раз для достижения состояния нормализации. Для примера выше это будет выглядеть так:
«Employee Department -> name» - первичныйключ;
«Employee Language -> name, language» - составнойпервичныйключ;
«Employee Language -> name», всвоюочередь, - внешнийключ, наполе «Employee Department -> name».
Если таблицу удаётся сходу свернуть в отношения ключей, то это, зачастую, значит, что она не нормализована.
Достарыңызбен бөлісу: |