Рис. 13
Примечание
Данные в поле supplierId могут повторяться в нескольких записях в таблице products, но не в таблице suppliers.
Давайте проанализируем взаимосвязь между таблицами products, order_details и orders (рис. 14).
Рис. 14
Таблица order_details имеет два первичных ключа (обозначено значками ключей). Можно трактовать это как составной ключ, то есть для определения первичного ключа используются два или более поля. Хотя технически в примере задействовано два ключа, стоит рассматривать их как единый элемент — собственно первичный ключ.
Комбинация данных в полях, используемая для формирования составного ключа, работает как уникальный идентификатор для любой записи в таблице. Другими словами, если запись OrderId в таблице order_details равна 101, а ProductId той же записи — P006, то мы можем предположить, что никакая другая запись в таблице не будет иметь такую же комбинацию данных этих двух полей. Могут существовать одна или несколько других записей с OrderId, равным 101, а также одна или несколько других записей с ProductId, равным P006, но только одна запись может иметь и 101 в качестве своего OrderId, и P006 в качестве своего ProductId. Эта комбинация данных работает как составной ключ, который, как и любой первичный ключ, обеспечивает уникальный идентификатор для каждой записи в таблице.
Рис. 15
В связи «один-ко-многим» стандартный первичный ключ находится на стороне «один». Например, в таблице orders мы видим, что первичный ключ, поле OrderId, предоставляет уникальный идентификатор для каждой записи в таблице. Сторона связи «ко-многим» находится в таблице order_details. Как вы думаете, почему?
Давайте рассуждать логически. Можно сделать вывод, что роль таблицы order_details — предоставить информацию о различных заказанных товарах. Также допустимо, что любой товар может быть заказан несколько раз несколькими заказчиками при самых разных обстоятельствах, с разными ценами и т. д. Следовательно, поле ProductId не может использоваться само по себе в качестве первичного ключа для таблицы order_details. Кроме того, любой заказ может включать в себя несколько товаров, и если мы проанализируем другие поля, используемые в таблице order_details — UnitPrice, Quantity и Discount, тогда мы четко поймем, что эти поля обозначают свойства определенного товара, а не заказ в целом. Также поле OrderId не может использоваться само по себе в качестве первичного ключа для таблицы order_details. Решение состоит в том, чтобы объединить ProductId и OrderId в составной ключ, тем самым гарантируя, что данные, содержащиеся в столбцах UnitPrice, Quantity и Discount, будут соответствовать уникальному и определенному заказу и уникальному и определенному товару в этом заказе.
Типы данных
Ранее в этой главе мы описывали концепцию метаданных, которые представляют собой детальную информацию обо всех объектах системы. При разработке базы данных с использованием SQL для каждого используемого столбца должен быть назначен определенный тип данных. Типы данных могут незначительно отличаться в зависимости от используемой версии SQL. Однако, как правило, у вас будут числовые, символьные или текстовые типы данных, дата и время, а также логические значения. Рассмотрим каждый из них.
Числовые типы данных
В состав числовых данных входят целочисленные данные, которые служат для отображения целых чисел. Обычно, когда используется целочисленный тип данных, он имеет ограничения на длину. Напомним, что изображенная на рис. 7 таблица содержала сведения о пациентах. Для столбца Weight (Вес) разумно использовать целочисленный тип данных с ограничением до трех цифр. Почему?
1. Вполне достаточно округлить значение в большую и меньшую сторону до ближайшего значения фунта или килограмма и не использовать десятичные знаки.
2. Вряд ли нам понадобится более трех цифр для указания значения веса в фунтах.
Когда целочисленные данные не подходят и возникает необходимость в более точном числовом формате, мы можем использовать формат чисел с плавающей запятой. Как и целочисленные данные, они могут быть ограничены по длине.
Рис. 16*
Примечание
Для типов данных, допускающих более длинные диапазоны цифр, символов и т. д., требуется больший объем памяти в байтах. SQL также допускает денежные (финансовые) типы данных.