Перейти к содержимому

Нарисуйте связи

Также доступно на 28 языках

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

A card model of a region from above: one distribution center joined by red threads to many small stores, and a second center with its own.
Изображение создано с помощью ИИ

Модуль 2 из 6 главы Моделирование данных ради смысла, глава 2 курса Data Architect. Каждый модуль самостоятелен. Назад: Прислушайтесь к существительным · Далее: Постройте логическую модель

Вопрос, на который отвечает этот модуль: Как превратить сущности-кандидаты в концептуальную модель данных?

Существительные уже на доске. Теперь я хочу разобраться с линиями между прямоугольниками, потому что набор сущностей — это еще не настоящая модель данных. Большая часть смысла живет именно в связях. Розничный партнер управляет распределительными центрами. Манифест перечисляет доставки. Доставка идет получателю. Бригада работает на грузовике. Каждое из этих утверждений что-то говорит мне о бизнесе, и каждое дает мне еще один вопрос.

Я по-прежнему не хочу говорить о Salesforce. Я не спрашиваю, должна ли это быть связь lookup или master-detail, не думаю о связующих объектах Salesforce (Salesforce Junction Object) и не решаю, что произойдет при удалении родительской записи. Я пытаюсь понять бизнес-связь.

Возьмем «розничный партнер управляет распределительными центрами». Звучит просто. Но у розничного партнера один DC или много? В Steve Trucking каждый розничный партнер держит региональный распределительный центр в каждом регионе, который обслуживает Steve Trucking, так что много. Может ли DC принадлежать больше чем одному розничному партнеру? Важен ли DC сам по себе, со своим персоналом и историей, или это просто адрес? Если розничный партнер уходит, нам все еще важны его DC?

Это не вопросы о Salesforce. Это бизнес-вопросы, и ответы на них могут полностью изменить модель.

Прежде чем идти глубже, я хочу дать вам язык, которым мы будем пользоваться на каждой диаграмме дальше. Он небольшой. Линия между двумя прямоугольниками говорит, что две вещи связаны, а отметки на ее концах говорят, сколько их.

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

Единственное правило, которое нужно запомнить: каждую отметку читают у того прямоугольника, которого она касается. Отметка ближе всего к прямоугольнику — это максимум; следующая за ней — минимум.

Как читать линии Легенда языка диаграмм курса. Простая линия без отметок означает, что две вещи связаны, но сколько — еще не решено. Одна черта на конце означает один; «воронья лапка» — много. Со второй отметкой для обязательности: две черты — ровно один; круг и черта — ноль или один; черта и «воронья лапка» — один или много; круг и «воронья лапка» — ноль или много. Каждая отметка читается у блока, которого она касается. НАЧАЛО: ПРОСТАЯ ЛИНИЯ Простая линия эти двое связаны; сколько — еще не решено ЗАТЕМ: ОДИН ИЛИ МНОГО Один одна черта (крест): один из блока, которого она касается Много «воронья лапка»: много из блока, которого она касается ЗАТЕМ: МОЖЕТ ЛИ БЫТЬ НОЛЬ? Ровно один две черты: минимум один, максимум один Ноль или один круг, затем черта: может еще не существовать Один или много черта, затем «воронья лапка»: хотя бы один Ноль или много круг, затем «воронья лапка»: ни одного — нормально Читайте каждый конец у блока, которого он касается: отметка ближе к блоку — максимум; следующая — минимум. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Прежде чем перейти к Steve Trucking, вернемся к собакам из модуля 1. У нас было пять прямоугольников: Владелец, Заводчик, Собака, Порода и Трюк. Теперь я спрашиваю о линиях между ними.

Один или много? У владельца может быть больше одной собаки; у Ana их две. У собаки один владелец, по крайней мере в нашей модели. Это «один ко многим»: черта у Владельца, «воронья лапка» у Собаки. С заводчиком та же форма: один заводчик выводит много собак.

Может ли не быть ни одного? Max взяли из приюта, так что заводчика у него нет вовсе. Конец у Заводчика получает кружок: у собаки ноль или один заводчик. А вот владелец есть у каждой собаки, так что этот конец получает вторую черту: ровно один.

Многие ко многим? Собака знает много трюков, а трюк, скажем «Сидеть», знают многие собаки. Это «многие ко многим», и именно здесь я иду искать скрытое понятие. Есть ли что-то, что относится к тому, что эта собака знает этот трюк? Насколько хорошо она его выполняет и когда выучила. У связи есть собственные факты, поэтому она становится самостоятельной вещью: Трюк собаки (Dog Trick), и в английском имени собака идет первой, потому что ведущая здесь именно собака.

