Сказка о рыбаке и рыбке - строим модель данных

Аватар пользователя Markov

В рамках повышения технологической грамотности наших заказчиков - подготовили материал с пошаговым описанием создания модели данных по произведению А.С. Пушкина "Сказка о рыбаке и рыбке" (Золотая рыбка). Вдруг кому :)

Модель данных - ядро информационной системы

Давайте спроектируем модель данных на примере сказки (кейса) "О рыбаке и рыбке" Александра Сергеевича Пушкина

Модель данных - это система, отражающая ключевые сущности (объекты управления), их атрибуты и связи

Модель данных - логическое отражение конкретной управленческой (жизненной) ситуации (системы), которая рассматривается как совокупность объектов (сущностей) и их связей

Давайте разберем - какие ключевые сущности (объекты) мы видим?

Старик и Старуха - это люди. С точки зрения проектирования информационных систем это один объект (сущность) - человек. Однако, для наглядности визуализации и восприятия не погруженного в тему проектирования давайте создадим - два объекта

oldWoman - Старуха
oldMan - Старик

Движемся дальше. Тезис, что "Старуха своя" - толкуем таки, что Старик и Старуха сформировали ячейку общества - Family

Уже возникают интересные нюансы в проектировании и построении учетной информационной системы

Связь oldWoman - oldMan можно реализовать и без таблицы Family добавив Старику и Старухе по атрибуту (строке), содержащему ссылку на супруга spouseId и
указав взаимные связи между объектами

Такой подход с одной стороны - облегчит проектируемую систему (минус одна таблица), но с другой стороны и уменьшатся учетные возможности нашей информационной системы. Если Старик разведется со Старухой (удалится связь; сорри за спойлер), то мы потеряем данные, что они были женаты

Использование же таблицы Family (для учета семей), позволяет нам хранить в базе данных всю актуальную и архивную информацию о таком важно объекте управления, как - семья

Движемся дальше - фиксируем новые сущности (объекты)

See - море (которое "самое синие")
Land - суша, на которой живут Старик со Старухой

По сути - это два фундаментальных объекта управления в кейсе про "Золотую рыбку". Так что игнорирование данных объектов значительно снизит качество нашей будущей информационной системы

p.s. По уму See и Land это просто два разных представителя (конкретизация) такой сущности как Пространство (как Старик и Старуха - Человек), однако для простоты восприятия мы их различим

Они жили в ветхой землянке

Ровно тридцать лет и три года.

Старик ловил неводом рыбу,

Старуха пряла свою пряжу

 

Видим, что живут они не в чистом поле (Land), а в ветхой землянке - Building (называем так, потом что Building будет претерпевать значимые физические и информационные изменения; сорри за спойлер)

Стаж проживания в тридцать лет и три года можно отнести как к свойству Family, так и к связи Family - Building (Тонкое отличие: семье может быть 33 года, но проживали они в разных локациях). Однако не будем перегружать нашу модель в виду несущественности данной информации в нашем кейсе. Равно как и проигнорим пряжу, но не - невод

FishingTool - невод

Обратите внимание на связи:
Family связана (проживают) с Building, а Building в свою очередь находится (связано) на Land.
Ну а инвентарный номер fishingToolId логически закреплен за oldMan

Далее. От статической картинки дошли до процессов - "старик ловил"
Обратите внимание - бизнес-процесс "ловля неводом рыбы" (и его результат) пока никак не могут быть отражены в нашей модели данных. Пока у нас имеется только oldManfishingTool и связь между ними

 

Раз он в море закинул невод, —

Пришел невод с одною тиной.

Он в другой раз закинул невод,

Пришел невод с травой морскою

 

Заброс невода в море - транзакция

Дошли до более тонкой темы - как организовать учет процесса и его результата

FishingAct - один заброс невода в море

