Редактирование связей
Связи рисуются из контекстного меню холста, с панели инструментов холста, из Быстрого поиска или с помощью сочетания клавиш — см. Начало редактирования.
На этой странице описано, что можно делать с уже созданной связью, как окно «Сопоставить столбцы» завершает связь на столбцах, которые уже есть в дочерней таблице, и как именуются добавляемые ею столбцы внешнего ключа.
Удаление
Удалить связь можно через ее контекстное меню.

Сочетания клавиш для этого нет, поскольку связь не выделяется так, как таблица или заметка: клавиши Delete и Backspace, которые удаляют выделенное, никогда не удаляют связь отдельно — см. Удаление таблиц и заметок.
Кроме того, связи удаляются вместе с тем, что они соединяют: удаление таблицы удаляет все связи, которые к ней примыкают, а удаление столбца — все связи, в которых он используется.
Изменение типа
Тип меняется через пункт Relationship Type в контекстном меню связи.
Предлагаются четыре типа, а текущий отмечен галочкой:
- Zero One
- Zero N
- One Only
- One N

Это те же четыре типа, которые выбираются при создании связи, и у каждого из них есть свое сочетание клавиш — см. Начало редактирования.
ON DELETE и ON UPDATE
Задаются через пункты On Delete и On Update в контекстном меню связи, между пунктами Relationship Type и Map Columns.
В каждом из них одни и те же шесть пунктов, а текущий отмечен галочкой:
- Not set
- NO ACTION
- CASCADE
- SET NULL
- SET DEFAULT
- RESTRICT
Пункт Not set не записывает никакого предложения, поэтому действует поведение по умолчанию самой базы данных. У новой связи, нарисованной или созданной в окне «Сопоставить столбцы», оба действия изначально имеют значение Not set, а если позже выбрать Not set, действие сбрасывается.
Эти два действия независимы: изменение одного не затрагивает другое.
Заданные действия видны на линии связи — см. Как читать линию связи.
Связь, скопированная и вставленная или продублированная вместе со своими таблицами, сохраняет оба действия, а импорт Схемы SQL, DBML или AML переносит объявленные в файле действия — см. Импорт и экспорт файлов.

Любое действие можно выбрать независимо от базы данных.
Рядом с действием, которое выбранная база данных не включает в свою Схему SQL, отображается приглушенная пометка, например not in MySQL. У пункта Not set такой пометки никогда нет, а при смене базы данных пометки обновляются.
Действие с пометкой все равно хранится в связи: линия связи его показывает, а JSON, DBML и AML его сохраняют, но Схема SQL этой базы данных опускает это предложение, поэтому действует поведение базы данных по умолчанию.
Схема SQL записывает следующие действия и опускает остальные:
| База данных | ON DELETE | ON UPDATE |
|---|---|---|
| Databricks | NO ACTION | NO ACTION |
| MSSQL | NO ACTION, CASCADE, SET NULL, SET DEFAULT | NO ACTION, CASCADE, SET NULL, SET DEFAULT |
| MariaDB | NO ACTION, CASCADE, SET NULL, RESTRICT | NO ACTION, CASCADE, SET NULL, RESTRICT |
| MySQL | NO ACTION, CASCADE, SET NULL, RESTRICT | NO ACTION, CASCADE, SET NULL, RESTRICT |
| Oracle | CASCADE, SET NULL | нет |
| PostgreSQL | все пять | все пять |
| Snowflake | NO ACTION | NO ACTION |
| SQLite | все пять | все пять |
Схема SQL для Snowflake также записывает комментарий с названием каждого опущенного действия — см. Ссылочные действия.
Какие действия записывают целевые форматы ORM Генератора кода, зависит как от целевого формата, так и от выбранной базы данных — см. Генератор кода.
Сопоставление столбцов
Окно «Сопоставить столбцы» сопоставляет ключ родительской таблицы со столбцами дочерней таблицы, по одной строке на каждый столбец ключа.
Каждая строка либо использует столбец, который уже есть в дочерней таблице, либо добавляет новый столбец внешнего ключа, поэтому связь может завершаться на уже существующих столбцах.