Что означает каждая линия? Владелец владеет собакой. Заводчик ее выводит. Собака знает свои трюки. Дайте линиям имена, и любой сможет прочитать вам модель вслух.

Сейчас или во времени? Кому-нибудь важно, насколько хорошо Bella выполняет «Сидеть» сегодня, или то, как она к этому пришла? Если дрессировщик проверяет ее раз в несколько месяцев, каждая проверка — это отдельная запись: Оценка трюка (Trick Assessment) с датой, уровнем навыка и тем, кто проверял, под тем Трюком собаки, к которому она относится. Даже у связи, которая стала вещью, может быть своя история.

Породу я пока оставляю без связей. Это все тот же вопрос из модуля 1: отдельный прямоугольник или слово у собаки. Его решит модуль 4.

Модель собак со связями Семь блоков. Владелец владеет одной или многими собаками, и у каждой собаки ровно один владелец. Заводчик разводит одну или много собак, а у собаки ноль или один заводчик. Собака знает ноль или много трюков собаки, а трюк известен в нуле или многих трюках собаки; каждый трюк собаки — это одна собака и один трюк. Каждый трюк собаки проверяется в нуле или многих оценках трюка. Порода стоит отдельно, пока не связана. владеет разводит знает известен в проверяется в Владелец Заводчик Собака Порода Трюк собаки Трюк Оценка трюка ровно один ноль или один один или много ноль или много © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Каждый из этих вопросов точно так же работает и на настоящем бизнесе. Теперь зададим их Steve Trucking.

Одно из первых, что я хочу понять о связи, — ее кардинальность. Это термин из баз данных, а вопрос гораздо проще: сколько этих может быть связано со сколькими теми? На концептуальном уровне есть три базовых шаблона.

Это важный шаг процесса: взять два разных существительных и понять их связь. В большинстве случаев это «один ко многим» или «многие к одному». Только в редких случаях вы встретите «один к одному».

«Один ко многим» встречается повсюду. У одного розничного партнера много распределительных центров. Один манифест перечисляет много доставок. В одном маршруте около десяти остановок. Когда я слышу такие слова, я начинаю рисовать линию.

И теперь линия получает отметки. Каждый конец говорит, сколько может быть того прямоугольника, которого он касается: черта — один, «воронья лапка» — много. Читайте от каждого прямоугольника: у одного розничного партнера много распределительных центров.

Базовая связь, один ко многим Две пары блоков, каждая соединена линией в базовой нотации «воронья лапка». Один розничный партнер управляет многими распределительными центрами: одна черта у розничного партнера, «воронья лапка» у распределительного центра. Один манифест перечисляет много доставок, отмеченных так же. Каждый конец подписан словами. один: Розничный партнер много: Распределительные центры управляет один: Манифест много: Доставки перечисляет Розничный партнер Распределительный центр Манифест Доставка Одна черта — это один. «Воронья лапка» — это много. Читайте каждый конец от блока, которого он касается. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Связи «один к одному» существуют, но они редки, и когда я нахожу такую, я задаю несколько вопросов. Это действительно два разных существительных или одно и то же? Если разные, то в чем состоит связь «один к одному» между ними? И будет ли она всегда «один к одному» или только сейчас? Это ключевые вопросы при проектировании модели данных. Бригада и грузовик в любое отдельно взятое утро выглядят как «один к одному»: два человека, один грузовик, один маршрут. За месяц это уже не так, и именно там прячется самая интересная связь этой модели.

Связи «многие ко многим» особенно интересны, потому что часто говорят нам, что в бизнесе есть еще одно понятие. Может ли бригада со временем водить больше одного грузовика? Да. Может ли грузовик водить больше одной бригады? За время его службы — безусловно. Значит, между бригадами и грузовиками связь «многие ко многим». Но теперь я хочу знать больше. Важно ли бизнесу, когда у бригады был грузовик? Для какого маршрута, в какой день? Кто сделал назначение? Если сама связь несет информацию, которая нам важна, мы открыли еще одно бизнес-понятие: назначение бригады (Crew Assignment).

Это важная привычка моделирования. Иногда самое интересное — это не одно из существительных, которые мы услышали вначале. Оно прячется в связи между двумя существительными.

