powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Вопрос по теории, помогите разобраться с обязательностью в связях
14 сообщений из 14, страница 1 из 1
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37050658
Lord Daedra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветствую!

Посмотрите, пожалуйста, на приложенный скриншот (я сделал все возможные виды связей 1:М между двумя сущностями).

при проектировании я могу указать в настройках связи такой параметр как Child Optionality, выбрав Optional или Madatory

А теперь, уважаемые знатоки, внимание, вопрос:
в чём разница? генерируется одинаковый код..

я понимаю, почему код одинаковый, потому что первичный ключ не может быть null

например, нет разницы между связями между сущностями 9-10 и 11-12...

Спасибо!
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37050712
Бредятина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lord Daedra Посмотрите, пожалуйста, на приложенный скриншот (я сделал все возможные виды связей 1:М между двумя сущностями).
Вы "сделали" ограничения целостности (PK и FK). Никаких связей в реляционных СУБД просто нет:)
Lord Daedra в чём разница? генерируется одинаковый код..
Поскольку в реляционных СУБД никаких связей нет, их нет и в коде, естественно:)
Mandatory, возможно, следует трактовать так: для каждого кортежа в отношении A ("родитель") в отношении B ("потомок") должен быть, как минимум, один кортеж, имеющий FK, значение которого равно значению PK кортежа в отношении A.
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37050825
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бредятина,

ну при чем тут рмд
просто туфтовый инструмент не может генерировать check
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37050920
Lord Daedra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот конкретный пример, нарисовал схемку, система сгенерировала мне SQL:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
...