Окно открывается двумя способами:
- С помощью кнопки
Map to existing columnsрядом с дочерней таблицей во время рисования связи — см. Создание связи. Тогда кнопкаMapдобавляет связь того типа, который рисуется. - Через пункт
Map Columnsв контекстном меню связи, чтобы изменить столбцы уже существующей связи. Тогда кнопкаSaveзаписывает изменение. В редакторе только для чтения этот пункт не отображается.
В подзаголовке окна указаны обе таблицы и тип связи, например users → posts · One N. Тип здесь отображается, но не меняется — для этого используйте Изменение типа.
Список References задает ключ, на который указывает связь: Primary Key со столбцами в порядке их следования в таблице, затем Unique: <column> для каждого столбца с параметром Unique. Он отображается, только если вариантов больше одного.
Уникальный индекс здесь не считается ключом, а столбец с параметром Unique, который составляет весь первичный ключ, не указывается дважды.
Выбор другого ключа перестраивает строки. Строка сохраняет выбранный столбец, пока этот столбец остается в дочерней таблице.
Под заголовками Referenced column и Foreign key column каждая строка показывает столбец ключа с его типом данных и список столбцов дочерней таблицы для сопоставления с ним:
- Пункт
Pick a columnоставляет строку пустой. - Пункт
New column: <name>добавляет новый столбец внешнего ключа. Показано имя, которое получит столбец, как описано в разделе Имена столбцов внешнего ключа, с нумерацией, учитывающей столбцы дочерней таблицы и другие строки, которые добавляют новый столбец. Этот пункт не предлагается, если имя оказалось бы пустым, как в случае ключа без имени. - Все столбцы дочерней таблицы в виде
<name> (<data type>). Столбец, выбранный в другой строке, отображается как<name> (<data type>) · in useи недоступен для выбора, поэтому две строки не могут использовать один столбец. Столбец, который уже использует другая связь, по-прежнему можно выбрать, поэтому один столбец, например общийtenant_id, может участвовать в нескольких связях.
В окне с кнопкой Map строка изначально заполнена, только если ровно у одного столбца дочерней таблицы имя без учета регистра совпадает с тем, которое получил бы новый столбец внешнего ключа для этой строки до какой-либо нумерации _2, например users_id для id таблицы users и member_id для member_id. Пока параметр Bracket имеет значение по умолчанию None, учитывается также имя, построенное из табличной части имени таблицы с указанием схемы, поэтому id таблицы public.users сопоставляется с public.users_id или users_id. Для ключа Unique учитывается и собственное имя столбца ключа, поэтому vin сопоставляется с vin. Во всех остальных строках изначально выбран пункт Pick a column.
В окне с кнопкой Save в каждой строке изначально выбран столбец, который связь использует сейчас. В обоих случаях выбор другого ключа в списке References заполняет пустые строки этого ключа по тем же именам.
Если тип данных выбранного столбца отличается от того, который родительский столбец передает внешнему ключу, об этом сообщает пометка под строкой.
Если Синхронизация типа данных в связях включена и у родительского столбца задан тип данных, в пометке отображается <column> becomes <type> с типом, который запишет сопоставление. Иначе в ней отображается Types differ: <parent type> and <child type>, а столбец сохраняет свой тип.
Кнопка Map или Save остается неактивной, пока что-то этому мешает, а надпись под строками сообщает, что именно:
Pick a foreign key column for every referenced column: одна из строк еще пуста.At least one column must reference a different column: рекурсивная связь, в которой каждая строка выбирает свой же родительский столбец.These columns are already linked by another relationship: другая связь между теми же двумя таблицами соединяет в точности эти столбцы.<parent> has no key to reference: в окне с кнопкойMapу родительской таблицы нет ни первичного ключа, ни столбца с параметромUnique.
Кнопка Save также остается неактивной, пока сопоставление не станет отличаться от текущего сопоставления связи.
В окне с кнопкой Save строка отображается как (removed), если ее столбец исчез из своей таблицы. Выберите другой столбец дочерней таблицы, а если исчез родительский столбец, выберите ключ в списке References. В окне с кнопкой Map строка, выбранный столбец которой удален, возвращается к Pick a column.
Для связи, родительские столбцы которой не совпадают в точности ни с одним из ключей родительской таблицы, окно открывается с дополнительным вариантом в конце списка References — Current columns (not a key), который оставляет эти столбцы как есть. Если у родительской таблицы вообще нет ключа, это единственный вариант, и список References не отображается.
В этом случае надпись The referenced columns are not a key of <parent> или, если у родительской таблицы вообще нет ключа, <parent> has no key to reference — это уведомление, а не ошибка: кнопка Save по-прежнему работает, поэтому можно изменить столбцы дочерней таблицы и сохранить ссылку.
Связь, два списка столбцов которой нельзя попарно сопоставить, например из-за разной длины, показывает строки (invalid), а кнопка Save остается неактивной, пока вы не выберете ключ в списке References или, если у родительской таблицы нет ключа, не добавите в нее первичный ключ или столбец с параметром Unique.
Пока окно открыто, оно следит за диаграммой, включая правки соавтора или агента для программирования, и сохраняет сделанный вами выбор.
Если тем временем меняются столбцы связи или ключ, с которым окно было открыто, в нем появляется надпись This relationship changed while the dialog was open.
Что записывают кнопки Map и Save:
- Кнопка
Mapдобавляет связь, у которойOn DeleteиOn Updateимеют значениеNot set. КнопкаSaveменяет только столбцы связи, направляя ее родительскую сторону на ключ, выбранный в спискеReferences, и сохраняет ее тип и действия ON DELETE и ON UPDATE. - Строка
New columnдобавляет столбец в конец дочерней таблицы, как и при рисовании:NOT NULL, с именем, образованным от ключа, с типом данных, значением по умолчанию и комментарием ключа — см. Идентифицирующие связи. - Выбранный столбец никогда не переименовывается, а его
Not Null, первичный ключ,Unique, значение по умолчанию и комментарий остаются как есть. Его тип данных меняется, только пока включен параметрRelationship DataType Syncи у родительского столбца есть тип данных: столбец получает тип, который родительский столбец передает внешнему ключу (для ключа типа serial — целочисленный тип, как и новый столбец), и изменение распространяется по связям так же, как при синхронизации. - Столбец, который сопоставление перестает использовать, остается в дочерней таблице и больше не помечается как внешний ключ, если на нем не завершается другая связь.
- Все, что записывает одно нажатие
MapилиSave, включая новые столбцы и изменения типов, составляет один шаг отмены.
Является ли связь идентифицирующей и как рисуется ее родительский конец, определяется по сопоставленным столбцам дочерней таблицы, как и для любой связи. Сопоставление со столбцами первичного ключа дочерней таблицы сразу делает связь идентифицирующей, а сопоставление со столбцом, допускающим NULL, ставит кружок на родительском конце — см. Как читать линию связи.
Внешний ключ в Схеме SQL ссылается на выбранный вами ключ, например REFERENCES vehicle (vin) для ключа Unique.
Если к моменту нажатия Map или Save диаграмма уже содержит это сопоставление, потому что соавтор или агент для программирования успел раньше, ничего не записывается.
Если она изменилась так, что сопоставление больше не подходит, ничего не записывается и появляется уведомление Couldn't map columns: the diagram changed.
Кнопка Cancel, кнопка x, клавиша Escape или щелчок по затемненной области вне окна закрывают его, ничего не записывая.
Затемненная область закрывает весь редактор, включая панель инструментов, а открытый Обозреватель остается открытым под ней.
Окно закрывается и при открытии Быстрого поиска, а также при уходе с вкладки ERD или переходе редактора в режим только для чтения.
Ctrl + F (Windows/Linux) или ⌘ + F (Mac) тоже закрывает окно и ставит курсор ввода в поле поиска на панели поиска Обозревателя, открывая Обозреватель, если он закрыт. В редакторе, слишком узком для отображения Обозревателя, это сочетание все равно закрывает окно, но вместо перемещения курсора ввода показывает уведомление — см. Открытие и закрытие.
Если одна из его таблиц или сама связь удаляется, пока окно открыто, оно закрывается с уведомлением, например Map Columns closed: the relationship was removed.
Пока окно открыто, сочетания клавиш холста, отмена и повтор, а также копирование и вставка ничего не делают.
У агента для программирования нет инструмента «Сопоставить столбцы». Он заново сопоставляет связь, удаляя ее инструментом erd_remove_relationship, который сохраняет ее столбцы внешнего ключа, и снова рисуя ее на существующих столбцах инструментом erd_link_columns, причем оба шага выполняются в одном вызове erd_batch — см. Инструменты.
Связи N:M
Поскольку редактор основан на физической модели, связь N:M выражается через связующую таблицу, как показано ниже.