Это одно из мест, где я хочу, чтобы администраторы начали думать иначе. В Salesforce мы привыкли говорить об объектах и полях, поэтому легко считать прямоугольники главным, а линии — сантехникой. Но у самой связи может быть бизнес-смысл.

Возьмем доставку и продукты в ней. В одной доставке может быть несколько продуктов, например стиральная и сушильная машины. Один продукт, та же модель холодильника, встречается в тысячах доставок. Пока все просто. Но что если мне нужно знать, сколько единиц этого продукта в этой доставке, будет ли он устанавливаться и вывозится ли старый? Меня интересует уже не только связь между доставкой и продуктом. Меня интересует позиция доставки (Delivery Item), и это понятие заслуживает собственной сущности.

Если вы пришли из мира Salesforce, вы, возможно, уже думаете: «Это же связующий объект». Вы не ошибаетесь. Но я не хочу начинать с этого. Позиция доставки — это бизнес-понятие, прежде чем стать связующим объектом Salesforce. Сначала бизнес, потом реализация.

Несколько моих привычек для таких сущностей-связей, где бы их в итоге ни построили.

Дайте ей имя. Если у бизнеса уже есть для нее слово, используйте его. Если нет, возьмите имена двух родителей и сложите их. Подумайте о заказе и продукте. То, что между ними, — это Order Item (позиция заказа): заказ и позиция в заказе. Это дочерняя запись обоих родителей, и в Salesforce она может стать связующим объектом Salesforce. Но какое имя идет первым в английском названии: Item Order или Order Item? Посмотрите, что за данные у каждого родителя. Продукт — это справочные данные; заказ — транзакционные, и ведет именно заказ. Поэтому Order Item, или Order Product, так же как в Salesforce есть Opportunity Product. В Steve Trucking это позиция доставки (Delivery Item). Ведущее имя идет первым, и запись оказывается рядом со своим владельцем в любом списке, который вы когда-либо откроете.

Дайте ей собственный ключ. Соблазнительно сказать, что позиция доставки определяется доставкой плюс продуктом, и на этом остановиться. Это составной ключ, а с составными ключами работать гораздо труднее: каждая система, которая ссылается на запись, должна нести обе половины. Дайте сущности-связи собственный идентификатор, а «доставку плюс продукт» оставьте правилом уникальности, а не ID записи.

Два родителя, один потомок: дайте ему свой ключ Два родителя и один потомок. Доставка (ID записи — ID доставки; дата доставки, статус) содержит много позиций доставки. Продукт (ID записи — ID продукта; название, номер модели) входит во многие позиции доставки. Позиция доставки стоит между ними: у нее свой ID записи, ID позиции доставки, и она несет ID доставки и ID продукта своих двух родителей, плюс количество. Примечание внизу: ID доставки плюс ID продукта — это правило уникальности, а не ID записи. ТРАНЗАКЦИОННЫЕ ДАННЫЕ СПРАВОЧНЫЕ ДАННЫЕ содержит входит в Доставка ID доставки ID ЗАПИСИ Дата доставки Статус Позиция доставки ID позиции доставки ID ЗАПИСИ ID доставки ID продукта Количество Продукт ID продукта ID ЗАПИСИ Название Номер модели ID доставки + ID продукта: правило уникальности, а не ID записи. один много © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Обратите внимание, чего здесь нет: серийного номера. Количество и серийный номер не принадлежат одной записи. Количество считает несколько единиц чего-то; серийный номер идентифицирует одну конкретную вещь. Если бизнесу нужны серийные номера, каждая единица становится отдельной записью, и пять холодильников — это пять записей. Я не вижу сценария, где под позицией доставки была бы еще «деталь позиции доставки». Либо одно, либо другое: агрегат с количеством или одна запись на единицу. Здесь — количество.

Следите за атрибутами, которым нужна история. Некоторые сущности-связи после создания больше не меняются: стиральная машина в этой доставке так и остается стиральной машиной в этой доставке. Другие меняются постоянно. На этой неделе у бригады грузовик 117, а на следующей грузовик уходит другой бригаде. Когда связь меняется и бизнесу важно, какой она была раньше, сущности-связи нужны даты, и как раз за назначением бригады стоит следить. Спросите пораньше, важно ли бизнесу сейчас или во времени; мы вернемся к этому через минуту.

Смысл связи не исчерпывается кардинальностью

Заголовок раздела «Смысл связи не исчерпывается кардинальностью »

