С первого взгляда все понятно, верно? В этой таблице три столбца – ID, NAME и BIRTHDATE.
В столбце ID хранится уникальный идентификатор каждого сотрудника. Он же может являться табельным номером. У каждого сотрудника этот номер свой.
В столбце NAME хранится Фамилия Имя Отчество (ФИО) сотрудников. В компании, которую мы уже начали рассматривать в рамках наших уроков, полные однофамильцы допустимы. И чтобы различать сотрудников в кадровом, бухгалтерском и других учетах, каждому сотруднику и присваивают уникальный идентификатор (табельный номер) – столбец ID.
В столбце BIRTHDATE – дата рождения каждого сотрудника.
Столбцы таблицы в терминологии баз данных называются полями. В приведенном выше примере у таблицы Сотрудники три поля.
Строки таблицы называются ее записями. Когда мы будем писать запросы, те строки данных, которые будет возвращать запрос SELECT, тоже будут называться записями. Ты, наверняка, слышал, как общаются между собой разработчики или аналитики, пишущие запросы: «сколько записей вернул твой запрос»? Это и имелось ввиду: сколько строк данных удалось получить запросом (командой выборки данных из базы данных). У таблиц и запросов строки данных имеют еще одно название – кортежи. Этот термин был введен одним из разработчиков языка SQL, но на практике термин кортеж не прижился.
Столбец или набор столбцов, с помощью которых можно явно определить только одну строчку (запись) в таблице, называется первичным ключом (Primary Key, или сокращенно PK). В нашем примере, это специально созданный (для идентификации) столбец ID.
При проектировании системы эквайринга (приеме денежных оплат) через терминалы (которые мы можем встречать в супермаркетах или на улице) или через банк, в таблице приема платежей у каждой операции должен быть свой уникальный идентификатор (он печатается на чеке). Чтобы, в случае не зачисления средств, можно было обратиться в службу поддержки и назвать номер платежа. Хотя, современные информационные системы умеют и без того быстро находить проводившиеся оплаты с помощью номера телефона, в счет которого совершался платеж, или с помощью номера лицевого счета, который итак всегда известен плательщику.
В каждой таблице, где требуется иметь возможность сослаться на конкретную строчку таблицы (например, в таблице платежей – на конкретный платеж, в таблице клиентов – на конкретного клиента), должен быть первичный ключ.
Надеюсь, теперь стало ясно что такое первичный ключ и для чего он нужен. В большинстве случаев – это отдельный (один) столбец. Но также первичным ключом может быть два столбца (два поля)! И более. Тогда сочетание значений в этих столбцах должно быть всегда уникально в пределах целой таблицы. И сочетание значений одной строки не может повторяться для другой строки. Чтобы лучше понять для чего же такое может понадобиться, рассмотрим следующий пример.
Некоторая фирма, имеющая несколько филиалов, в конце каждого месяца собирает аналитику по деятельности компании: среднесписочная численность сотрудников в каждом филиале, общая сумма денежных поступлений и сумма денежных расходов по филиалу.
В графе ID_FILIAL указывается идентификатор филиала, по которому файл. сохраняются итоги, а в графе PERIOD указывается месяц и год, за который сохраняются итоги. Далее в столбцах AVG_PERS_COUNT, SUM_IN и SUM_OUT указывается среднее количество сотрудников, сумма поступлений и расходов, соответственно.
В нашем примере, за январь 2018 года, была внесена информация по трем филиалам. Проходит месяц и теперь вносится информация за февраль 2018.
Если смотреть значение только в графе ID_FILIAL, то мы обнаружим, что оно повторяется. Конечно, ведь данные по одному филиалу вносились каждый месяц. Значение идентификатора филиала повторяется, но в сочетании со значением столбца PERIOD – оно уникально! Со значением ID_FILIAL = 1 и PERIOD = Январь 2018 есть только одна строчка. Также как и со значением ID_FILIAL = 3 и PERIOD = Февраль 2018.
Так как при проектировании таблицы, так и задумали, что по каждому филиалу за один месяц информация будет только в одной строке, программисты установили сочетание столбцов ID_FILIAL и PERIOD первичным ключом. Это очень просто можно настроить на любой таблице и в одной из следующих глав мы рассмотрим, как это делается. Первичный ключ, если его устанавливать на таблице, помимо логики, дает еще массу преимуществ: теперь ORACLE (или другая СУБД, если ты работаешь не в ORACLE) будет контролировать, чтобы никто не смог добавить строку в таблицу с повторяющейся комбинацией ID_FILIAL и PERIOD. Кроме того, первичный ключ – это еще и самый быстрый способ получения из таблицы информации: если кто–то захочет получить сведения из таблицы по ID_FILIAL = 1 и за Апрель 2019 (например), то вне зависимости столько бы много строчек в таблице не было, СУБД сразу даст результат. Сразу – это значит за мгновение, даже если в таблице будут миллионы строк. Об оптимизации запросов, ключах и индексах у нас будет отдельная тема и мы подробно рассмотрим, как писать запросы так, чтобы они всегда быстро работали!
Теперь рассмотрим еще один термин, который нам нужно понять – внешний ключ (Foreign Key, или сокращенно FK).
В компании, базу данных которой мы рассматриваем, помимо таблицы «Сотрудники», есть еще таблица «Автомобили сотрудников».
В таблице «Автомобили сотрудников» есть 4 столбца: столбец ID – сквозной идентификатор каждого учетного автомобиля, столбец ID_PERS – идентификатор сотрудника, владельца автомобиля, столбец NOMER – государственный регистрационный номер автомобиля и столбец MARKA – марка автомобиля.
В таблице «Автомобили сотрудников» столбец ID будет являться собственным первичным ключом. А в столбце ID_PERS указаны только такие значения, которые есть в таблице «Сотрудники» в графе ID. Столбец (или набор столбцов), значения которого ссылаются на первичный ключ другой таблицы, называется внешним ключом (или foreign key, сокращенно FK). Чтобы было еще понятнее, Foreign key лучше перевести не как «внешний ключ», а как «чужой ключ», то есть ключ не своей таблицы, а другой. Стало понятнее?
Из рисунка выше видно, что Audi A4 принадлежит сотруднику с идентификатором 1, то есть Иванову Ивану. Два автомобиля BMW X3 и Ford Mondeo у сотрудника Петрова Надежда Анатольевна. Fiat Panda принадлежит Афанасию Константиновичу и т.д. Сотрудник Первый Николай Николаевич не имеет ни одного автомобиля, так как в таблице «Автомобили сотрудников» нет ни одной записи (ни одной строки), где бы в столбце ID_PERS было значение 4.
Разработчики создали в таблице «Автомобили сотрудников» столбец ID_PERS и сознательно настроили так, чтобы он был внешним ключом, то есть значения в нем могли бы быть только такими, которые есть в таблице «Сотрудники» в столбце ID. Теперь СУБД будет сама контролировать, запись с каким значением для графы ID_PERS добавляется в таблицу «Автомобили сотрудников». Чтобы нельзя было добавить строчку в таблицу, указав идентификатор владельца такого, которого нет. Это и есть главное назначение внешнего ключа.
В таблице «Автомобили сотрудников» значение графы ID_PERS ссылается на идентификатор конкретного сотрудника. По этому идентификатору всегда можно получить все сведения о сотруднике: Фамилию Имя Отчество, в каком отделе он работает, на какой должности и т.д. В базе данных еще есть много таблиц, и почти каждая из них имеет столбец, который ссылается на другую таблицу. Например, в таблице Сотрудников, помимо прочих, может быть еще и столбец, указывающий на идентификатор филиала, в котором работает сотрудник. По идентификатору филиала в таблице Филиалов можно найти конкретную строчку с названием филиала и другой сопутствующей информацией: адресом, телефоном и т.д.