Если в связующей таблице уже есть ключевые столбцы, например product_id и tag_id в таблице product_tags, рисуйте каждую связь с помощью кнопки Map to existing columns и выбирайте эти столбцы вместо добавления новых — см. Сопоставление столбцов. Если они составляют первичный ключ связующей таблицы, каждая связь сразу является идентифицирующей.
Импорт GraphQL, DBML или AML сам создает связующую таблицу.
Объявление связи многие-ко-многим импортируется как таблица с именем <left>_<right> и комментарием Junction table inferred from <left> <-> <right>, соединенная с обеими сторонами идентифицирующими связями.
См. Импорт и экспорт файлов.
Идентифицирующие связи
Рисование связи щелчком по дочерней таблице или с помощью кнопки Create new columns копирует каждый первичный ключ родительской таблицы в дочернюю таблицу как столбец внешнего ключа NOT NULL, поэтому новая связь изначально является неидентифицирующей.
Копия получает тип данных, значение по умолчанию и комментарий ключа, но не Unique и не Auto Increment, а ее имя образуется так, как описано в разделе Имена столбцов внешнего ключа.
Исключение по типу данных — ключ типа serial: его копия получает целочисленный тип, который хранит serial. Для любой базы данных smallserial и serial2 дают smallint, serial4 дает integer, а bigserial и serial8 дают bigint. Тип serial без суффикса дает integer для PostgreSQL и bigint unsigned для MySQL и MariaDB, а для любой другой базы данных остается serial.
Учитывается только полное имя типа без учета регистра, поэтому serial(4) копируется как есть. Тип, записанный прописными буквами, дает прописные буквы: SERIAL дает INTEGER для PostgreSQL. Столбец внешнего ключа, у которого в сохраненной диаграмме уже указан тип serial, сохраняет этот тип.
Чтобы сделать связь идентифицирующей, назначьте эти столбцы внешнего ключа в дочерней таблице первичными ключами: выделите их все и один раз нажмите Alt + K (Windows/Linux) или ⌥ + K (Mac) либо выберите пункт Primary Key в контекстном меню таблицы (когда выделено два столбца или больше, он называется Primary Key on selected columns) — см. Первичный ключ столбца.