«Один ко многим» — этого мало, чтобы понять связь. Я также хочу знать, что связь означает.

У доставки есть место. Какое? Распределительный центр, из которого она выезжает? Дом получателя, куда она едет? Это не взаимозаменяемые вещи. У двух моделей могут быть абсолютно одинаковые прямоугольники и одинаковая кардинальность, а линии при этом означают совершенно разное. Вот почему хорошая модель — это не просто прямоугольники, соединенные линиями. Линиям нужны имена. Если я передам свою диаграмму другому архитектору, ему не придется гадать, что означает связь, а если я показываю ее бизнесу, на ней должен быть язык, который они узнают.

Линиям нужны названия Две панели, в каждой блок «Место» над блоком «Доставка», соединенные двумя линиями, каждая отмечена как одно место ко многим доставкам. В левой панели, «Без названий на линиях», две линии не подписаны и выглядят одинаково. В правой панели, «Подписанные линии», одна линия называется «уходит из», а другая «доставляется в». Те же блоки, та же кардинальность: только названия говорят, какая линия какая. БЕЗ НАЗВАНИЙ НА ЛИНИЯХ ПОДПИСАННЫЕ ЛИНИИ уходит из доставляется в Место Доставка Место Доставка Те же блоки, та же кардинальность. Только названия говорят, какая линия какая. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Внутри вопроса «сколько?» прячется еще один: обязательна ли связь? Может ли доставка существовать до того, как ее поставили в маршрут? Должна: манифест приходит за день-два до доставки, а маршруты окончательно составляются накануне вечером. Может ли доставка существовать без розничного партнера? Нет; каждая доставка приходит из манифеста партнера. Это и есть обязательность (optionality).

И снова не прыгайте сразу к флажку Required (обязательное) в Salesforce. Есть разница между «у каждой доставки должен быть розничный партнер» и «Salesforce должен требовать поле розничного партнера при создании записи». В итоге это может оказаться одной и той же реализацией, но это разные утверждения. Первое — бизнес-правило; второе — один из способов его обеспечить. Как архитекторы мы хотим понять первое, прежде чем решать второе.

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

Чтение обеих отметок на каждом конце Три блока в ряд: Манифест, Доставка, Остановка. Манифест перечисляет одну или много доставок, и каждая доставка находится ровно в одном манифесте: две черты у манифеста, «воронья лапка» и черта у доставки. На остановке оставляют ноль или много доставок, и каждая доставка относится к нулю или одной остановке: круг и «воронья лапка» у доставки, круг и черта у остановки. Ближе к блоку — максимум; следующая отметка — минимум. ровно один: Манифест один или много: Доставки перечисляет ноль или один: Остановка ноль или много: Доставки оставляет Манифест Доставка Остановка Ближе к блоку: максимум (один или много). Следующая отметка: минимум (черта — хотя бы один, круг — ноль). © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Вот вопрос, который я задаю очень часто: вы имеете в виду сейчас или во времени?

Бригада работает на грузовике. Прямо сейчас? Для сегодняшнего маршрута? Пока эти двое работают вместе? Это дает разные модели. Если бизнесу важно только, какой грузовик у бригады сегодня, модель может остаться простой. Если ему нужен каждый грузовик, который водила бригада, когда и на каком маршруте, нам нужна история, и то назначение бригады, которое мы открыли, внезапно становится очень важным.

Назначение бригады: какая бригада на каком грузовике Два родителя и один потомок. Бригада (ID записи — ID бригады; название, статус) работает во многих назначениях бригады. Грузовик (ID записи — ID грузовика, также известен по бортовому номеру; марка, модель, статус) используется во многих назначениях бригады. У каждого назначения бригады свой ID записи, оно несет ID бригады и ID грузовика, и дат в нем нет. Примечание внизу: какая бригада на каком грузовике, но не с какого времени. работает в используется в Бригада ID бригады ID ЗАПИСИ Название Статус Назначение бригады ID назначения бригады ID ЗАПИСИ ID бригады ID грузовика Грузовик ID грузовика ID ЗАПИСИ Бортовой номер ТАКЖЕ ИЗВЕСТЕН КАК Марка Модель Статус Какая бригада на каком грузовике, но не с какого времени. один много © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Это частый источник ошибок моделирования. Мы моделируем текущее состояние, потому что его мы видим на экране. А через несколько недель розничный партнер подает претензию о повреждении, и кто-то спрашивает: «Какая бригада была на грузовике 117 17 марта?» И мы обнаруживаем, что каждый раз при смене назначения перезаписывали ответ.