Обратите внимание на параметры (атрибуты) FishingAct:
id - уникальный идентификационный номер (уже случилось два FishingAct)
fisher_id - идентификационный номер рыбака (у нас рыбак один - oldMan, но в теории их может же быть много )
fishingTool_id - идентификационный номер FishingTool (у нас это - невод, но может быть и удочка и запрещенка же всякая с разными инвентарными номерами)
sea_id - идентификационный номер Sea, в котором рыбачим (предусмотрим возможность рыбалки в различных водоемах)
startTime - дата и время заброса FishingTool в Sea
endTime - дата и время извлечения FishingTool в Sea (по разнице endTime - startTime - можно вычислить продолжительность операции)
result - описание того бесполезного, что оказалось в FishingTool по результатам fishingAct (типа, трава морская и прочее)
isGoldFish - оказалась ли в FishingTool gGoldFish? (boolean)

Пока ход бизнес-процесса "ловля рыбы" и его результаты отражаются следующими данными в нашей информационной системе:

В третий раз закинул он невод, —

Пришел невод с одною рыбкой,

С непростою рыбкой, — золотою.

Как взмолится золотая рыбка!

Голосом молвит человечьим:

«Отпусти ты, старче, меня в море,

Дорогой за себя дам откуп:

Откуплюсь чем только пожелаешь.»

Удивился старик, испугался:

Он рыбачил тридцать лет и три года

И не слыхивал, чтоб рыба говорила.

Отпустил он рыбку золотую

И сказал ей ласковое слово:

«Бог с тобою, золотая рыбка!

Твоего мне откупа не надо;

Ступай себе в синее море,

Гуляй там себе на просторе».

Очевидно, что у нас возникает объект GoldFish. Но это еще не все!

Также возникает уже "невидимый" объект - обязательства GoldFish перед OldMan. И это будет отдельный объект, при чем он будет спроектирован в логике связей - "многие к многим" (Для сравнения - связь OldMan - FishingTool - "один ко многим" - у одного рыбака может быть несколько девайсов для рыбалки, но у каждого девайса будет ровно один хозяин-рыбак)

GoldFish_OldMan_commitment - таблица по учету обязательств GoldFish (могу быть разные) перед OldMan (тоже могут быть разные; отсюда и логика связи "многие-к-многим"). Таблица для учета "рыбьей дебиторки" OldMan
 

При этом пока эта таблица - пуста («Бог с тобою, золотая рыбка! Твоего мне откупа не надо; Ступай себе в синее море, Гуляй там себе на просторе»)

Обратите внимание, что мы установили связь между GoldFish и Sea (убираем риск, что oldMan может забыть к какому Sea потом идти с каждым новым Commitment; сорри - спойлер)

Также по уму напрашиваются два существенных атрибута для GoldFish_OldMan_Commitment - дата и время возникновения обязательства (дебиторки), и дата и время исполнения обязательства (погашения дебиторки), но мы опустим данные параметры для упрощения модели (к тому же - точные данные этих параметров - безвозвратно утеряны)

Также обращаем внимание, что дальше меняется структура бизнес-процессов. FishingAct более не происходит - вся дальнейшая движуха происходит на связях OldMan с OldWoman и GoldFish

Воротился старик ко старухе,

Рассказал ей великое чудо.

«Я сегодня поймал было рыбку,

Золотую рыбку, не простую;

По-нашему говорила рыбка,

Домой в море синее просилась,

Дорогою ценою откупалась:

Откупалась чем только пожелаю.

Не посмел я взять с нее выкуп;

Так пустил ее в синее море».

Старика старуха забранила:

«Дурачина ты, простофиля!

Не умел ты взять выкупа с рыбки!

Хоть бы взял ты с нее корыто,

Наше-то совсем раскололось».

Не будем плодить новую информационную сущность про "коммуникационный акт" между OldMan и OldWoman (кстати, до этого и не коммуницировали в нашей кейс) - с управленческой точки зрения для нас важен факт того, что OldWoman формулирует содержание GoldFish_OldMan_Commitment и ставит соответствующую задач OldMan

Теперь у нас в базе данных появляется следующая запись (по аналогии с FishingAct)

Вот пошел он к синему морю;

Видит, — море слегка разыгралось.

Стал он кликать золотую рыбку,

