Что такое сущность в программировании
Перейти к содержимому

Что такое сущность в программировании

  • автор:

Что такое сущность в программировании

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

Основные понятия и определения

  • сущность
  • связь
  • атрибут
  • модель данных

Каждый экземпляр сущности должен быть отличим от любого другого экземпляра той же сущности.

  • Один к одному
  • Один ко многим
  • Многие к одному
  • Многие ко многим

Пример связи «один ко многим» — Фамилия — Человек. Фамилия Иванов одна, а людей с такой фамилией — много.
Пример связи «многие ко многим» — Врачи — Пациенты.
Рассмотрим пример связи «многие к одному» необязательную с одного конца. Связь между сущностями БИЛЕТ и ПАССАЖИР связывает билеты и пассажиров. При том конец сущности с именем «для» позволяет связывать с одним пассажиром более одного билета, причем каждый билет должен быть связан с каким-либо пассажиром. Конец сущности с именем «имеет» означает, что каждый билет может принадлежать только одному пассажиру, причем пассажир не обязан иметь хотя бы один билет.

  • Каждый БИЛЕТ предназначен для одного и только одного ПАССАЖИРА;
  • Каждый ПАССАЖИР может иметь один или более БИЛЕТОВ.

Атрибутом сущности является любая деталь, которая служит для уточнения, идентификации, классификации, числовой характеристики или выражения состояния сущности. Имена атрибутов заносятся в прямоугольник, изображающий сущность, под именем сущности и изображаются малыми буквами, возможно, с примерами.

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

Модель данных — способ отражения сущностей, атрибутов сущностей и их связей.

Введение

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

Ниже перечислены основные предложения логического определения данных:

CREATE TABLE CREATE VIEW CREATE INDEX
ALTER TABLE
DROP TABLE DROP VIEW DROP INDEX

В курсе лекций также рассматриваются различные предложения SQL, такие как DELETE, INSERT, UPDATE. А также, самое главное предложение SQL — SELECT.

Базовые таблицы

Базовая таблица — (важный) специальный случай более общего понятия «таблица». Поэтому давайте начнем с того, что несколько уточним это более общее понятие.

Определение

  1. Строка заголовков столбцов специфицирует один или более столбцов, задавая наряду с прочим тип данных для каждого из них;
  2. Каждая строка данных содержит в точности одно значение данных для каждого из столбцов, специфицированных в строке заголовков столбцов. Кроме того, все значения в заданном столбце имеют один и тот же тип, а именно: тип данных, специфицированный для этого столбца в строке заголовков столбцов.
  1. Отметим, что в этом определении нет никакого упоминания об упорядочении строк. Строго говоря, строки реляционной таблицы считаются неупорядоченными. (Отношение — это математическое множество — множество строк, а множество в математике не обладает каким-либо упорядочением.) Как мы увидим, можно, однако, задавать некоторый порядок для этих строк, когда осуществляется их выборка в ответ на запрос, но такое упорядочение следует считать не чем иным, как удобством для пользователя. Оно не существенно для понятия таблицы.
  2. В отличие от строк столбцы таблицы предполагаются упорядоченными слева направо. (По крайней мере, они считаются упорядоченными таким образом в большинстве систем). Однако на практике существует очень немного ситуаций, когда такое упорядочение слева направо является существенным. Подобных ситуаций можно избегать при некоторой дисциплине, и это рекомендуется делать, как будет показано позднее.

Предложение CREATE TABLE


Теперь мы подробно обсудим предложение CREATE TABLE. Это предложение имеет следующий общий формат:

CREATE TABLE имя_базовой_таблицы (определение_столбца [, определение_столбца] . ) [другие параметры];

Здесь «определение_столбца» в свою очередь имеет формат:

имя_столбца тип_данных [NOT NULL]

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

Рассмотрим пример предложения CREATE TABLE для таблицы Поставщики:

create table Поставщики (Номер_Поставщика int, Фамилия char(20), Город char (15));

Результат этого предложения состоит в том, что создается новая пустая базовая таблица, названная xyz. Поставщики, где xyz-имя, под которым известен системе пользователь, издающий предложение CREATE TABLE. В системный каталог при этом помещается статья, описывающая эту таблицу. Пользователь xyz может обращаться к таблице по ее полному имени xyz. Поставщики или по сокращенному имени Поставщики. Другие пользователи должны обращаться к ней только по ее полному имени. Данная таблица состоит из трёх столбцов с именами xyz.Поставщики.НОМЕР_ПОСТАВЩИКА, xyz.Поставщики.ФАМИЛИЯ xyz.Поставщики.ГОРОД, имеющих указанные в определении типы данных. (Типы данных будут рассматриваться ниже). Пользователь xyz может обращаться к этим столбцам по их полным или по сокращенным именам: Поставщики.HOMEP-ПОСТАВЩИКА, Поставщики.ФАМИЛИЯ и Поставщики.ГОРОД. Другие пользователи должны применять только полные имена столбцов. Заметим, однако, что независимо от того, включается ли в имя часть «xyz», часть «Поставщики» может быть опущена, если это не приводит к двусмысленности, но ее включение никогда не является ошибкой. Вообще относительно имен справедливы следующие правила. Имена пользователей, например xyz, являются уникальными во всей системе. Имена таблиц (неуточненные) уникальны для пользователя. Имена столбцов (неуточненные) уникальны для таблицы.

