Отношение многие-ко-многим
Отношение многие-ко-многим
В этом интересном случае, показанном на рис. 17.2, наша модель данных показывает, что каждая строка в таблице TableA может иметь отношения со множеством строк таблицы TableB, и в то же время каждая строка в TableB может иметь множественные отношения со строками В TableA.
Рис. 17.2. Отношения многие-ко-многим
Это отношение использует условие, называемое циклической ссылкой. Предлагаемый внешний ключ в таблице TableB ссылается на первичный ключ таблицы TableA, что означает, что строка таблицы TableB не может быть создана, если в таблице TableA нет строки с соответствующим первичным ключом. В то же время, по этой же причине требуемая строка не может быть добавлена в таблицу TableA, если не существует соответствующего значения первичного ключа в таблице TableB.
Работа с циклическими ссылками
Если ваши структурные требования диктуют необходимость существования подобных циклических ссылок, это можно сделать обходным путем. Firebird позволяет внешнему ключу иметь значение NULL - если не указывать для столбца ограничение NOT NULL, - поскольку NULL означает отсутствие значения. Это не нарушит правила, по которому столбец внешнего ключа должен иметь соответствие в столбце родительской таблицы, на которую ссылается внешний ключ. Присваивая значение NULL внешнему ключу одной таблицы, вы можете добавлять строку в эту таблицу, создавая первичный ключ, требуемый в другой таблице:
CREATE TABLE TABLEA (
ID INTEGER NOT NULL,
. . .,
CONSTRAINT PK_TABLEA PRIMARY KEY (ID));
COMMIT;
CREATE TABLE TABLEB (
ID INTEGER NOT NULL,
. . . ,
CONSTRAINT PK_TABLEB PRIMARY KEY (ID));
COMMIT;
ALTER TABLE TABLEA
ADD CONSTRAINT FK_TABLEA_TABLEB
FOREIGN KEY(IDB) REFERENCES TABLEB(ID);
COMMIT;
ALTER TABLE TABLEB
ADD CONSTRAINT FK_TABLEB_TABLEA
FOREIGN KEY(IDA) REFERENCES TABLEA(ID);
COMMIT;
Вот этот прием:
INSERT INTO TABLEB(ID)
VALUES(1);
/* создает строку со значением NULL в столбце IDB */
COMMIT;
INSERT INTO TABLEA(ID, IDB)
VALUES(22, 1);
/* связывает с только что созданной строкой в TABLEB */
COMMIT;
UPDATE TABLEB
SET IDA = 22 WHERE ID = 1;
COMMIT;
Понятно, что эта модель не лишена потенциальных проблем. В большинстве систем ключи генерируются, а не поставляются приложениями. Чтобы обеспечить согласованность, описанная работа выполняется для всех клиентских приложений, добавляющих данные в эти таблицы, чтобы они обеспечивали значения обоих ключей для обеих таблиц в контексте одной транзакции. Выполнение единой операции в хранимой процедуре уменьшит зависимость кода приложения от такого отношения.
! ! !
ВНИМАНИЕ! На практике таблицы с отношением многие-ко-многим, реализованным циклически, очень сложно представить в приложениях с графическим интерфейсом.
. ! .
Использование таблиц пересечения
В большинстве случаев лучшей практикой разрешения отношения многие-ко-многим является добавление таблицы пересечения. Такая специальная структура имеет один внешний ключ для каждой таблицы в отношении многие-ко-многим. Ее собственный первичный ключ (или ограничение UNIQUE) состоит из двух внешних ключей. Две связанные этим отношением таблицы вовсе не имеют внешних ключей, связывающих одну с другой.
Такая реализация проста для использования в приложениях. Триггеры BEFORE INSERT (до добавления) и BEFORE UPDATE (до изменения) для обеих таблиц выполняют при необходимости добавление строки в таблицу пересечения. Рис. 17.3 иллюстрирует, как таблица пересечения реализует отношение многие-ко-многим.
Рис. 17.3. Реализация отношения многие-ко-многим
Вот как это может быть реализовано:
CREATE TABLE TABLEA (
ID INTEGER NOT NULL,
. . . ,
CONSTRAINT PK_TABLEA PRIMARY KEY (ID));
COMMIT;
CREATE TABLE TABLEB (
ID INTEGER NOT NULL,
CONSTRAINT PK_TABLEB PRIMARY KEY (ID));
COMMIT;
/**/
CREATE TABLE TABLEA_TABLEB (
IDA INTEGER NOT NULL,
IDB INTEGER NOT NULL,
CONSTRAINT PK_TABLEA_TABLEB
PRIMARY KEY (IDA, IDB));
COMMIT;
ALTER TABLE TABLEA_TABLEB
ADD CONSTRAINT FK_TABLEA FOREIGN KEY (IDA)
REFERENCES TABLEA,
ADD CONSTRAINT FK_TABLEB FOREIGN KEY (IDB)
REFERENCES TABLEB;
COMMIT;
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Отношение ассоциации
Отношение ассоциации Отношение ассоциации является одним из фундаментальных понятий в языке UML и в той или иной степени используется при построении всех графических моделей систем в форме канонических диаграмм.Применительно к диаграммам вариантов использования оно
Отношение расширения
Отношение расширения Отношение расширения определяет взаимосвязь экземпляров отдельного варианта использования с более общим вариантом, свойства которого определяются на основе способа совместного объединения данных экземпляров. В метамодели отношение расширения
Отношение включения
Отношение включения Отношение включения между двумя вариантами использования указывает, что некоторое заданное поведение для одного варианта использования включается в качестве составного компонента в последовательность поведения другого варианта использования.
Отношение зависимости
Отношение зависимости Отношение зависимости в общем случае указывает некоторое семантическое отношение между двумя элементами модели или двумя множествами таких элементов, которое не является отношением ассоциации, обобщения или реализации. Оно касается только самих
Сокет типа «один-ко-многим»
Сокет типа «один-ко-многим» Сокет типа «один-ко-многим» дает разработчику приложения возможность написать сервер, не использующий большого количества дескрипторов сокетов. Один дескриптор для такого сервера будет представлять несколько ассоциаций, подобно сокету UDP,
10.2. Потоковый эхо-сервер SCTP типа «один-ко-многим»: функция main
10.2. Потоковый эхо-сервер SCTP типа «один-ко-многим»: функция main Наши клиент и сервер SCTP вызывают функции в последовательности, представленной на рис. 9.2. Код последовательного сервера представлен в листинге 10.1[1].Листинг 10.1. Потоковый эхо-сервер SCTP//sctp/sctpserv01.c 1 #include "unp.h" 2 int 3
23.2. Сервер типа «один-ко-многим» с автоматическим закрытием
23.2. Сервер типа «один-ко-многим» с автоматическим закрытием Вспомните программу-сервер, которую мы написали в главе 10. Эта программа не отслеживала ассоциации. Сервер рассчитывал, что клиент самостоятельно закроет ассоциацию, удалив тем самым данные о ее состоянии.
Гениальные идеи приходят не в те головы, или Почему многим идеям так и не суждено реализоваться
Гениальные идеи приходят не в те головы, или Почему многим идеям так и не суждено реализоваться Как идеи превращаются в реальные бизнес-проекты?Самый простой ответ на этот сложный вопрос: никак! И с точки зрения вероятности этот ответ самый правильный. Потому что
12.3. Отношение сигнал-шум
12.3. Отношение сигнал-шум Следующее, что нам предстоит определить, - отношение сигнал/шум при выходной мощности 1 Вт и сопротивлении нагрузки 8 Ом. Для этого амплитуда выходного напряжения должна составлять 4 В, что соответствует амплитуде входного напряжения, равной
Отношения типа один-ко-многим
Отношения типа один-ко-многим Гораздо чаще, чем отношения типа один-к-одному, в базах данных используются отношения типа один-ко-многим, в которых каждая запись таблицы связана с одной или несколькими записями в другой таблице (или вообще не связана ни с какими записями). В
Отношения типа многие-ко-многим
Отношения типа многие-ко-многим Отношение типа многие-ко-многим по сравнению с отношением один-ко-многим идет еще дальше. В качестве классического примера отношения типа многие-ко-многим можно привести отношение между студентами и классами. Каждый студент может иметь
Алексей Пажитнов, создатель «Тетриса»: «Сегодня многие головоломки делают просто для умственно отсталых» Степан Чижов
Алексей Пажитнов, создатель «Тетриса»: «Сегодня многие головоломки делают просто для умственно отсталых» Степан Чижов Опубликовано 14 июня 2013 Так совпало, что 6 июня, в 29-й день рождения «Тетриса», у меня появилась возможность взять интервью у