Приплыла к нему рыбка и спросила:

«Чего тебе надобно, старче?»

Ей с поклоном старик отвечает:

«Смилуйся, государыня рыбка,

Разбранила меня моя старуха,

Не дает старику мне покою:

Надобно ей новое корыто;

Наше-то совсем раскололось».

Отвечает золотая рыбка:

«Не печалься, ступай себе с богом,

Будет вам новое корыто».

Воротился старик ко старухе,

У старухи новое корыто.

Еще пуще старуха бранится:

«Дурачина ты, простофиля!

Выпросил, дурачина, корыто!

В корыте много ль корысти?

Воротись, дурачина, ты к рыбке;

Поклонись ей, выпроси уж избу».

Ускорим сказку и сразу отразим всю историю транзакций в таблице GoldFish_OldMan_commitment

isKorytoExist - true
isKorytoBroken - true

Теперь вспомним вот эту фразу:

"По сути - Sea и Land это два фундаментальных объекта управления в кейсе про "Золотую рыбку". Так что игнорирование данных объектов значительно снизит качество нашей будущей информационной системы"

 

В итоге у финальная модель данных кейса "Сказка о рыбаке и рыбке" сложилась следующим образом

Информация - это различие

 

Кант давно уже говорил, что этот кусок мела содержит миллион потенциальных фактов (Tatsachen) , но лишь очень немногие станут подлинными фактами, воздействуя на поведение сущностей, способных реагировать на факты. Вместо кантовых Tatsachen я бы употребил слово различия и заметил бы, что количество потенциальных различий в этом меле бесконечно, но очень немногие из них станут эффективными различиями (т.е. единицами информации) в умственном процессе некоторой большей сущности. Информация состоит из действенных различий.

Грегори Бейтсон, "Разум и природа. Неизбежное единство", 1979г.

 

Оригинал статьи на нашем сайте

Наш телеграм канал - "Восстание машин"

Авторство: 
Авторская работа / переводика

Комментарии

Аватар пользователя Nikmich19
Nikmich19(8 лет 4 месяца)

В многосвязной  матрице и достаточной её размерности для этой задачи  всё отразить - не судьба?

Аватар пользователя TOP
TOP(9 лет 1 месяц)

Раскладка - просто класс.smile9.gif

Мне бы такую работу, где можно рабочее время на такие шедевры тратить.smile3.gif

Аватар пользователя Markov
Markov(4 года 1 неделя)

Спасибо!
Дык - выходной же :)

Аватар пользователя Positron
Positron(5 лет 2 недели)

Предложена довольно кривая структура данных, наплодили лишних сущностей (таблиц) oldman & oldWoman это просто должна быть одна таблица Actor с дополнительным полем gender, туда же и рыбку можно записать с аттрибутом Type. Для людей это будет Human, для рыбки - Fish. land & sea тоже только одна таблица - с флагом isLand - Yes/No, Family нужна только если надо отслеживать историю разводов и свадеб старика и старухи или других персонажей, а если не надо, то просто добавить поле SpouseId в таблицу Actor (Персонажи). Ну и так далее..

При этом туда можно будет и внучку и жучку добавлять, а не плодить новые таблицы типа Zhychka & youngWoman.

Аватар пользователя Markov
Markov(4 года 1 неделя)

Согласен. Но в тексте же есть дисклеймер на эту тему (лишних таблиц :)

Задача - ликбез заказчиков на тему проектирования моделей данных (апчем они)

Двигаемся мелкими шагами - минимизируем риски срыва во фрустрацию целевой аудитории ;)

Аватар пользователя Советчик
Советчик(6 лет 6 месяцев)

Дык автор не знает, что такое "описание бизнес-процессов". Поэтому и рисует таблицы непонятно для чего.

Аватар пользователя Pavel-ch
Pavel-ch(9 лет 6 месяцев)

автор - таблица Family должна быть темпоральной. для записей должны быть поля: Дата начала/дата окончания

в варианте со сказкой - дата окончания пустая, но если в описании вы строите вариант, что может быть развод и повторная женитьба, то эти поля нужны - как вы актуальный брак рассчитаете ?