Кроме того, в качестве имен не могут использоваться ключевые слова языка SQL (CREATE, TABLE, SELECT и т. д.). Первая литера любого имени должна быть буквой ( А-Z или одной из специальных литер #, $, @), а остальные литеры — буквами, цифрами (0-9) или знаком подчеркивания. Имена таблиц и столбцов могут содержать максимум 18 литер, а имена пользователей — максимум 8 литер. Под «таблицей» здесь понимаются как базовые таблицы, так и представления. Таким образом, представление не может иметь такое же имя, как и базовая таблица. После того как таблица создана, в нее могут быть введены данные с помощью предложения INSERT (вставить) языка SQL. Вариант заполненной таблицы Поставщики.

Типы данных

INTEGER двоичное целое число, занимающее полное машинное слово, 31 бит со знаком
SMALLINT двоичное целое число, занимающее полуслово, 15 бит со знаком
DECIMAL (p,q) упакованное десятичное число, включающее р цифр и знак (0 254, то поле является и «длинным полем», и объектом строгих ограничений. Длинные поля предназначены для того, чтобы иметь дело с данными в свободном формате, такими, как длинные текстовые строки, а не с простыми форматизированными данными, например номер поставщика или объем поставки. По существу, единственной операцией, в которой могут в качестве операндов использоваться такие поля, является операция присваивания базе данных (INSERT или UPDATE) либо из базы данных (SELECT). He допускаются какие-либо операции, которые предполагают сравнение с длинным полем. Поэтому, например, длинные поля не могут быть индексированными, на них нельзя ссылаться во фразах WHERE, GROUP BY или ORDER BY и т. п.)

Числовые типы
Числовые типы позволяют хранить числовые данные (целые числа, действительные числа и числа с плавающей точкой), представлять величины и выполнять вычисления.

BINARY-INTEGER

Тип данных BINARY-INTEGER используется для представления целых чисел со знаком. Диапазон его значений: -2147483647 ..2147483647. Значения BINARY-INTEGER требуют для своего хранения меньше памяти, чем значения типа NUMBER.

Тип данных NUMBER используется для представления чисел с фиксированной или плавающей точкой практически любого размера. Диапазон абсолютной величины его значений: 1 .0Е-130 .. 9.99Е125. Для значений этого типа вы можете указать также точность, т.е. общее число значащих цифр, и масштаб, который определяет, с какого разряда после десятичной точки начинается округление. Спецификация типа имеет следующий синтаксис:

NUMBER[(точность, масштаб)]

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

NUMBER(точность, масштаб)

При объявлении переменной, предназначенной для хранения чисел с плавающей точкой, нельзя указывать точность или масштаб, поскольку десятичная точка «плавает» (и может занять любую позицию); в этом случае спецификация типа должна иметь следующую форму:

NUMBER

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

NUMBER(точность) -- то же самое, что и NUMBER(точность,0)

Для указания точности и масштаба нельзя использовать константы или переменные — они должны быть заданы целочисленными литералами. Максимальная точность чисел типа NUMBER — 38 десятичных разрядов. Если точность не указана, по умолчанию она будет установлена равной 38 или максимально возможному для вашей системы значению, если оно меньше 38.
Масштаб может быть задан любым числом в диапазоне от -84 до 127 и определяет, с какого разряда после десятичной точки начинается округление. Например, при масштабе, равном 2, округление будет производиться до ближайших сотых (вместо 3.456 будет 3.46). Масштаб может быть отрицательным, что вызовет округление в разрядах слева от десятичной точки. Например, при масштабе, равном -3, округление будет производиться до ближайших тысяч (вместо 3456 будет 3000). При масштабе, равном нулю, округление происходит до ближайшего целого. Если масштаб не указан, по умолчанию он принимается равным нулю.

INTEGER используется при объявлении переменных, предназначенных для хранения целых чисел с максимальной точностью до 38 десятичных цифр.

Символьные типы

Символьные типы позволяют хранить алфавитно-цифровые данные, представлять слова и текст, а также оперировать символьными строками.

Тип данных CHAR используется для представления символьных данных фиксированной длины. Внутреннее представление символов зависит от установленной кодировки базы данных, которая может быть, например, 7-битовым кодом ASCII или кодовой страницей 500 для кода EBCDIC.
Спецификация типа данных CHAR имеет необязательный параметр, который позволяет указать максимальную длину до 32767 байтов. Спецификация имеет следующий синтаксис:

CHAR[(максимальная длина)]

Максимальную длину нельзя задавать константой или переменной -можно использовать только целочисленный литерал со значением в диапазоне 1 .. 32767.
Если максимальная длина не указана, по умолчанию она устанавливается равной 1. Обратите внимание, что максимальная длина переменной указывается в байтах, а не в символах. Таким образом, если переменная со спецификацией char (n) используется для хранения многобайтовых символов, то ее максимальная длина в символах будет меньше n. В базе данных максимальный размер столбца типа char не может превышать 2000 байтов. Поэтому в столбец типа char невозможно поместить значение типа char, если оно длиннее 2000 байтов.
Любое значение типа char (n) можно поместить в столбец базы данных, имеющий тип long, поскольку такой столбец может содержать значения с длиной до 2147483647 байтов, т.е. 2 гигабайтов. Однако вы не можете выбрать в переменную типа char (n) значение из столбца типа long, если оно длиннее 32767 байтов.

Тип данных VARCHAR используется для представления символьных данных переменной длины. Внутреннее представление символов зависит от установленной кодировки базы данных, которая может быть, например, 7-битовым кодом ASCII или кодовой страницей 500 для кода EBCDIC.
Спецификация типа данных VARCHAR имеет обязательный параметр, который позволяет указать максимальную длину до 32767 байтов. Спецификация имеет следующий синтаксис:

VARCHAR(максимальная длина)

Максимальную длину нельзя задавать константой или переменной — можно использовать только целочисленный литерал со значением в диапазоне 1 .. 32767.
Обратите внимание, что максимальная длина переменной указывается в байтах, а не в символах. Таким образом, если переменная со спецификацией VARCHAR (n) используется для хранения многобайтовых символов, то ее максимальная длина в символах будет меньше n. В базе данных максимальный размер столбца типа VARCHAR не может превышать 4000 байтов. Поэтому в столбец типа VARCHAR невозможно поместить значение типа VARCHAR, если оно длиннее 4000 байтов.
Любое значение типа VARCHAR (n) можно поместить в столбец базы данных, имеющий тип LONG, поскольку такой столбец может содержать значения с длиной до 2147483647 байтов. Однако вы не можете выбрать в переменную типа VARCHAR (n) значение из столбца типа LONG, если оно длиннее 32767 байтов.

Другие типы

Тип данных boolean используется для представления булевых значений true и false, а также пустого значения null, которое применяется в случаях, когда настоящее значение отсутствует, неизвестно или неприменимо. К переменным типа boolean могут применяться только логические операции.
Спецификация типа данных boolean не имеет никаких параметров. Переменной типа boolean могут быть присвоены только значения true и false, а также пустое значение null. Значения true и false нельзя поместить в столбец базы данных. Вы не можете также выбрать значение из столбца базы данных в переменную типа boolean.

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

Целочисленная записывается как десятичное целое число со знаком или без знака, без десятичной точки; примеры: 4 -95 +364 0
Десятичная записывается как десятичное число со знаком или без знака, с десятичной точкой; примеры: 4,0 -95.7 +364.05 0.007
С плавающей точкой записывается как десятичная константа, за которой следует буква Е с последующей целочисленной константой; примеры: 4ЕЗ -95.7Е46 +364Е-5 0.7Е1 (примечание: выражение хЕу представляет значение х*(10**у))
Строковая записывается либо как строка литер, заключенная в одиночные кавычки, либо как строка пар шестнадцатиричных цифр, представляющих рассматриваемые литеры в коде EBCDIC, заключенная в одиночные кавычки, которой предшествует буква X; примеры: ‘123 Main St.’ ‘PIG’ X’FlF2F340D481899540E2A34B’ X’D7C9C7′ (первый и третий примеры представляют одно и то же значение, так же как второй и четвертый)

Предложение ALTER TABLE


Точно так же, как в любое время можно с помощью предложения CREATE TABLE создать новую базовую таблицу, можно также в любое время изменить существующую базовую таблицу, добавляя к ней справа новый столбец. Для этого используется предложение ALTER TABLE:

ALTER TABLE имя_базовой_таблицы ADD имя_столбца тип_данных ;
ALTER TABLE Поставщики ADD СКИДКА SMALLINT;

Это предложение добавляет к таблице Поставщики столбец СКИДКА. Все существующие записи таблицы Поставщики расширяются с трёх значений полей данных до четырёх, и во всех случаях новое пятое поле принимает неопределенное значение. Спецификация NOT NULL в предложении ALTER TABLE не допускается. Заметим, между прочим, что только что описанное расширение существующих записей, не означает, что в это время физически обновляются записи в базе данных. Изменяется лишь хранимое в каталоге описание таблицы. Отдельные записи физически не изменяются до тех пор, пока они в следующий раз не станут целевыми для предложения UPDATE языка SQL.

Предложение DROP TABLE


Существующую базовую таблицу можно в любое время уничтожить с помощью предложения:

DROP TABLE имя-базовой-таблицы;

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

В дальнейших примерах будет использованы следующие таблицы:

Номер_Поставщика Фамилия Город
1 Смит Лондон
2 Джонс Париж
3 Блейк Париж
4 Кларк Лондон
5 Адамс Атенс
Номер_Поставщика Название Вес Цвет
1 гайка 12 красный
1 болт 15 зеленый
3 винт 17 голубой
4 винт 15 красный
4 шуруп 20 голубой

Понятие «сущность»

Например, во введении в управление потоком задач говорю: «вычленяю главную сущность менеджмента – «ЗАДАЧУ», даю описание этой сущности».

Слово «сущность» звучит постоянно. Даже название настоящей рубрики блога звучит так: «Главная сущность менеджмента – «задача».

Поэтому прежде, чем описывать «задачу», как главную сущность менеджмента, считаю необходимым разъяснить понятие сущности.

Иначе возникнет недопонимание этого термина. В то время как на нём базируется многое в управлении потоком задач.

Итак, что такое сущность?

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

Атрибут сущности – это некоторое поименованное свойство (черта, характеристика, признак) сущности.

У сущности может быть несколько атрибутов.

Сущность – это тип объектов, а не конкретный объект. Когда мы не знаем конкретные значения атрибутов какого-то объекта, мы обозначаем его как тип.

Например, если мы не знаем чьё-либо ФИО, год рождения, то мы говорим: «я видел какого-то человека», а иногда даже так: «какой-то тип, проходил мимо». Если бы мы знали такие значения атрибутов, как ФИО, год рождения, то, например, мы бы сказали так: «я видел Петрова Ивана Васильевича моего соседа», или «Сидоров Александр Владимирович проходил мимо». То есть мы бы обозначили его как конкретный объект.

Отсюда, «человек» — это тип и значит сущность, а Мотаев Александр Александрович 1976 года рождения, автор настоящего блога – это конкретный объект. «Автомобиль» — это тип и поэтому сущность, а чёрная Тойота Лэнд Крузер Прадо 2010 года выпуска с госномером а555аа – это конкретный объект. «Город» — это тип и, следовательно, сущность, а «Екатеринбург областной центр Свердловской области» — это конкретный объект.

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

Например, имеем какое-то живое существо. Его границы обозначены пределами его физического биологического тела.

Если данное живое существо обладает такой отличительной особенностью как «разум», который придаёт ему способность мыслить всеобще, осознанно, способность анализа, абстрагирования и обобщения, то на 99,9% — это «человек», а не «обезьяна» и не «медведь».

Предназначение человека – созидать наследие, используя разум. Любой тип, который имеет разум, то есть является сущностью «человек», обладает возможностью (способностью) созидать наследие, и по идее должен это делать. В этом его смысл бытия – функциональное предназначение. [2]

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

Если указанное транспортное средство имеет возможность перемещать людей и/или грузы в произвольном направлении при наличии дороги, то скорее всего – это «автомобиль», а не «поезд» или не «самолёт», или не «пароход».

Его предназначение – перемещать людей и/или грузы по земле из одной точки в другую в произвольном направлении, где есть пригодная дорога.

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

То есть у сущности нет значений атрибутов, а только их названия. А у конкретного объекта должны быть ещё и конкретные уникальные значения атрибутов.

Названия атрибутов, присущие типу, наравне с функциональностью типа, позволяют идентифицировать и отделить в пространстве и времени один тип от другого. В том числе на логическом уровне. Не путать их между собой.

Например, сущностью является такой тип объектов как «смартфон». Чтобы идентифицировать и отсортировать «смартфон» от устройств других типов, у него есть список следующих названий атрибутов, без их значений: сенсорная панель, серийный номер, модель, операционная система, ЦП, ОЗУ, GPS, Wi-Fi, Bluethooth и т.д.

Всё, что обладает совокупностью этих названий атрибутов – есть сущность «смартфон». То есть любое устройство, которое имеет сенсорную панель, серийный номер, модель, операционную систему, ЦП, ОЗУ, GPS, Wi-Fi, Bluethooth и при этом обладает такой функциональностью, как «осуществление звонков и отправление сообщений из любого местонахождения», является сущностью «смартфон».

В отличие от сущности каждый конкретный объект, чтобы его идентифицировать и отделить от других конкретных объектов, в том числе от других сущностей, должен обладать не только названиями атрибутов, но и своими уникальными конкретными ЗНАЧЕНИЯМИ атрибутов. Например, мой смартфон имеет следующие уникальные значения атрибутов:

Таблица: Пример названий и значений атрибутов моего смартфона

Пример названий и значений атрибутов моего смартфона

Только по совокупности этих названий и конкретных значений атрибутов можно чётко идентифицировать конкретный объект – мой смартфон, являющийся сущностью «смартфон». Только по ним его можно однозначно отсортировать от других смартфонов и в пространстве, и во времени, и на логическом уровне, например, при занесении его в базу данных.

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

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

Например, атрибут «сенсорная панель» универсален для любого устройства, являющегося смартфоном. Все смартфоны имеют сенсорную панель. Всё что не имеет сенсорную панель – не смартфон. То же можно сказать об атрибуте «GPS».

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

К примеру, нет смысла прикручивать к «смартфону» такой атрибут, как «способность отблескивать в свете лампочки». Этот атрибут никакого значения и важности для идентификации сущности не имеет и ничего не даёт для этого. Никак не отражает содержание смартфона и не указывает на его «природу». Многое может отблескивать в свете лампочки.

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

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

Сущность – это тип, у которого есть срок «жизни». Всё течёт, всё меняется. Одни сущности исчезают, другие появляются.

Например, были «динозавры» — вымерли. Появились «млекопитающие». У любой сущности есть срок жизни. Пока сущность нужна и применяется, она «живёт».

Когда отпадает необходимость или возможность в существовании этой сущности, она прекращает своё бытие. Её срок «жизни» заканчивается.

Например, когда-то была популярна такая сущность, как «стационарный телефон», сейчас её замещает более продвинутая сущность «смартфон». «Стационарный телефон» постепенно умирает. А «смартфон» процветает.

Сущность – это тип, идентифицируемый по необходимому и достаточному количеству функций и названий атрибутов. То есть, чтобы чётко отделить одну сущность от другой, нужно иметь минимально необходимый и максимально достаточный набор функций и названий атрибутов.

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

В частности, чтобы чётко отделить «смартфон» от «планшета», нам необходим минимальный перечень функций и названий атрибутов. Думаю, если мы укажем функцию: «осуществление звонков и отправление сообщений из любого местонахождения» и следующий перечень названий атрибутов: сенсорная панель, серийный номер, модель, операционная система, ЦП, ОЗУ, GPS, Wi-Fi, Bluethooth, то этого скорее всего будет достаточно для того, чтобы определить (угадать), что это сущность «смартфон».

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

Сущность – это тип, по наличию функций и названий атрибутов которого неопределённое количество конкретных объектов относится или не относится к этому типу. Это означает, что если какой-то конкретный объект имеет основную функцию: «осуществление звонков и отправление сообщений из любого местонахождения» и при этому у него есть совокупность всех следующих названий атрибутов: сенсорная панель, серийный номер, модель, операционная система, ЦП, ОЗУ, GPS, Wi-Fi, Bluethooth, то этот объект почти наверняка является сущностью «смартфон».

При этом такой сущностью будет неограниченное, неопределенное и любое количество конкретных объектов, имеющих указанные функции и названия атрибутов. Эта множественность является одной из ключевых характеристик сущности. Только то, что может напрямую или опосредованно (через подсущность) объединять под собой большое (более одного) и постоянно расширяющееся множество конкретных объектов, может являться сущностью. Нет смысла выделять отдельную сущность, для единичного экземпляра объекта. В этом случае объект и есть объект, а не сущность.

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

Сущность может быть или абстрактной, или процессной.

Сущность может быть или абстрактной, или процессной.

Абстрактная сущность — это сущность, объединяющая (обобщающая) другие подсущности — другие сущности (абстрактные и/или процессные), наследующие её:

  • функции, но в более узкой специализации,
  • и названия атрибутов, но обязательно имеющие дополнительно к наследуемым свои отличительные названия атрибутов.

В абстрактную сущность обобщаются другие сущности, а не конкретные объекты. В этом и заключается её абстрактность. То есть абстрактная сущность не может объединять конкретные объекты с конкретными значениями атрибутов.

Например, сущность «дом» объединяет такие отдельные сущности (подсущности), как «многоквартирный дом (МКД)» и «индивидуальное жилое строение (ИЖС)». Эти сущности имеют свои комбинации названий атрибутов, но не их значений. Поэтому они тоже сущности, а не конкретные объекты.

И «ИЖС» и «МКД» — это «дом». Но у них будет разная специализация функций.

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

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

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

И «ИЖС» и «МКД» унаследуют от «дома» такие названия атрибутов, как «адрес», «фундамент», «крыша», «количество этажей». Это будут общие – одинаковые названия атрибутов. По их наличию и идёт объединение (обобщение). Но при этом каждая из этих сущностей добавит свои отличительные названия атрибутов.

«ИЖС» добавит «тип автономного отопления», «площадь приусадебного участка», «наличие хозпостроек на приусадебном участке», «наличие плодовых насаждений на приусадебном участке». Этих названий атрибутов нет у «МКД».

Зато у «МКД» есть «количество квартир», «наличие лифта», «площадь придомовой территории» и другие.

Из-за разности индивидуальных названий атрибутов и из-за различий в функциональной специализации эти сущности и отличаются друг от друга (МКД от ИЖС). При этом они остаются сущностью «дом». И поэтому «дом» является абстрактной сущностью, а не процессной. В этой ситуации абстрактная сущность «дом» становится контекстной для относящихся к ней подсущностей – других сущностей: «МКД» и «ИЖС».

Процессная сущность (ПС) – это сущность, которая рождается в среде «процессы» [3] , поэтому и процессная, и которая объединяет (обобщает) неограниченное количество конкретных процессных объектов (КПО), наследующих её названия атрибутов, которым для их идентификации присваиваются конкретные значения атрибутов.

Процессная сущность в отличие от абстрактной объединяет (обобщает) не другие сущности, а уже конкретные процессные объекты (КПО).

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

Список названий атрибутов КПО наследует от контекстной процессной сущности, к которой он относится.

Поэтому у всех КПО, относящихся к процессной сущности, одинаковые названия её обязательных атрибутов. Объединение (обобщение) происходит по наличию общих – одинаковых названий атрибутов у КПО, унаследованных от процессной сущности, к которой они относятся. В этой ситуации процессная сущность становится контекстной для относящегося к ней конкретного процессного объекта.

Например, приведённые выше в настоящей статье в таблице «Пример названий и значений атрибутов моего смартфона» значения атрибутов смартфона описывают конкретный процессный объект (КПО) – мой смартфон. Для него контекстной процессной сущностью будет сущность «смартфон», так как он к ней относится, он наследует от неё заданный набор названий атрибутов.

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

В частности, в «МКД» обобщаются все конкретные процессные объекты, которые уже будут описываться, идентифицироваться и дифференцироваться между собой не названиями атрибутов, а и их значениями – совокупностью (комбинацией) значений.

Например, набором значений таких атрибутов, как «этажность», «адрес», «количество квартир», «наличие лифта», «площадь придомовой территории» и т. д.

У каждого КПО, относящегося к процессной сущности «МКД», будут конкретные значения этих атрибутов, образующие уникальную их комбинацию. Эта уникальная комбинация значений атрибутов и позволит отделить один КПО от другого. А наличие у каждого такого КПО одинакового набора названий обязательных атрибутов объединит их в одну сущность «МКД». Она для них и будет контекстной.

Приведём пример в виде следующей таблицы:

Таблица: Пример взаимосвязи и иерархии сущностей

Пример взаимосвязи и иерархии сущностей

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

«абстрактная сущность (АС) → процессная сущность (ПС) → конкретный процессный объект (КПО)».

Кстати, на практике бывают иерархии более глубокие, например такая:

«абстрактная сущность (АС) → абстрактная сущность (АС) → процессная сущность (ПС) → конкретный процессный объект (КПО)».

То есть может быть несколько уровней вложенности сущностей.

В нашем примере, абстрактная сущность «дом» имеет свою функцию. Объединяет такие процессные сущности (в данном случае подсущности), как «МКД» и «ИЖС».

У этих процессных сущностей есть специализация по функции. У каждой своя. Есть общие единые названия атрибутов. По которым можно и «МКД» и «ИЖС» отнести к абстрактной сущности «дом».

При этом у каждой процессной сущности имеются дополнительные названия атрибутов, по набору (списку) которых можно их отличить друг от друга (МКД от ИЖС) и отделить.

Отдельная процессная сущность объединяет свой набор конкретных процессных объектов (КПО).

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

Более того, когда мы формируем процессную сущность путём составления набора названий её атрибутов, мы должны формировать такой набор, чтобы в дальнейшем при присвоении конкретному процессному объекту значений этих атрибутов обязательно складывалась уникальная комбинация этих значений. Именно по этой уникальной комбинации значений и будет вестись отбор – отделение одного КПО от другого.

И ещё заметьте каждая процессная сущность имеет своё множество КПО – более одного. В свою очередь абстрактная сущность «дом» объединяет эти множества в одно большое множество под собой – опосредованно – через ПС: «МКД» и ПС: «ИЖС». И это множество неограниченное, может постоянно расширяться и дополнятся. Поэтому и «МКД», и «ИЖС», и «дом» — это сущности.

Полная версия статьи доступна в моей книге «Задачи чудесные, или Козырная «ТУЗ» Мотаева!»

С уважением к Вам и Вашему делу, Мотаев Александр

Обсудить эту и другие статьи блога вы можете в нашем Telegram-канале «Управление потоком задач».

[1] — Хейвуд «Вуди» Аллен (Аллан Стюарт Конигсберг, род. 01.12.1935) — американский кинорежиссёр, актёр-комик, продюсер, четырёхкратный обладатель премии «Оскар», писатель, автор многочисленных рассказов и пьес.

[2] — Это моя личная точка зрения на предназначение человека на земле. Я считаю, что каждый человек должен созидать. Созидать Наследие, которое останется после него и будет приносить пользу другим людям. Таким наследием по древним обычаям минимум должно быть три «Д»: Дом, Дерево, Дети. Дом останется детям, как крыша над головой, без которой не может жить человек, или как их стартовый капитал. Дерево – это кислород, утилизация CO₂, экология. Дети – это потенциальные созидательные потомки, конечно же если их в дальнейшем правильно воспитать. Когда выполнена программа минимум, а я, например, её выполнил, далее можно созидать какое угодно наследие: созидательных потомков – воспитанных на созидание детей (родить мало, надо ещё воспитать, заточить детей на созидание), изобретения, дома, заводы, пароходы, произведения литературы, искусства, архитектуры и т. д. Всё, что приносит пользу другим людям, в том числе эстетическую. В этом предназначение человека, в этом его бессмертие. В наследии бессмертие! На мой взгляд, именно для созидания разум дан человеку природой и богом. Созидание требует труда, требует развития разума и сознания человека. Поэтому, созидая человек самосовершенствуется и развивается как личность, достигает осознания. Согласно Юнгу, самый тягчайший грех — нежелание достигнуть осознания, хотя такая возможность есть. Именно поэтому Юнг говорит, что с точки зрения психологии одной из самых злых и губительных сил являются нереализованные творческие способности. Если кто-то обладает творческим даром и вследствие своей лени или по какой-либо другой причине его не использует, эта психическая энергия превращается в настоящий яд. А я добавлю, если человек обладает разумом и его не использует для созидания. Он грешит. Он обрекает себя и часто тех, кто его окружает, на муки при жизни. Более подробно я эти мысли разворачиваю в блоге «Патримонизм» по адресу: http://patrimonizm.ru

[3] — В целях настоящего блога процесс — это устойчивая и целенаправленная совокупность взаимосвязанных процессных задач и действий, которые по определённой технологии воспроизводимо преобразуют входы в выходы для получения заранее определённых результатов, представляющих ценность для внешнего или внутреннего потребителя выходов процесса. В организации может функционировать несколько процессов. Одним из таких процессов, по моему мнению, является процесс «Управление Потоком Задач» — т. е. «менеджмент», описываемый в книге «Задачи чудесные, или Козырная «ТУЗ» Мотаева!». Для осуществления этого процесса нужна «Технология Управления Задачами»

Сущности и связи — JS: Предметно-ориентированное проектирование

ERM — Модель данных, позволяющая описывать концептуальные схемы предметной области.

Сущности

Этот подход включает в себя два основных понятия: сущность и связь. Проще всего начать с примеров:

  • Пользователь
  • Кинозал
  • Фильм
  • Билет
  • Показ фильма

Это сущности нашей предметной области, с которыми предстоит работать в коде. Как видите, понятие сущность довольно интуитивно. Но также оно обладает и рядом формальных характеристик:

  • Идентификация
  • Время жизни

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

const user = new User('Илон'); console.log(user.id); // 896b677f-fb14-11e0-b14d-d11ca798dbac // User.js import uuid from 'uuid/v4'; class User  constructor(name)  this.id = uuid(); this.name = name; > > 

Библиотека uuid позволяет генерировать уникальный идентификатор, который можно использовать для идентификации. Кстати uuid очень полезная штука, может пригодиться в некоторых типах задач.

Время жизни означает, что наша сущность в какой-то момент появилась и когда-то может исчезнуть.

Связи

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

Таким образом можно выделить три основных типа связи: один к одному (o2o), один ко многим (o2m) и многие ко многим (m2m).

Выше представлена диаграмма Entity-Relationship. Она входит в стандарт UML и неплохо помогает понять то, какие сущности составляют вашу предметную область и как они друг с другом связаны.

Что можно сказать глядя на диаграмму?

  • В одном зале может быть много показов фильмов;
  • Один фильм может быть показан много раз;
  • Фильмы и залы связаны друг с другом как «многие ко многим». То есть один фильм показывается в разных залах, а в одном зале идут разные фильмы.

Всё это довольно очевидно и соответствует нашему опыту посещения кинозалов. В других предметных областях это уже не так просто, и то, как вы проектируете сущности и их связи, имеет сильное влияние на ваше приложение. Общее правило такое, чем больше связей и чем более они разнообразные, тем сложнее приложение. Часто бывает такое, что программисты «закладываются на будущее» (которое не факт, что наступит) и пытаются делать чуть ли не все связи m2m. Чаще всего такой подход оказывается примером over-engineering (гиперпроектирование), другими словами, не надо добавлять сложности там, где нет реальной потребности.

Кроме влияния на логику работы, связи также сильно влияют на способ хранения сущностей в базе данных. Например, в реляционных базах данных, связь m2m всегда подразумевает наличие промежуточной таблицы. В свою очередь рефакторинг базы данных не такое простое занятие, как изменение кода.

Пример

На Хекслете есть курсы. Каждый курс состоит из уроков. Урок не может существовать без курса. Вот как может быть представлена эта модель в коде:

const course = new Course('JS: DDD'); const lesson1 = new Lesson(course, 'Введение'); const lesson2 = new Lesson(course, 'Модель Сущность-Связь'); 

Передача курса в конструктор удобна по двум причинам. Сразу становится видна и понятна связь урока с курсом. А также на уровне языка заложено бизнес-правило, что урок не может существовать без курса.

Объекты-значения (Справочники)

Открыть доступ

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

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Введение в проектирование сущностей, проблемы создания объектов

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

В данной статье описываются две такие проблемы, и рассматривается способ их решения. Так же статья подойдет как введение в проектирование сущностей. Для понимания материала понадобится базовое представление о предметно-ориентированном проектировании.

Итак, мы изучили предметную область, сформировали единый язык, выделили ограниченные контексты и определились с требованиями [2]. Всё это выходит за рамки данной статьи, тут мы попробуем решить конкретные узкие проблемы:

  1. Создание и обеспечение консистентности сложных объектов-сущностей.
  2. Создание объектов-сущностей с генерацией идентификатора по автоинкрементному полю базы данных.

Введение

У нас есть клиент, который должен быть смоделирован как сущность (Entity) [2]. С точки зрения бизнеса у каждого клиента обязательно есть:

  • имя или наименование;
  • организационная форма (физ. лицо, ИП, ООО, АО и т.д.);
  • главный менеджер (один из менеджеров, закрепляется за клиентом);
  • информация о фактическом адресе;
  • информация о юридическом адресе.

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

namespace Domain; final class Client

Целый ряд свойств мы опустили, для упрощения примера, реальный класс может быть значительно больше.

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

$client = new Client(); // В данный момент клиент у нас уже находится в не консистентном состоянии // Если мы хотим запросить его идентификатор, то получим ошибку, т.к. он ещё не установлен $client->getId(); // Или мы можем сохранить (попытаться) не валидного клиента, у которого не установлены обязательные свойства $repository->save($client); 

Создание и обеспечение консистентности сложных объектов-сущностей.

Для начала попробуем решить проблему консистентности. Для этого уберем из класса сеттеры, а все обязательные параметры будем запрашивать в конструкторе [4]. Таким образом, объект будет всегда валиден, может использоваться сразу после создания и обеспечивается полноценная инкапсуляция предотвращающая возможность приведения клиента в неконсистентное состояние. Теперь наш класс выглядит следующим образом.

namespace Domain; final class Client

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

Что можно с этим сделать? Простое и очевидное решение — сгруппировать логически связанные параметры в объектах-значениях (Value Object) [3].

namespace Domain; final class Address
namespace Domain; final class Client

Выглядит гораздо лучше, но параметров всё ещё довольно много, особенно это не удобно, если часть из них скалярные. Решение — шаблон Строитель (Builder) [5].

namespace Application; interface ClientBuilder
$client = $builder->setId($id) ->setName($name) ->setGeneralManagerId($generalManager) ->setCorporateForm($corporateForm) ->setAddress($address) ->buildClient(); 

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

Создание объектов-сущностей с генерацией идентификатора по автоинкрементному полю базы данных.

У проектируемого класса обязательно должен быть уникальный идентификатор, т.к. основной отличительной чертой сущностей является индивидуальность. Объект может значительно изменяться с течением времени, так что ни одно из его свойств не будет равным тому, что было вначале. В то же время все или большинство свойств объекта могут совпадать со свойствами другого объекта, но это будут разные объекты. Именно уникальный идентификатор дает возможность различать каждый объект не зависимо от его текущего состояния [1].

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

Cгенерировать, например, UUID или запросить у базы данных очередное значение последовательности не составляет никаких трудностей. Но иногда возникает необходимость работать с уже существующей структурой БД, в которой таблица хранящая соответствующие данные имеет для идентификатора автоинкрементное поле.

В таком случае крайне затруднительно и ненадежно получать очередной уникальный идентификатор без сохранения сущности, а значит невозможно создать объект в полностью консистентном состоянии.

И снова нам поможет в этом шаблон Строитель, который мы можем реализовать следующим образом.

namespace Infrastructure; final class MySqlClientBuilder implements ClientBuilder < private $connection; public function __construct(Connection $connection); public function buildClient() < $this->connection ->insert('clients_table', [ $this->name, $this->corporateForm, $this->generalManager->getId(), $this->address ]); $id = $this->connection->lastInsertId(); return new Client( $id, $this->name, $this->corporateForm, $this->generalManager, $this->address ); > > 

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

$builder = $container->get(ClientBuilder::class); $client = $builder->setId($id) ->setName($name) ->setGeneralManagerId($generalManager) ->setCorporateForm($corporateForm) ->setAddress($address) ->buildClient(); $repository->save($client); $client->getId(); 

Благодарю за внимание!

P.S.:

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

Опыт разработки у меня относительно не большой — четыре года, DDD применял пока только на одном проекте.

Буду благодарен за отзывы и конструктивные замечания.

Ссылки:
  1. Эванс Э., «Предметно-ориентированное проектирование (DDD). Структуризация сложных программных систем.»
  2. Вернон В., «Реализация методов предметно-ориентированного проектирования.»
  3. М. Фаулер, Value Object
  4. М. Фаулер, Constructor Initialization
  5. Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидс, «Приёмы объектно-ориентированного проектирования. Паттерны проектирования.»
  • domain-driven design
  • design patterns
  • anemic domain model
  • rich domain model
  • code complete
  • mysql
  • php
  • ооп

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *