All streams
Search
Write a publication
Pull to refresh
50
-0.1
Alex Gusev @flancer

Я кодирую, потому что я кодирую…

Send message

Про ситнаксис — это просто замечательно! Вот тут-то мы и выходим на корень наших с вами различий. Это разное мировоззрение. Я считаю Вселенную "дискретной", а вы — "аналоговой". В моем случае у Вселенной есть начало и конец (ее можно уложить во временнЫе рамки — существует от события А и до события Б), вы же считаете, что Вселенная бесконечная, до события А можно выделить/придумать событие пре-А, только у него интенсивность очень-очень маленькая. А после события Б можно выделить/придумать событие пост-Б, также с очень малой интенсивностью.


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


Как я отмечал выше, инструментом для определения "правдивости" той или иной модели является ее практическое применение. Попробуйте разрешить апорию Зенона про Ахиллеса и черепаху не применяя дискретизацию. Промчитесь на "колеснице интенсивности" сквозь"бесконечные перемены". Через сколько итераций вам станет понятно, что в следующей уже нет смысла, т.к. черепаха все равно проползет 1/10 того растояния, что отделяет ее сейчас от Ахиллеса, и Ахиллесу опять придется догонять черепаху?


Мне действительно интересно, как "аналоговый" человек (т.е. — вы) разрешит апорию Зенона, не прибегая к дискретности (т.е., началу и концу, "рождению", "жизни" и "смерти"). А все остальное непонимание — следствие именно этого расхождения.

Получается, что тот, кто не видел результата, не может смоделировать операцию?

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


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


Инициация операции — это из области теории деятельности. То есть, мы, опираясь на это определение, автоматически отсекаем те операции, которые были никем не инициированы и те операции, инициаторов которых мы не знаем, или даже не знаем, есть ли они, или их нет

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


а инструмента выразить эти «правости» у нас нет.

Есть. Практика. Насколько хорошо модель соответствует реалу? У кого лучше соответствует, того "правда" и правее. И тут мы опять приходим к необходимости измерений, неким метрикам, сравнивая которые мы можем оценить соответствие моделей тому, что они моделируют. Человекам не нужна "универсальная теория всего", им нужны инструменты для достижения своих целей. Для получения определенного результата.

Теперь я задаю вопрос: кому и какие потребности закрывает тезис, что процесс должен быть направлен кем-то на достижение результата? У вас есть гипотеза на этот счет?

IMHO, результат — неотъемлемый атрибут процесса. Процесс меняет что-то где-то за какое-то время. Или обеспечивает неизменность. Совокупность этого "что", "где" и "какое время" и дают "результат". Ну а "кто-то" — это "инициатор процесса".


Таким образом, тезис "процесс должен быть направлен кем-то на достижение результата" говорит о том, что, чтобы являться процессом действие должно быть кем-то инициировано и должно оставлять следы, которые могли быть зафиксированы сторонним наблюдателем. Я бы еще добавил, что "достижение" говорит также о конечности "процесса". Т.е., бесконечное действие не является процессом. Как и безначальное (ибо нет инициатора).


Т.е., процесс — это действие с началом, концом и оставляемыми (измеряемыми) следами.

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

А разве группа не может быть представителем группы? Группа групп, например. Множество множеств. Класс классов. Может. И чем больше мы уходим в абстракт, тем более "может". В пределе "все" — есть "что-то", и каждое "что-то" состоит из других "что-то".

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


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


Скрытый текст
DROP TABLE IF EXISTS struct_elem, elem_class, elem, struct_class, struct_obj, struct;
DROP TABLE IF EXISTS obj_attr, attr_class, obj_class, attr, obj;
DROP TABLE IF EXISTS meta_struct_elem, meta_elem, meta_struct;
DROP TABLE IF EXISTS meta_classifier_attr, meta_classifier;
DROP TABLE IF EXISTS meta_obj_attr, meta_attr, meta_obj;