Один из способов сохранить эту историю — сделать назначение отдельной записью. Когда бригаду назначают, мы создаем назначение бригады с датой начала. Когда назначение меняется, мы ставим дату окончания в старой записи и создаем новую с собственной датой начала. Теперь на вопрос «у кого было это назначение полгода назад?» ответить просто, а не раскапывать историю полей или журнал изменений данных. А когда у бригады накопится много назначений, кто-нибудь спросит, какое из них текущее, поэтому я бы добавил еще флажок Active (активно).

Назначение бригады во времени: даты и флаг «Активно» Два родителя и один потомок, с датами. Бригада (ID записи — ID бригады; название, статус) работает во многих назначениях бригады. Грузовик (ID записи — ID грузовика, также известен по бортовому номеру; марка, модель, статус) используется во многих назначениях бригады. У каждого назначения бригады свой ID записи, оно несет ID бригады и ID грузовика, дату начала, дату окончания и флаг «Активно». Примечание внизу: каждое изменение завершает одно назначение и начинает следующее, а «Активно» отмечает текущее. работает в используется в Бригада ID бригады ID ЗАПИСИ Название Статус Назначение бригады ID назначения бригады ID ЗАПИСИ ID бригады ID грузовика Дата начала Дата окончания Активно Грузовик ID грузовика ID ЗАПИСИ Бортовой номер ТАКЖЕ ИЗВЕСТЕН КАК Марка Модель Статус Каждое изменение завершает одно назначение и начинает следующее. «Активно» отмечает текущее. один много © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Поэтому, когда мне рассказывают о связи, я не просто спрашиваю, как вещи связаны. Я спрашиваю: меняется ли эта связь и важна ли нам ее история?

Наша модель Steve Trucking становится полезной. Мы знаем, какие связи «один ко многим», где за «многие ко многим» прячется еще одно понятие, какие связи необязательны и какие меняются во времени. И мы до сих пор не создали ни одного объекта Salesforce. Это сделано намеренно.

Концептуальная модель после модулей 1 и 2 Концептуальная модель Steve Trucking, сгруппированная как данные о клиентах, транзакционные и справочные данные. Розничный партнер отправляет манифесты, которые перечисляют доставки, и управляет распределительными центрами. Каждая доставка уходит из распределительного центра, идет к получателю и содержит позиции доставки. У маршрутов есть остановки, на которых оставляют доставки. Назначение бригады связывает бригаду и грузовик с маршрутом, поэтому модель хранит, кто на каком грузовике ездил и когда. ДАННЫЕ О КЛИЕНТАХ ТРАНЗАКЦИОННЫЕ ДАННЫЕ СПРАВОЧНЫЕ ДАННЫЕ управляет отправляет перечисляет содержит уходит из доставляется в имеет оставляет водит работает в используется в Розничный партнер ритейлер, для которого мы доставляем Получатель тот, кто получает Манифест список доставок партнера Доставка один заказ одному получателю Позиция доставки что в грузовике Маршрут дневной рейс с остановками Остановка один адрес на маршруте Назначение бригады кто на каком грузовике ездил и когда Распределительный центр откуда уходят доставки Бригада два человека Грузовик машина ровно один ноль или один один или много ноль или много © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Эту диаграмму я должен иметь возможность положить перед бизнесом, и им не нужно знать Salesforce, чтобы сказать мне, верна ли она. Если они не могут ее проверить, потому что она полна терминологии Salesforce, значит, я слишком быстро перешел к физическому проектированию.

Прорабатывая связи в концептуальной модели, я решаю:

  • Как основные бизнес-сущности связаны друг с другом.
  • Является ли каждая связь «один к одному», «один ко многим» или «многие ко многим» — сейчас и во времени.
  • Обязательна ли каждая связь или необязательна.
  • Не прячется ли за связью «многие ко многим» значимое бизнес-понятие.
  • Меняется ли связь во времени и нужна ли нам ее история.

Lookup или master-detail, настройка связующего объекта, каскадное поведение и общий доступ — это физические решения; мы до них дойдем. Сейчас мы все еще отвечаем на более важный вопрос: как на самом деле работает этот бизнес? Когда мы поймем сущности и связи между ними, можно начать добавлять детали, которые их описывают. Тогда наша концептуальная модель и начинает превращаться в логическую модель данных.