После того, как вы разделили вашу информацию по таблицам, вам требуется способ сказать Visual FoxPro, как принести ее назад в удобным способом. Например, приведенная ниже форма включает в себя информацию из нескольких таблиц.
Поясняющие надписи у рисунка - слева направо и сверху вниз:
Информация берется из таблицы Customer...
... таблицы Products
... таблицы Order Line Items
... и таблицы Orders
Visual FoxPro представляет собой систему управления реляционными базами данных. Это означает, что вы храните связанные данные в отдельных таблицах. Затем вы определяете отношения между таблицами, а Visual FoxPro использует эти отношения для поиска связанной информации, хранящейся в базе данных.
Например, предположим, что вы желаете позвонить работнику с вопросом о сделанных им продажах. Номер телефона работника записан в таблицу Employee; продажи записаны в таблицу Orders. Когда вы говорите Visual FoxPro, какая из продаж вас интересует, Visual FoxPro может поискать телефонный номер на основев отношения между двумя таблицами. И это работает, так как Employee_id, являющийся первичным ключом таблицы Employee, является также полем в таблице Orders. В терминологии баз данных поле Employee_id в таблице Orders называется внешним (foreign) ключом, потому что оно ссылается на первичный ключ из другой, внешней (foreign),таблицы.
Поясняющие надписи у рисунка - слева направо и сверху вниз:
Первичный ключ
Поле Employee ID появляется в обоих таблицах
Внешний ключ
Итак, для установки отношения между двумя таблицами — Table A и Table B — вы добавляете первичный ключ таблицы в другую таблицу с тем, чтобы он появился в обоих таблицах. Но как решить - первичный ключ какой таблицы использовать? Для корректной установки отношения, вы сначала должны определить природу отношения. Имеется три типа отношений между таблицами:
-
Один-ко-многим (One-to-many)
-
Многие-ко-многим (Many-to-many)
-
Один-к-одному (One-to-one)
Приведенные ниже примеры представляют каждый тип отношений и объясняют, как сконструировать ваши таблицы, так чтобы Visual FoxPro мог корректно связывать данные. Примеры предназначены для объяснения - как вы сможете определить отношения между вашими таблицами и как вы сможете решить - какие поля, принадлежащие этим таблицам, будут поддерживать такие отношения - но не описывают интерфейса Visual FoxPro для связывания таблиц отношениями.
Пример
Отношение "один-ко-многим" является наиболее общим типом отношений в реляционной базе данных. В отношении "один-ко-многим" запись в таблице Table A может иметь более одной соответствующей записи в таблице Table B, а записи в таблице Table B имеют, по крайней мере, одну соответствующую запись в таблице Table A.
Например, таблицы Category и Products в базе данных Tasmanian Traders имеют отношение "один-ко-многим".
Поясняющие надписи у рисунка - слева направо и сверху вниз:
Одна категория может относиться ко многим продуктам
Для установки одношения, вы добавляете поле или поля, которые создают первичный ключ на стороне отношения "один" к таблице на стороне отношения "многим". Вы используете первичный ключ или индекс-кандидат для стороны отношения "один" и обычный индексный ключ на стороне отношения "многим". Вы таком случае, вы должны добавить поле Category_id из таблицы Category в таблицу Products, поскольку она категория включается в себя много продуктов. Visual FoxPro использует номер category ID для поиска корректной категории для каждого продукта.
Для получения более подробной информации смотрите описание Работа с таблицами.
Пример
В отношении "Многие-ко-многим", запись в таблице Table A может иметь более одной соответствующей записи в таблице Table B, а запись в таблице Table B может иметь более одной соответствуюзей записи в таблице Table A. Такой тип отношения требует изменений в дизайне вашей базы данных до того, как вы сможете корректно указать отношения в Visual FoxPro.
Для обнаружения отношения "многие-ко-многим" между вашими таблицами, очень важно, чтобы вы посмотрели оба направления отношения. Например, рассмотрим отношения между заказами и продуктами в бизнесе Tasmanian Traders. Один заказ может включать в себя более одного продукта. Поэтому для каждой записи в таблице Orders имеется много записей в таблице Products. Но это еще не вся история. Каждый продукт может появляться во многих заказах. Поэтому каждой записи в таблице Products имеется много записей соответствия в таблице Orders.
Субъекты двух таблиц — заказы и продукты — имеют отношение "многие-ко-многим". Это представляет определенную проблему в дизайне баз данных. Для понимания проблемы, представьте себе, что случится, если вы попытаетесь установить отношение между двумя таблицами введением поля Product_id в таблицу Orders. Для того, чтобы иметь более одного продукта в заказе, вам необходима более чем одна запись на один заказ в таблице Orders. Вы будете повторять информацию о заказе снова и снова для каждой записи, которая связана с одиночным заказам - то есть неэффективный дизайн может привести к неточным данным. Вы можете попасть в такую же проблему, если вы вставить поле Order_id field в таблицу Products — у вас будет более чем одна запись для кждого продукта в таблице Products. Для решения этой проблемы, создайте третью таблицу, которая разорвет отношение "многие-ко-многим" на два отношения "один-ко-многим". Эта третья таблица, называется перекрестной или объединяющей таблицей, так как она действует как объединение между двумя таблицами. Вы положите первичный ключ из каждой таблицы в одну перекрестную таблицу.
Поясняющие надписи у рисунка - слева направо и сверху вниз:
Первичный ключ из таблицы Orders
Первичный ключ из таблицы Products
Информация, которая связывает оба субъета - и заказ, и продукт
Перекрестная таблица должна хранить только два первичных ключа из таблиц, которые их связывают, или, подобно таблице Order_Line_Items table, перекрестная таблица может хранить дополнительную информацию.
Каждая запись в таблице Order_Line_Items представляет одну строку в заказе. Первичный ключ таблицы Order_Line_Items состоит из двух полей - внешних ключей из таблиц Orders и Products. Поле Order_id само по себе не работает в качестве первичного ключа для этой таблицы, потому что один заказ может иметь множество строк предметов заказа. Значение order ID повторяется для каждой строки предметов в заказе, поэтому поле не содержит уникальных значений. Поле Product_id само по себе также не работает, так как один продукт может появляться в различных заказах. Но вместе два этих поля в таблице объединения всегда производят уникальное значение для записи. Перекрестная таблица не нуждается в своем собственном первичном ключе.
В базе данных Tasmanian Traders, таблицы Orders и Products прямо не связаны между собой. Вместо этого, они связаны непрямо через таблицу Order_Line_Items. Отношение "многие-ко-многим" между заказами и продуктами представлено в базе данных посредством двух отношений "один-ко-многим":
-
Таблицы Orders и Order_Line_Items имеют отношение "один-ко-многим". Каждый заказ может иметь более одного предмета в списке заказа, но каждая строка предмета соединена только с одним заказом.
-
Таблицы Products и Order_Line_Items также имеют отношение "один-ко-многим". Каждый продукт может иметь множество строк в предметах заказов, связанных с ним, но каждая строка в списке заказа ссылается только на один продукт.
Пример
В отношении "один-к-одному" запись в таблице Table A может иметь не более одной соответствующей записи в таблице Table B, и запись в таблице Table B может иметь не более соответствующей записи в таблице Table A. Этот тип отношения бесполезен и может потребовать некоторых изменений в дизайне вашей базы данных.
Отношение "один-к-одному" между таблицами бесполезно по ряду причин, информация в двух таблицах может быть просто сведена в одну таблицу. Например, предположим, что вы создали таблицу с именем Ping-Pong Players, для отслеживания соревнования по настольному теннису. Поскольку все игроки соревнования являются работниками Tasmanian Traders, такая таблица имеет отношение "один-к-одному" с таблицей Employee в баз данных Tasmanian Traders.
Поясняющие надписи у рисунка - слева направо и сверху вниз:
Каждый игрок в настольный теннис имеет одно поле соответствия в таблице Employee
Этот набор значений является поднабором поля Employee_id в таблице Employee
Вы могли бы добавить все поля из таблицы Ping-Pong Players в таблицу Employee. Но таблица Ping-Pong Players отслеживает одномоментное событие, и информация после завершения соревнования вам уже не нужна. Кроме того, не все работники играют в настольный теннис, так что если бы эти поля были в таблице Employee, они содержали бы пустые значения во многих записях. По этой причине потребовалось создать отдельную таблицу.
Когда вы определили необходимость наличия отношения "один-к-одному" в вашей базе данных, прежде всего посмотрите, а не сможете ли вы свести информацию в одну таблицу? Например, в таблице Employee один работник может иметь одного руководителя, который сам по себе тоже работник. Вы можете просто добавить поле для учетного номера руководителя. Если в дальнейшем потребуется свести такую информацию воедино, вы сможете использовать самообъединение (self-join) в вашем запросе или представлении. Вам, в описанном случае, не требуется отдельная таблица для разрешения отнощения "один-к-одному". Если вы не хотите делать этого по какой-то причине, то ниже показано - как установить отношение "один-к-одному" между двумя таблицами:
-
Если две таблицы имеют одного и того же субъекта, вы можете, вероятно, установить отношение с использованием одного и того же поля первичного ключа в обеих таблицах.
-
Если две таблицы имеют разных субъектов с разными первичными ключами, выберите одну из таблиц и положите ее первичный ключ в другую таблицу в качестве внешнего ключа.