Аватар пользователя Markov
Markov(4 года 1 неделя)

Принимается-согласен ;)

Аватар пользователя Ответчик
Ответчик(6 лет 4 месяца)

Повторная женитьба - это уже другая семья, отдельная запись.

Аватар пользователя Doc_Mike
Doc_Mike(6 лет 10 месяцев)

Правильная модель предметной области это всё. За её пределами ничто.

Аватар пользователя ИЮЛь Майский
ИЮЛь Майский(8 лет 9 месяцев)

Почему на языке "партнёров"?

Аватар пользователя Markov
Markov(4 года 1 неделя)

Не понял вопроса

Аватар пользователя Советчик
Советчик(6 лет 6 месяцев)

Ну видимо предполагается, что современные СУБД позволяют создавать объекты не только на языке "вероятного противника"......

Аватар пользователя ИЮЛь Майский
ИЮЛь Майский(8 лет 9 месяцев)

Не понял вопроса

Ну integer, boolean -хрен с ними. Но OldMan и OldWomen -это для разбора сказок Киплинга&Со.

Аватар пользователя Аль Капоне
Аль Капоне(8 лет 9 месяцев)

Что Вы курите? Скажите, чую вещь забористая... 

Аватар пользователя ДК
ДК(12 лет 1 месяц)

у вас ошибка в генерализации данных. старик и старуха - абсолютно равны по структуре данных. это один класс. так что принимая христианские нормы мы можем parent id для старика делать null a для старухи - id старика. 

мало того, если сказка происходит в исламской стране, где количество жён может быть больше 1, эта модель работает без переделки. а вашу надо полностью выкидывать.

Аватар пользователя joho
joho(11 лет 1 месяц)

мало того, если сказка происходит в исламской стране, где количество жён может быть больше 1, эта модель работает без переделки. а вашу надо полностью выкидывать.

Эта модель и для посвящённого запада не работает. Вот Позитрон сразу отметил, надо в таблице Гендер прописывать. Правда поскромничал, не стал писать что он должен быть Int16, а то и Int32, что бы учесть все возможные варианты.

А может и вообще Float,

И все варианты людей сводить в один концлагерь в одну таблицу.

Аватар пользователя ДК
ДК(12 лет 1 месяц)

да. это я тоже заметил, также как избыточность моря и земли, которые всегда в единичном экземпляре. типичные константы или в крайнем случае таблица начальных установок. также как генерализация всех морских объектов в одну таблицу fishingResults к которой 1..n цепляется таблица свойств объектов, поскольку мы заранее не знаем ни объектов ни их свойств и добавлять будем по мере работы системы.

далее, у каждого хуман объекта должно быть состояние. у старика - рыбак (из заголовка сказки), у старухи - старуха, потом дворянка, потом царица и т.д. это такблица состояний.

из таблицы fishingAct убрать result, поскольку он будет определяться соотношением 1-0..n к таблице fishingResults.

далее нужна таблица встреч старика и старухи... тут много чего не так...

Аватар пользователя joho
joho(11 лет 1 месяц)

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

Аватар пользователя ДК
ДК(12 лет 1 месяц)

не факт что будет хуже. а дед хоть от этой бабки отдохнёт.

Аватар пользователя Поручик Арбузов
Поручик Арбузов(3 года 12 месяцев)

See - море (которое "самое синие")

Sea 

Аватар пользователя Фрол
Фрол(3 года 5 месяцев)

Не занимайтесь ерундой, вставайте под знамена графовых баз данных.

Аватар пользователя E_g_o_r
E_g_o_r(12 лет 5 месяцев)

Нда... Назвать этот опус мастер-классом это сильно... Это из серии "смотри,  дядя, как я могу" в исполнении ребенка, который уже многое в этой жизни успел познать))) 

Аватар пользователя Steel Rat
Steel Rat(6 лет 7 месяцев)

Занятно...

 

Столько коллег, и все не правы...

 

...одна я умная в белом пальто стою красивая.

 

ДБЛ БЛД