Редактор сам поддерживает это соответствие.
Связь является идентифицирующей, пока каждый столбец на ее дочерней стороне является первичным ключом, и становится неидентифицирующей, как только один из них перестает им быть.
Имена столбцов внешнего ключа
При рисовании связи каждый добавляемый столбец внешнего ключа получает имя по родительскому ключу, который этот столбец копирует:
- Имя ключа из одного слова, например
id,IDилиuuid, получает спереди имя родительской таблицы и символ подчеркивания:idв таблицеproductsстановитсяproducts_id. - Имя ключа из нескольких слов, например
member_id,userIdилиUserID, остается без изменений. - Имя ключа из одного слова, которое без учета регистра совпадает с именем самой таблицы, тоже остается без изменений:
currencyв таблицеcurrencyостаетсяcurrency. Ключ, имя которого лишь содержит имя таблицы, все равно получает префикс:usernameв таблицеuserстановитсяuser_username.
Имя считается одним словом, если состоит только из букв и цифр без смены регистра.
Любой другой символ разделяет его, поэтому _id, order no и order-no — это несколько слов.
Разделяет его и смена регистра, которая определяется так же, как в camelCase: строчная буква, за которой следует прописная (userId), две прописные, за которыми следует строчная (IDCard, IDs), или буква письменности без регистра, например хангыля, каны или ханьских иероглифов, рядом с буквой, у которой есть регистр (회원ID).
Цифры не разделяют слово, поэтому id2 и SHA256 — это одно слово. Составное слово, записанное в одном регистре, тоже считается одним словом: memberid в таблице members становится members_memberid.
Имя таблицы используется так, как оно записано, за исключением пробелов по краям: регистр, внутренние пробелы и точки сохраняются, имя не приводится к единственному числу, а параметры Table Name Case и Column Name Case Генератора кода не играют роли. Таблица Users с ключом ID дает Users_ID.
Каждый столбец составного ключа именуется отдельно: таблица orders с ключом (tenant_id, id) добавляет tenant_id и orders_id.
Имя, которое без учета регистра уже есть в дочерней таблице, нумеруется суффиксами _2, _3 и т. д., причем берется первый свободный номер.
Вторая связь от таблицы users с ключом id к той же таблице добавляет users_id_2, а рекурсивная связь таблицы members с ключом member_id добавляет member_id_2.
Столбцы одного составного ключа нумеруются относительно друг друга так же, причем имя, оставленное без изменений, занимает свое место первым: таблица user с ключом (id, user_id) добавляет user_id для user_id и user_id_2 для id.
Если у родительской таблицы нет имени, имя ключа остается без изменений и при совпадении нумеруется, как и любое другое.
Ключ без имени дает столбец внешнего ключа без имени.
Это относится и к первичному ключу, который редактор добавляет в родительскую таблицу без ключа, если только вы не дадите ему имя до щелчка по дочерней таблице.
Имена задаются при рисовании связи. Последующее переименование родительской таблицы или ее ключа их не переименовывает.
Строки New column в окне «Сопоставить столбцы» именуются по тем же правилам, и список показывает каждое имя до того, как вы его выберете.
Связи, которые появляются вместе с уже существующими столбцами — при импорте, вставке, дублировании или сопоставлении существующих столбцов в окне «Сопоставить столбцы», — сохраняют имена этих столбцов.
Агент для программирования, добавляющий связь инструментом erd_add_relationship, получает те же имена и типы данных — см. Инструменты.
Как читать линию связи
- Идентифицирующая связь рисуется сплошной линией, неидентифицирующая — пунктирной.
- На дочернем конце находится символ кардинальности типа связи: кружок и черта у Zero One, кружок и воронья лапка у Zero N, две черты у One Only, а также черта и воронья лапка у One N.
- Родительский конец обозначается кружком и чертой, как у Zero One, если хотя бы один из столбцов внешнего ключа допускает
NULL, и двумя чертами, как у One Only, если все ониNOT NULL. - При наведении указателя на линию связи подсвечиваются она сама и соединяемые ею столбцы в обеих таблицах.