--
-- Мета данные для объектов.
--
CREATE TABLE meta_obj (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Реестр типов объектов (деревья, люди, ...)';

CREATE TABLE meta_attr (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Реестр типов атрибутов (высота, имя, ...)';

CREATE TABLE meta_obj_attr (
  obj  INT(10) UNSIGNED NOT NULL,
  attr INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (obj, attr),
  CONSTRAINT meta_obj_attr_to_obj FOREIGN KEY (obj) REFERENCES meta_obj (id)
    ON DELETE CASCADE,
  CONSTRAINT meta_obj_attr_to_attr FOREIGN KEY (attr) REFERENCES meta_attr (id)
    ON DELETE CASCADE
)
  COMMENT = 'Привязка типов атрибутов к типам объектов (высота для деревьев, имена для людей)';

--
-- Мета данные для классификатора объектов.
--
CREATE TABLE meta_classifier (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Реестр классов (способов объединения атрибутов объекта для различения экземпляров объектов по значениям атрибутов)';

CREATE TABLE meta_classifier_attr (
  class INT(10) UNSIGNED NOT NULL,
  attr  INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (class, attr),
  CONSTRAINT meta_classifier_attr_to_class FOREIGN KEY (class) REFERENCES meta_classifier (id)
    ON DELETE CASCADE,
  CONSTRAINT meta_classifier_attr_to_attr FOREIGN KEY (attr) REFERENCES meta_attr (id)
    ON DELETE CASCADE
)
  COMMENT = 'Привязка класса к атрибутам, его характеризующим (масса-высота-ширина или долгота-широта)';

--
-- Мета данные для классификатора конструкций.
--
CREATE TABLE meta_struct (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Реестр типов конструкций';

CREATE TABLE meta_elem (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Реестр типов элементов конструкций';

CREATE TABLE meta_struct_elem (
  struct INT(10) UNSIGNED NOT NULL,
  elem   INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (struct, elem),
  CONSTRAINT meta_struct_elem_to_struct FOREIGN KEY (struct) REFERENCES meta_struct (id)
    ON DELETE CASCADE,
  CONSTRAINT meta_struct_elem_to_elem FOREIGN KEY (elem) REFERENCES meta_elem (id)
    ON DELETE CASCADE
)
  COMMENT = 'Привязка типов элементов к типам конструкций';

--
-- Предметная область (объекты и их свойства).
--
CREATE TABLE obj (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Реестр экземпляров объектов (#1, #2, ...)';

CREATE TABLE obj_class (
  obj   INT(10) UNSIGNED NOT NULL,
  class INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (obj, class),
  CONSTRAINT obj_class_to_obj FOREIGN KEY (obj) REFERENCES obj (id)
    ON DELETE CASCADE,
  CONSTRAINT obj_class_to_class FOREIGN KEY (class) REFERENCES meta_obj (id)
    ON DELETE CASCADE
)
  COMMENT = 'Привязка экземпляров объектов к типам объектов (#1 - дерево, #2 - человек)';

CREATE TABLE attr (
  id    INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  -- значением атрибута может быть что угодно, включая ссылки на другие объекты; для упрощения - просто некий текст
  -- каким образом он обрабатывается - решается на программном уровне, для хранилища главное - хранить значение
  value TEXT             NULL,
  PRIMARY KEY (id)
)
  COMMENT = 'Реестр значений атрибутов (#1 - тополь, #2 - 3м)';

CREATE TABLE attr_class (
  attr  INT(10) UNSIGNED NOT NULL,
  class INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (attr, class),
  CONSTRAINT attr_class_to_attr FOREIGN KEY (attr) REFERENCES attr (id)
    ON DELETE CASCADE,
  CONSTRAINT attr_class_to_class FOREIGN KEY (class) REFERENCES meta_attr (id)
    ON DELETE CASCADE
)
  COMMENT = 'Привязка значений атрибутов к типам (классам) атрибутов (#1 - порода, #2 - высота)';

CREATE TABLE obj_attr (
  obj  INT(10) UNSIGNED NOT NULL,
  attr INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (obj, attr),
  CONSTRAINT obj_attr_to_obj FOREIGN KEY (obj) REFERENCES obj (id)
    ON DELETE CASCADE,
  CONSTRAINT obj_attr_to_attr FOREIGN KEY (attr) REFERENCES attr (id)
    ON DELETE CASCADE
)
  COMMENT = 'Привязка значений атрибутов к экземплярам объектов (порода объекта #1 - тополь';

--
-- Конструкции и элементы.
--
CREATE TABLE struct (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Реестр экземпляров конструкций';

CREATE TABLE struct_obj (
  struct INT(10) UNSIGNED NOT NULL,
  obj    INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (struct, obj),
  CONSTRAINT struct_obj_to_struct FOREIGN KEY (struct) REFERENCES struct (id)
    ON DELETE CASCADE,
  CONSTRAINT struct_obj_to_obj FOREIGN KEY (obj) REFERENCES obj (id)
    ON DELETE CASCADE
)
  COMMENT = 'Привязка экземпляров конструкций к экземплярам объектов';

CREATE TABLE struct_class (
  struct INT(10) UNSIGNED NOT NULL,
  class  INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (struct, class),
  CONSTRAINT struct_class_to_struct FOREIGN KEY (struct) REFERENCES struct (id)
    ON DELETE CASCADE,
  CONSTRAINT struct_class_to_class FOREIGN KEY (class) REFERENCES meta_struct (id)
    ON DELETE CASCADE
)
  COMMENT = 'Привязка экземпляров конструкций к типам конструкций';

CREATE TABLE elem (
  id  INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  -- элемент конструкции сам является объектом
  obj INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (id),
  CONSTRAINT elem_to_obj FOREIGN KEY (obj) REFERENCES obj (id)
    ON DELETE CASCADE
)
  COMMENT = 'Реестр значений элементов экземпляров конструкций';

CREATE TABLE elem_class (
  elem  INT(10) UNSIGNED NOT NULL,
  class INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (elem, class),
  CONSTRAINT elem_class_to_elem FOREIGN KEY (elem) REFERENCES elem (id)
    ON DELETE CASCADE,
  CONSTRAINT elem_class_to_class FOREIGN KEY (class) REFERENCES meta_elem (id)
    ON DELETE CASCADE
)
  COMMENT = 'Привязка значений элементов к типам элементов';

CREATE TABLE struct_elem (
  struct INT(10) UNSIGNED NOT NULL,
  elem   INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (struct, elem),
  CONSTRAINT struct_elem_to_obj FOREIGN KEY (struct) REFERENCES struct (id)
    ON DELETE CASCADE,
  CONSTRAINT struct_elem_to_attr FOREIGN KEY (elem) REFERENCES elem (id)
    ON DELETE CASCADE
)
  COMMENT = 'Привязка значений элементов к экземплярам конструкций';


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

В применении к схеме из самой статьи (с желтыми и зелеными прямоугольниками) что является "структурой", "объектом", "элементом", "типом объектов", "атрибутом"?

Код переформатировался в комменте :( Исправил. Оба фрагмента объединены:


Скрытый текст
DROP TABLE IF EXISTS obj_trassa_attr_num;
DROP TABLE IF EXISTS ctx_lep_as_trassa, ctx_lep_as_uch, ctx_trassa_as_provod, ctx_trassa_as_uch_tr;
DROP TABLE IF EXISTS ctx_uch_lep_as_uch_tr, ctx_provod_as_uch_prov, ctx_uch_tr_as_uch_prov, ctx_lep_as_uch_tr;
DROP TABLE IF EXISTS obj_lep, obj_trassa, obj_provod, obj_uch_lep, obj_uch_trassa, obj_uch_provod;

--
--  Objects (реестры объектов)
--
CREATE TABLE obj_lep (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'ЛЭП';
CREATE TABLE obj_trassa (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Трасса';
CREATE TABLE obj_provod (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Провод';
CREATE TABLE obj_uch_lep (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Участок ЛЭП между опорами';
CREATE TABLE obj_uch_trassa (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Участок трассы между опорами';
CREATE TABLE obj_uch_provod (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Участок провода между опорами';

--
--  Contexts (контексты/конструкции)
--
CREATE TABLE ctx_lep_as_trassa (
  lep    INT(10) UNSIGNED NOT NULL,
  trassa INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (lep, trassa),
  CONSTRAINT ctx_lep_as_trassa_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_lep_as_trassa_to_trassa FOREIGN KEY (lep) REFERENCES obj_trassa (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 1: ЛЭП как трассы';
CREATE TABLE ctx_lep_as_uch (
  lep INT(10) UNSIGNED NOT NULL,
  uch INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (lep, uch),
  CONSTRAINT ctx_lep_as_uch_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_lep_as_uch_to_uch FOREIGN KEY (uch) REFERENCES obj_uch_lep (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 2: ЛЭП как участки';
CREATE TABLE ctx_trassa_as_provod (
  trassa INT(10) UNSIGNED NOT NULL,
  provod INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (trassa, provod),
  CONSTRAINT ctx_trassa_as_provod_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_trassa_as_provod_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 3: трасса как провода';
CREATE TABLE ctx_trassa_as_uch_tr (
  trassa INT(10) UNSIGNED NOT NULL,
  uch_tr INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (trassa, uch_tr),
  CONSTRAINT ctx_trassa_as_uch_tr_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_trassa_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 4: трасса как участки трассы';
CREATE TABLE ctx_uch_lep_as_uch_tr (
  uch_lep INT(10) UNSIGNED NOT NULL,
  uch_tr  INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (uch_lep, uch_tr),
  CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_lep FOREIGN KEY (uch_lep) REFERENCES obj_uch_lep (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 5: участок ЛЭП как участок трассы';
CREATE TABLE ctx_provod_as_uch_prov (
  provod   INT(10) UNSIGNED NOT NULL,
  uch_prov INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (provod, uch_prov),
  CONSTRAINT ctx_provod_as_uch_prov_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_provod_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 6: провод как участок провода';
CREATE TABLE ctx_uch_tr_as_uch_prov (
  uch_tr   INT(10) UNSIGNED NOT NULL,
  uch_prov INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (uch_tr, uch_prov),
  CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 7: участок трассы как участок провода';
CREATE TABLE ctx_lep_as_uch_tr (
  lep    INT(10) UNSIGNED NOT NULL,
  uch_tr INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (lep, uch_tr),
  CONSTRAINT ctx_lep_as_uch_tr_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 8: ЛЭП как участок трассы';

--
-- Данные (объекты)
--
INSERT INTO obj_lep VALUES (1);
INSERT INTO obj_trassa VALUES (1), (2);
INSERT INTO obj_provod VALUES (1), (2);
INSERT INTO obj_uch_lep VALUES (1), (2);
INSERT INTO obj_uch_trassa VALUES (1), (2), (3);
INSERT INTO obj_uch_provod VALUES (1), (2), (3);

--
-- Данные (связи в контекстах)
--
INSERT INTO ctx_lep_as_trassa VALUES (1, 1), (1, 2);
INSERT INTO ctx_lep_as_uch VALUES (1, 1), (1, 2);
INSERT INTO ctx_trassa_as_provod VALUES (2, 1), (2, 2);
INSERT INTO ctx_trassa_as_uch_tr VALUES (2, 1), (2, 2);
INSERT INTO ctx_uch_lep_as_uch_tr VALUES (1, 2), (1, 3);
INSERT INTO ctx_provod_as_uch_prov VALUES (2, 1), (2, 2);
INSERT INTO ctx_uch_tr_as_uch_prov VALUES (2, 2), (2, 3);
INSERT INTO ctx_lep_as_uch_tr VALUES (1, 1), (1, 2), (1, 3);

--
--  Атрибуты объектов
--
CREATE TABLE obj_trassa_attr_num (
  id INT(10) UNSIGNED NOT NULL,
  value varchar(255) NOT NULL ,
  PRIMARY KEY (id),
  CONSTRAINT obj_trassa_attr_num_to_obj FOREIGN KEY (id) REFERENCES obj_trassa (id)
    ON DELETE CASCADE
)
  COMMENT = 'Номер трассы';

Картинку лучше открывать отдельно в новой вкладке, будет более читабельно. Схема данных навеяна Anchor Modeling.

Если вы оперируете объектами, а не их атрибутами, то для их представления вполне достаточно ID объекта и его типа/класса. Классические инструменты вполне позволяют это делать, если не закапываться в дебри. Ваша схема из статьи про ЛЭП/трассы/провода/участки очень хорошо укладывается в типичную RDBMS (MySQL в моем случае). Все, что с префиксом "obj" — это таблицы для желтых элементов вашей схемы, с префиксом "ctx" — для синих:


image


Вот SQL-код для построения структуры и заполнения ее данными:


Скрытый текст
DROP TABLE IF EXISTS ctx_lep_as_trassa, ctx_lep_as_uch, ctx_trassa_as_provod, ctx_trassa_as_uch_tr;
DROP TABLE IF EXISTS ctx_uch_lep_as_uch_tr, ctx_provod_as_uch_prov, ctx_uch_tr_as_uch_prov, ctx_lep_as_uch_tr;
DROP TABLE IF EXISTS obj_lep, obj_trassa, obj_provod, obj_uch_lep, obj_uch_trassa, obj_uch_provod;

— — Objects (реестры объектов)
— CREATE TABLE obj_lep (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'ЛЭП';
CREATE TABLE obj_trassa (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Трасса';
CREATE TABLE obj_provod (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Провод';
CREATE TABLE obj_uch_lep (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Участок ЛЭП между опорами';
CREATE TABLE obj_uch_trassa (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Участок трассы между опорами';
CREATE TABLE obj_uch_provod (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Участок провода между опорами';

— — Contexts (контексты/конструкции)
— CREATE TABLE ctx_lep_as_trassa (
lep INT(10) UNSIGNED NOT NULL,
trassa INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (lep, trassa),
CONSTRAINT ctx_lep_as_trassa_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_lep_as_trassa_to_trassa FOREIGN KEY (lep) REFERENCES obj_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 1: ЛЭП как трассы';
CREATE TABLE ctx_lep_as_uch (
lep INT(10) UNSIGNED NOT NULL,
uch INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (lep, uch),
CONSTRAINT ctx_lep_as_uch_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_lep_as_uch_to_uch FOREIGN KEY (uch) REFERENCES obj_uch_lep (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 2: ЛЭП как участки';
CREATE TABLE ctx_trassa_as_provod (
trassa INT(10) UNSIGNED NOT NULL,
provod INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (trassa, provod),
CONSTRAINT ctx_trassa_as_provod_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id)
ON DELETE CASCADE,
CONSTRAINT ctx_trassa_as_provod_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 3: трасса как провода';
CREATE TABLE ctx_trassa_as_uch_tr (
trassa INT(10) UNSIGNED NOT NULL,
uch_tr INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (trassa, uch_tr),
CONSTRAINT ctx_trassa_as_uch_tr_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id)
ON DELETE CASCADE,
CONSTRAINT ctx_trassa_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 4: трасса как участки трассы';
CREATE TABLE ctx_uch_lep_as_uch_tr (
uch_lep INT(10) UNSIGNED NOT NULL,
uch_tr INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (uch_lep, uch_tr),
CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_lep FOREIGN KEY (uch_lep) REFERENCES obj_uch_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 5: участок ЛЭП как участок трассы';
CREATE TABLE ctx_provod_as_uch_prov (
provod INT(10) UNSIGNED NOT NULL,
uch_prov INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (provod, uch_prov),
CONSTRAINT ctx_provod_as_uch_prov_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id)
ON DELETE CASCADE,
CONSTRAINT ctx_provod_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 6: провод как участок провода';
CREATE TABLE ctx_uch_tr_as_uch_prov (
uch_tr INT(10) UNSIGNED NOT NULL,
uch_prov INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (uch_tr, uch_prov),
CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE,
CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 7: участок трассы как участок провода';
CREATE TABLE ctx_lep_as_uch_tr (
lep INT(10) UNSIGNED NOT NULL,
uch_tr INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (lep, uch_tr),
CONSTRAINT ctx_lep_as_uch_tr_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 8: ЛЭП как участок трассы';

— — Данные (объекты)
— INSERT INTO obj_lep VALUES (1);
INSERT INTO obj_trassa VALUES (1), (2);
INSERT INTO obj_provod VALUES (1), (2);
INSERT INTO obj_uch_lep VALUES (1), (2);
INSERT INTO obj_uch_trassa VALUES (1), (2), (3);
INSERT INTO obj_uch_provod VALUES (1), (2), (3);

— — Данные (связи в контекстах)
— INSERT INTO ctx_lep_as_trassa VALUES (1, 1), (1, 2);
INSERT INTO ctx_lep_as_uch VALUES (1, 1), (1, 2);
INSERT INTO ctx_trassa_as_provod VALUES (2, 1), (2, 2);
INSERT INTO ctx_trassa_as_uch_tr VALUES (2, 1), (2, 2);
INSERT INTO ctx_uch_lep_as_uch_tr VALUES (1, 2), (1, 3);
INSERT INTO ctx_provod_as_uch_prov VALUES (2, 1), (2, 2);
INSERT INTO ctx_uch_tr_as_uch_prov VALUES (2, 2), (2, 3);
INSERT INTO ctx_lep_as_uch_tr VALUES (1, 1), (1, 2), (1, 3);


Если же вы захотите еще оперировать и атрибутами объекта, то вы можете добавить любое кол-во различных атрибутов (или наборов атрибутов, если они связаны друг с другом по отношению к объекту, как, например, Имя/Отчество/Фамилия). Вот структура для сохранения «номера трассы», например:

Скрытый текст
CREATE TABLE obj_trassa_attr_num (
id INT(10) UNSIGNED NOT NULL,
value varchar(255) NOT NULL,
PRIMARY KEY (id),
CONSTRAINT obj_trassa_attr_num_to_obj FOREIGN KEY (id) REFERENCES obj_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Номер трассы';


Вам нужна гибкость? Пожалуйста. Но заплатите за нее простотой.

Вот видите, приходится выделять "ведущего" (генератор значения для identity) и от него уже плясать. Можно хоть по одной таблице на атрибут сделать (что, кстати, 6NF и предусматривает), но identity values должны хранится в одном месте, если вы хотите обеспечить их уникальность и консистентность.


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

Сложнее всего отвечать на вопросы, имеющие очевидный ответ :) Где у вас ведется учет идентификаторов для новых экземпляров сущностей User — в user_auth, в user_pass, в приложении (в каком экземпляре, если идет балансировка нагрузки)? И что будет, если два процесса одновременно вводят разные данные (auth & pass) по одному пользователю?


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

И что мы имеем в итоге? Две независимые таблицы, каждая из которых имеет свой набор полей, включающий identity-поле, по значению которого и осуществляется сопоставление данных из одной таблицы данным из другой. Никаких внешних связей (foreign keys) друг с другом на уровне структур базы данных. Связывание данных идет в объектной модели на программном уровне.


CREATE TABLE user_auth (
  id int(10) UNSIGNED NOT NULL,
  username varchar(255) NOT NULL,
  ...
  PRIMARY KEY (id)
);

CREATE TABLE user_pass (
  id int(10) UNSIGNED NOT NULL,
  firstname varchar(255) NOT NULL,
  ...
  PRIMARY KEY (id)
);

Но ведь именно это я имел в виду, говоря "бред". А вы что имели в виду, говоря "связь 1:1"?

Паспортных с аутентификационными или аутентификационных с паспортными? Кто на кого ссылается? Где находится identity для экземпляра User'а — в паспортных данных или аутентификационных? Могут ли паспортные существовать без идентификационных и наоборот?

Связь чего с чем? Левых атрибутов User'а с правыми?

Неправильно называть разные конструкции одним и тем же понятием (User), обозначающим весь объект.

Вот и я за то — иметь в программе два разных типа к одному моделируемому объекту на данный момент большинству программистов "религия не позволяет"


А на родительский объект ссылаются по id.

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

Ага, так и есть. Вот только иметь в программе два разных типа к одному моделируемому объекту на данный момент большинству программистов "религия не позволяет". Это как иметь в БД две таблицы с различными атрибутами для одной и той же сущности User. Это же бред? Бред. Вот и сливают все атрибуты из различных моделей User'а в одну таблицу и делают одну общую, универсальную модель. Так кошерно.

Программирование — это тоже моделирование. И довольно гибкое. Если уж нельзя в программировании, то о каком "моделировании предметной области" вы сейчас говорите?

Никто не запрещает переименовать "короткую" переменную при "разрастании" однострочника. Это косяк не того, кто однострочник составил, а того, кто его развернул.

Не меняется то, что называется английским словом identity. И именно это мы связываем с объектом в целом.

Насколько я понял, предполагается в приложении иметь различные модели (с различным набором атрибутов) для одного и того же identity.

Information

Rating
Does not participate
Location
Рига, Латвия, Латвия
Date of birth
Registered
Activity

Specialization

Fullstack Developer
Lead
From 3,000 €
JavaScript
HTML
CSS
Node.js
Vue.js
Web development
Progressive Web Apps
PostgreSQL
MySQL
GitHub