CREATE TABLE "public"."Entity1"(
"id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity1_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

CREATE TABLE "public"."Entity2"(
"id" BIGSERIAL NOT NULL,
"Entity1_id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity2_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

CREATE TABLE "public"."Entity3"(
"id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity3_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

CREATE TABLE "public"."Entity4"(
"id" BIGSERIAL NOT NULL,
"Entity3_id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity4_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

ALTER TABLE "public"."Entity2" ADD CONSTRAINT "fk_Entity2Relationship1" FOREIGN KEY ("Entity1_id") REFERENCES "public"."Entity1"("id") MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;

ALTER TABLE "public"."Entity4" ADD CONSTRAINT "fk_Entity4Relationship2" FOREIGN KEY ("Entity3_id") REFERENCES "public"."Entity3"("id") MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;

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

из всех инструментов для проектирования этот мне понравился больше всех, тем более бесплатный или недорогой (в зависимости от тарифного плана), а существуют ли решения лучше для работы с postgres из недорогих (до $200) или тех что реально найти на трэкерах?
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37050945
Фотография vadiminfo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для связи между Entity3 и Entity4
Ожидалось
допуск пустых значений для Entity3_id:
"Entity3_id" BIGSERIAL
а не
"Entity3_id" BIGSERIAL NOT NULL

Т.е.
Код: plaintext
1.
2.
3.
4.
5.
6.
CREATE TABLE "public"."Entity4"(
"id" BIGSERIAL NOT NULL,
"Entity3_id" BIGSERIAL,
CONSTRAINT "Entity4_pkey" PRIMARY KEY ("id")
)


Ну, думау, ниче страшного: удалять не добавлять. Руками доправите другой раз.
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37051771
Lord Daedra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не-а, похоже, что не совсем так.

Привел более полный пример чтобы было понятнее (тут 4 варианта, все неидентифицируемые, все 1:М, отличаются только тем, что выбрано в списках Parent Optionality и Child Optionality, то есть в каждом можно выбрать либо Mandatory либо Optional).

Здесь 1-2 ничем не отличается от 3-4, а 5-6 ничем не отличается от 7-8. Имею ввиду генерируемый sql-код для создания таблиц.

То есть если я удалю NOT NULL то из 1-2 или 3-4 получится 5-6 или 7-8.


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
CREATE TABLE "public"."Entity1"(
"id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity1_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

CREATE TABLE "public"."Entity2"(
"id" BIGSERIAL NOT NULL,
"Entity1_id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity2_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

CREATE TABLE "public"."Entity3"(
"id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity3_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

CREATE TABLE "public"."Entity4"(
"id" BIGSERIAL NOT NULL,
"Entity3_id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity4_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

CREATE TABLE "public"."Entity5"(
"id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity5_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

CREATE TABLE "public"."Entity6"(
"id" BIGSERIAL NOT NULL,
"Entity5_id" BIGSERIAL,
CONSTRAINT "Entity6_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

CREATE TABLE "public"."Entity7"(
"id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity7_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

CREATE TABLE "public"."Entity8"(
"id" BIGSERIAL NOT NULL,
"Entity7_id" BIGSERIAL,
CONSTRAINT "Entity8_pkey" PRIMARY KEY ("id")
)
WITHOUT OIDS;

ALTER TABLE "public"."Entity2" ADD CONSTRAINT "fk_Entity2Relationship1" FOREIGN KEY ("Entity1_id") REFERENCES "public"."Entity1"("id") MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;

ALTER TABLE "public"."Entity4" ADD CONSTRAINT "fk_Entity4Relationship2" FOREIGN KEY ("Entity3_id") REFERENCES "public"."Entity3"("id") MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;

ALTER TABLE "public"."Entity6" ADD CONSTRAINT "fk_Entity6Relationship3" FOREIGN KEY ("Entity5_id") REFERENCES "public"."Entity5"("id") MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;

ALTER TABLE "public"."Entity8" ADD CONSTRAINT "fk_Entity8Relationship4" FOREIGN KEY ("Entity7_id") REFERENCES "public"."Entity7"("id") MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37051781
Lord Daedra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как мне кажется, в случае 1-2 и 5-6 должна добавляться какая-то дополнительная проверка на то, что для каждой существующей строчки из таблички 1 и 5 существует хотя бы одна связанная с ней строчка из таблички 2 и 6 соответственно.

[Если не придираться к терминологии, которую я использую,] прав ли я? Как правильно это реализовать наилучшим образом?

Получается, что в табличку 1 или 5 нельзя добавить новую запись, если она не будет связана с какой-нибудь записью из таблички 2 или 6, а также из таблички 2 или 6 нельзя удалять строчку если эта строчка единственная, с которой связана какая-нибудь запись из таблички 1 или 5 соответственно.

Как я понимаю, такие проверки как правило делают на уровне приложения, а не на уровне базы, но вот если хочется сделать на уровне базы, то как это должно выглядеть?
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37052002
Фотография vadiminfo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lord DaedraНе-а, похоже, что не совсем так.

Я имел в виду минимальное отличие, которое должно присутсвовать, чтобы подтвердить что генератор у вас не генерит yt обязательность связи со стороны много. Вам стоит попробовать Ервин. Он гененрил для разных СУБД, соотвествующее.

Если связь со стороны много обязательна, то наиболее просто эта обязательность реализуется в РМД с помощью ограничения целостности на значение: запрет пустых значений.
Для необязательности соотвественно отсутсвие такого ограничения.

Обязательность со стороны 1 в связи 1:M навязать декларативно в РМД, скорее всего, не получится. В таких случаях используются триггера: хранимые прцедуры, которые вызываются в ответ на события, связанные с изменение данных.

И Ервин генерит такие триггера для указанных ему СУБД. Потому Вам луче его поюзать и он Вам покажет реализации связей с подобными свойствами.

Хотел еще отметить что обычно для повышения семантичности связи используются одинаковые имена атрибутов с обоих сторон. И, наоборот, для разных атрибутов БД разные имена. У Вас же имя id - идентификатор для разных сущностей, а для связи разные имена. А ить связь может быть в общем случае, со свойствами для которых FK не подходит. Например, со стороны много могут быть не пустые значения, которых нет в табле со стороны 1. А одинаковые имена подскажут, что разработчик имел в виду какую-то связь.
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37055463
Бредятина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ViPRosБредятина,

ну при чем тут рмд
просто туфтовый инструмент не может генерировать check
При том, что связи не поддерживаются не зависимо от того, насколько хорошо "сгенерирован check":)
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37055797
Lord Daedra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Про Erwin: эта хрень (причём стоимостью несколько тыс долларов) не поддерживает Postgres, но так как вопрос для меня скорее носит познавательный характер, нежели практический и так или иначе все реляционные субд похожи, сойдёт и Oracle для примера, внизу поста листинг того что у меня получилось.

Я изучил те триггеры, что сгенерировал мне Ервин, но не нашел ничего такого, что ожидал увидеть.

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

Вообщем, сделал ещё один скриншот, там в ервине видны свойства отношения, я не понимаю блок настроек Cardinality (в чем разница *на практике* между Zero, One or More и One or More, Erwin вообще игнорирует это).. Возникает предположение, что разница есть только на схеме, а при генерации sql ервин забывает про этот блок настроек...

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

Я знаю, есть различные стандарты, http://en.wikipedia.org/wiki/SQL:2008 , например... В этих документах как-то прописывается, каким именно образом сделать такое?

На мой взгляд это должно происходить так:

- При попытке добавить (инсерт) что-то в первую табличку проверять что в этой транзакции следом за инсертом в эту первую табличку идет хотя бы один инсерт или апдэйт во вторую табличку, при этом 1_id (FK) второго инсерта/апдэйта = добавляемой 1_id (PK) первого инсерта (то есть добавляем запись в первую табличку только в том случае, если она будет связана хотя бы с кем-то из второй таблицы)

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

- При попытке обновить (апдэйт) 1_id (FK) для какой-нибудь записи из второй таблицы проверять, что у 1.1_id = old.1_id (FK) останется хотя бы кто-то один, который будет с ним связан иначе запретить такой апдэйт

- При попытке удалить (делит) кого-то из второй таблички проверять, что у родителя останутся и другие дети (хотя бы один), иначе запретить такое удаление

Вот это те 4 триггера которые я ожидал увидеть... Я не понимаю, почему ервин тоже их не сгенерировал мне... Это какая-нибудь договоренность что ли делать такие проверки не на уровне базы...

Что касается http://schemabank.com/ , о котором я писал выше - он генерирует триггеры, например для контроля связи 1:1 (чтобы не получилось 1:М), но вот конкретно момент с "не менее 1" не хочет...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
CREATE TABLE E_1
(
	1_id                 INTEGER NOT NULL 
);



CREATE UNIQUE INDEX XPKE_1 ON E_1
(1_id   ASC);



ALTER TABLE E_1
	ADD CONSTRAINT  XPKE_1 PRIMARY KEY (1_id);



CREATE TABLE E_2
(
	1_id                 INTEGER NULL ,
	2_id                 INTEGER NOT NULL 
);



CREATE UNIQUE INDEX XPKE_2 ON E_2
(2_id   ASC);



ALTER TABLE E_2
	ADD CONSTRAINT  XPKE_2 PRIMARY KEY (2_id);



ALTER TABLE E_2
	ADD (CONSTRAINT R_1 FOREIGN KEY (1_id) REFERENCES E_1 (1_id) ON DELETE SET NULL);



CREATE  TRIGGER  tD_E_1 AFTER DELETE ON E_1 for each row
-- ERwin Builtin Trigger
-- DELETE trigger on E_1 
DECLARE NUMROWS INTEGER;
BEGIN
    /* ERwin Builtin Trigger */
    /* E_1  E_2 on parent delete set null */
    /* ERWIN_RELATION:CHECKSUM="00009fe3", PARENT_OWNER="", PARENT_TABLE="E_1"
    CHILD_OWNER="", CHILD_TABLE="E_2"
    P2C_VERB_PHRASE="", C2P_VERB_PHRASE="", 
    FK_CONSTRAINT="R_1", FK_COLUMNS="1_id" */
    UPDATE E_2
      SET
        /* %SetFK(E_2,NULL) */
        E_2.1_id = NULL
      WHERE
        /* %JoinFKPK(E_2,:%Old," = "," AND") */
        E_2.1_id = :old.1_id;


-- ERwin Builtin Trigger
END;
/

CREATE  TRIGGER tU_E_1 AFTER UPDATE ON E_1 for each row
-- ERwin Builtin Trigger
-- UPDATE trigger on E_1 
DECLARE NUMROWS INTEGER;
BEGIN
  /* E_1  E_2 on parent update set null */
  /* ERWIN_RELATION:CHECKSUM="0000b96f", PARENT_OWNER="", PARENT_TABLE="E_1"
    CHILD_OWNER="", CHILD_TABLE="E_2"
    P2C_VERB_PHRASE="", C2P_VERB_PHRASE="", 
    FK_CONSTRAINT="R_1", FK_COLUMNS="1_id" */
  IF
    /* %JoinPKPK(:%Old,:%New," <> "," OR ") */
    :old.1_id <> :new.1_id
  THEN
    UPDATE E_2
      SET
        /* %SetFK(E_2,NULL) */
        E_2.1_id = NULL
      WHERE
        /* %JoinFKPK(E_2,:%Old," = ",",") */
        E_2.1_id = :old.1_id;
  END IF;


-- ERwin Builtin Trigger
END;
/


CREATE  TRIGGER tI_E_2 BEFORE INSERT ON E_2 for each row
-- ERwin Builtin Trigger
-- INSERT trigger on E_2 
DECLARE NUMROWS INTEGER;
BEGIN
    /* ERwin Builtin Trigger */
    /* E_1  E_2 on child insert set null */
    /* ERWIN_RELATION:CHECKSUM="0000c593", PARENT_OWNER="", PARENT_TABLE="E_1"
    CHILD_OWNER="", CHILD_TABLE="E_2"
    P2C_VERB_PHRASE="", C2P_VERB_PHRASE="", 
    FK_CONSTRAINT="R_1", FK_COLUMNS="1_id" */
    UPDATE E_2
      SET
        /* %SetFK(E_2,NULL) */
        E_2.1_id = NULL
      WHERE
        NOT EXISTS (
          SELECT * FROM E_1
            WHERE
              /* %JoinFKPK(:%New,E_1," = "," AND") */
              :new.1_id = E_1.1_id
        ) 
        /* %JoinPKPK(E_2,:%New," = "," AND") */
         and E_2.2_id = :new.2_id;


-- ERwin Builtin Trigger
END;
/

CREATE  TRIGGER tU_E_2 AFTER UPDATE ON E_2 for each row
-- ERwin Builtin Trigger
-- UPDATE trigger on E_2 
DECLARE NUMROWS INTEGER;
BEGIN
  /* ERwin Builtin Trigger */
  /* E_1  E_2 on child update no action */
  /* ERWIN_RELATION:CHECKSUM="0000e76e", PARENT_OWNER="", PARENT_TABLE="E_1"
    CHILD_OWNER="", CHILD_TABLE="E_2"
    P2C_VERB_PHRASE="", C2P_VERB_PHRASE="", 
    FK_CONSTRAINT="R_1", FK_COLUMNS="1_id" */
  SELECT count(*) INTO NUMROWS
    FROM E_1
    WHERE
      /* %JoinFKPK(:%New,E_1," = "," AND") */
      :new.1_id = E_1.1_id;
  IF (
    /* %NotnullFK(:%New," IS NOT NULL AND") */
    :new.1_id IS NOT NULL AND
    NUMROWS =  0 
  )
  THEN
    raise_application_error(
      - 20007 ,
      'Cannot update E_2 because E_1 does not exist.'
    );
  END IF;


-- ERwin Builtin Trigger
END;
/

...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37057770
Бредятина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lord DaedraПро Erwin: эта хрень (причём стоимостью несколько тыс долларов) не поддерживает ...
Я изучил те триггеры, что сгенерировал мне Ервин, но не нашел ничего такого, что ожидал увидеть.

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

На мой взгляд это должно происходить так:
...
Вот это те 4 триггера которые я ожидал увидеть... Я не понимаю, почему ервин тоже их не сгенерировал мне... Это какая-нибудь договоренность что ли делать такие проверки не на уровне базы...
Вы можете, конечно, и дальше игнорировать простой и понятный ответ на Ваши вопросы, если Вы считаете, что это поможет понять проблему:)
Разумеется, то что Вы говорите должно быть реализовано на уровне СУБД, которая поддерживает связи между объектами. Реляционная СУБД не поддерживает связи между объектами, и реализовать в ней нечто похожее на поддержку связей, действительно, практически невозможно. То, что Вы говорите (а Вы говорите то, что я и предположил, объясняя Вам смысл параметра Mandatory), должно поддерживаться не триггером к объекту (или отношению в РМД), а исключительно на основании АТРИБУТОВ СВЯЗИ МЕЖДУ ОБЪЕКТАМИ, КОТОРЫЕ УКАЗАНЫ ПРИ ОПИСАНИИ СВЯЗИ. При создании экземпляра первого объекта (а это всего лишь "создание" идентификатора, которого просто нет в РСУБД) должен просто автоматически создаваться связанный с ним экземпляр второго объекта. А здесь, в свою очередь, появляется, например, проблема пользовательского интерфейса (проблема, конечно, для РСУБД:))...
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37058151
Lord Daedra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Бредятина,

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

вот есть триггеры для проверки связи 1:1 (привожу ниже)

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

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

просто проверка вида "после изменения e2.e1_id (FK) проверяем, осталась ли в e2 хотя бы ещё одна FK с таким же значением" мне кажется вполне реальной... или я ошибаюсь? если подобная проверка являются технически возможной, то почему она не реализованы в ервине?

то есть может быть где-то есть статья на тему как лучше всего сделать подобные частичные проверки при переходе с этапа логического проектирования на этап физического проектирования (для реляционных субд)?

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
CREATE TABLE "public"."e1"(
"e1_id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity1_pkey" PRIMARY KEY ("e1_id")
)
WITHOUT OIDS;

CREATE TABLE "public"."e2"(
"e2_id" BIGSERIAL NOT NULL,
"e1_id" BIGSERIAL NOT NULL,
CONSTRAINT "Entity2_pkey" PRIMARY KEY ("e2_id")
)
WITHOUT OIDS;

ALTER TABLE "public"."e2" ADD CONSTRAINT "fk_Entity2Relationship1" FOREIGN KEY ("e1_id") REFERENCES "public"."e1"("e1_id") MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE;

CREATE OR REPLACE FUNCTION "func_oi_public_e2"() RETURNS TRIGGER AS '
DECLARE
	RowCount INTEGER;
BEGIN
 IF NEW."e1_id" IS NOT NULL THEN
	SELECT COUNT(*) INTO RowCount
	FROM "public"."e2"
	WHERE NEW."e1_id" = "public"."e2"."e1_id" ;
	IF (RowCount >= 1) THEN
		RAISE EXCEPTION ''Cannot insert record due to cardinality. Insertion aborted.'';
	END IF;
 END IF;
RETURN NEW;
END;'
LANGUAGE 'plpgsql';

CREATE TRIGGER "oi_public_e2"
BEFORE INSERT ON "public"."e2"
FOR EACH ROW EXECUTE PROCEDURE "func_oi_public_e2"();

CREATE OR REPLACE FUNCTION "func_ou_public_e2"() RETURNS TRIGGER AS '
DECLARE
	RowCount INTEGER;
BEGIN
 IF NEW."e1_id" != OLD."e1_id" THEN
	SELECT COUNT(*) INTO RowCount
	FROM "public"."e2"
	WHERE NEW."e1_id" = "public"."e2"."e1_id" ;
	IF (RowCount >= 1) THEN
		RAISE EXCEPTION ''Cannot update record due to cardinality. Update aborted.'';
	END IF;
 END IF;
RETURN NEW;
END;'
LANGUAGE 'plpgsql';

CREATE TRIGGER "ou_public_e2"
BEFORE UPDATE ON "public"."e2"
FOR EACH ROW EXECUTE PROCEDURE "func_ou_public_e2"();
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37058245
Фотография vadiminfo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lord Daedra
Я изучил те триггеры, что сгенерировал мне Ервин, но не нашел ничего такого, что ожидал увидеть.

Я не видел, что сгенерировал Ервин.
Я почему присоветовал Ервин.
Меня када-то интересовало каскадное обновление в связях один ко многим. И я хотел посмотреть что он сделает для MS SQL. Он сделал, то что меня разочаровало: он проверял скока записей на строне много и если больше одной, то отказывался обновлять. Меня интересовало тада прежде всего нет ли хде в Скуле средств декларативно такое сделать. Ервин сказал, что нельзя и показал пример триггера. А дальше сам уже.


Lord Daedra
На мой взгляд это должно происходить так:


Важно что это триггер, а не деклрации. Это главное, что показвает такая тулса.
Это говорит о том что такой вид связи, скорей всего, на практике редкий.
А связи один ко многим в случае обязательности, возможно, выглядят как имеющее значение для теоретических упражнений. Действительно, если соеденить две такие таблы, и запретить там не пустые значения, то получим, скорей всего, типа такую связь декларативно (конечно за счет избытка не приемлемого). Однако, это в литенратуре по БД это приводится как избитый пример аномалий удаления, обновления, добавления: товара не может быть на складе, пока его нет ни в одном магазине. А теперь мы декомпозировали, но навязали такое. Ну может, чтобы быть уверенными что это правильено таки, нуно покавыряться с триггерами и есче раз подумать правильно ли это. Ну типа чтобы те кто все же погорячился, одумались. (Шуткэ)

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


Lord Daedra
При попытке добавить (инсерт) что-то в первую табличку проверять что в этой транзакции следом за инсертом в эту первую
табличку идет хотя бы один инсерт


А если идет, но не следом? Мало ли как оно там на практике. Если тупо все делать, то, скорей всего, в триггерах на уровне записей все запомнать в коллекциях, а в триггерах на уровне инструкций проверять эти коллекции.

Есче раз хочу подчеркнуть, что Вы хорошо сделали, что стали юзать тулсы генерящие ОЦ для ознакомления с возможностями СУБД да и самими связями. Ну по, крайней мере, это один из моих, так сказать, приемчиков был када-то и потому мне понравилось что Вы пошли этим путем.
...
Рейтинг: 0 / 0
Вопрос по теории, помогите разобраться с обязательностью в связях
    #37060196
Бредятина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lord Daedra про то что не поддерживает связи между объектами я понял, но нельзя ли хотя бы частично реализовать такую проверку? то есть чтобы просто снизить число возможных ошибок...
Я же не случайно упомянул про пользовательский интерфейс. В котором, предположим, создается экземпляр первого объекта (в Вашей терминологии - запись в первой таблице).
Какую проверку реализовать???
Очевидно, что проверить атрибуты связей. В том числе, И В ВАШЕМ СЛУЧАЕ. Где они хранятся в "Вашей" реляционной СУБД (чтобы именно на стороне СУБД проверить)?
Поймите, что Вы хотите использовать, неизвестно для чего, несколько как-то взаимодействующих моделей:
1) модель, в которой описываете атрибуты связей (можно с натяжкой предположить, что в этой модели связи поддерживаются);
2) реляционную модель данных на логическом уровне;
3) какую-то модель на уровне пользовательского интерфейса;
4) и еще некую физическую модель, под которой Вы, вероятно, понимаете реализацию логической РМД в среде конкретной "реляционной" СУБД.
Используйте даже не вместо первых двух, а вместо первых трех, одну модель данных (например, похожую на ту, которая у Вас первая), и все у Вас будет получаться.
Правда, для 4) "реляционная" СУБД не подойдет:)
vadiminfo, конечно, прав, что случай довольно редкий (не концептуально, а практически), но именно невозможность его реализации превращает возможно существующую объективную необходимость в объективную невозможность:)
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Вопрос по теории, помогите разобраться с обязательностью в связях
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]