У связи, в которой задано ON DELETE или ON UPDATE, рядом с дочерним концом есть метка, например D:C U:R: D: и действие ON DELETE, затем U: и действие ON UPDATE, каждое — только если оно задано.
Действия сокращаются по образцу нотации erwin: C — CASCADE, R — RESTRICT, SN — SET NULL, SD — SET DEFAULT и NA — NO ACTION. У связи, в которой не задано ни одно из них, метки нет.
Метка располагается в стороне от дочерней таблицы: над линией, если линия связи выходит из левой или правой стороны этой таблицы, и справа от линии, если она выходит сверху или снизу, не перекрывая символ кардинальности.
Она рисуется цветом линии связи на небольшом прямоугольнике цвета фона холста и подсвечивается вместе со своей линией связи. Метки рисуются поверх всех линий связи, поэтому линия, пересекающая метку, проходит под ней.
Она показывает действие, сохраненное в связи, независимо от того, что записывает выбранная база данных, поэтому ON DELETE SET DEFAULT и в MySQL отображается как D:SD.
При наведении указателя на линию связи, в которой задано любое из действий, также появляется всплывающая подсказка с полными предложениями, по одному в строке, например ON DELETE CASCADE и ON UPDATE RESTRICT.
Всплывающая подсказка появляется, даже когда метка скрыта.
Переход к связи подсвечивает ее: выбор строки в папке Foreign Keys таблицы в Обозревателе или строки внешнего ключа в Просмотре различий рисует ее линию связи и метку тем же цветом, что и при наведении. В Просмотре различий подсвечивается линия связи на каждой стороне, где есть эта связь, поэтому добавленный внешний ключ подсвечивается только на стороне текущего документа, а удаленный — только на стороне сохраненного документа.
Переход выделяет только дочернюю таблицу с ее столбцами внешнего ключа, а ячейка в фокусе оказывается на первом из них; сама связь по-прежнему никогда не выделяется. О том, куда перемещается вид, см. Куда ведет переход.
Подсветка гаснет при следующем нажатии левой или правой кнопки мыши на холсте, будь то пустое место, таблица, заметка, группа таблиц или линия связи, даже если это нажатие оставляет выделение прежним. Ее гасит и переход к другой строке или совпадению поиска в Обозревателе, и переход к другой строке в Просмотре различий — на каждой стороне, к которой ведет эта строка.
Перемещение холста средней кнопкой мыши или инструментом «Рука» не гасит подсветку, как и сворачивание или разворачивание строки в Обозревателе или Просмотре различий, снятие выделения клавишей Escape и переход из Быстрого поиска или по кнопке карточки Flow со значком внешней ссылки.
Подсветка не сохраняется и не записывается в историю изменений, а соавторы ее не видят.
Скройте линии связи на холсте ERD с помощью параметра вида Relationship или только их метки с помощью параметра вида Referential Actions (он включен по умолчанию) — см. Параметры вида таблиц.
При масштабе 70% и ниже, когда таблицы сворачиваются до имени, метки не рисуются.
Экспорт изображения всегда рисуется в масштабе 100%, поэтому метки в нем рисуются при любом масштабе холста, если только их не скрывает параметр вида. Если параметр Background выключен, прямоугольник под каждой меткой тоже прозрачный.
Режим Flow на вкладке «Визуализация» рисует линии связи даже при выключенном параметре Relationship, каждую — одной плавной сплошной серой кривой с теми же обозначениями на концах, поэтому пунктирная линия, метки, всплывающая подсказка, подсветка после перехода и ортогональная прокладка, описанные на этой странице, относятся только к холсту ERD. Связь таблицы с самой собой и в режиме Flow огибает правый верхний угол таблицы — см. Прокладка линий связи.
Прокладка линий связи
Линии связи прокладываются ортогонально.
Маршрут огибает таблицы, которые находятся между двумя его концами, а не пересекает их, и его углы скруглены.
Каждый конец выходит из своей таблицы коротким прямым отрезком, прежде чем повернуть, поэтому две близко расположенные таблицы, концы линии связи которых находятся на одной прямой, соединяются одной прямой линией, а не обходным путем.
Маршруты, выходящие из одной стороны таблицы, разносятся по отдельным коридорам, чтобы не накладываться друг на друга.
Огибаются только таблицы: линия связи может пересекать заметку или рамку группы таблиц и рисуется над группами таблиц и под таблицами и заметками.
Связь таблицы с самой собой рисуется одной кривой вокруг правого верхнего угла таблицы: у родительского конца она выходит из верхней стороны, а у дочернего входит в правую.
Последующие рекурсивные связи той же таблицы располагаются снаружи первой, поэтому их кривые не пересекают ни друг друга, ни таблицу.
Настраивать здесь нечего.
Маршруты автоматически пересчитываются всякий раз, когда что-либо на холсте перемещается или меняет размер, поэтому их никогда не нужно править вручную.
