LINUX.ORG.RU

H2 insert многие ко многим

 ,


0

2

Имеется 2 таблицы:

Post
------
post_id (key)
address
security_id (foreign key)
Employee
------
id (key
name
main_post_id (foreign key)

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

Пример исключения:

[2019-10-13 18:15:36] [23506][23506] Referential integrity constraint violation: "CONSTRAINT_75: PUBLIC.EMPLOYEE FOREIGN KEY(MAIN_POST_ID) REFERENCES PUBLIC.POST(ID) (1)"; SQL statement:
[2019-10-13 18:15:36] insert into EMPLOYEE
[2019-10-13 18:15:36] (SECOND_NAME, FIRST_NAME, MIDDLE_NAME, PHONE_NUMBER, PSD_EXPIRATION_DATE, TRAINING_EXPIRATION_DATE, IS_RESERVED, MAIN_POST_ID, POSITION_ID, CATEGORY_ID, NOTE)
[2019-10-13 18:15:36] values ( 'n', 'f', 'm', '+9143114', 2010-12-12, 2010-12-12, 0, 1, 1, 1, '' ) [23506-196]
Ответ на: комментарий от no-such-file

А потом update? Просто чтобы уточнить: это h2 и derby такие неудобные реликты или просто sqlite упрощенный и простой?

JAkutenshi ★★
() автор топика
Ответ на: комментарий от JAkutenshi

это h2 и derby такие неудобные реликты или просто sqlite упрощенный и простой?

Это ты зачем-то замутил взаиморекурсивные ссылки, вместо того, чтобы сделать отдельную таблицу


Employee_main_post
----
employee_id
post_id

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Точно, спасибо.

В SQLite можно было и без него. Это плохо или хорошо с т.з. подхода? Т.е. мне лично было удобнее, но, судя по всему, так никто не делает - почему?

JAkutenshi ★★
() автор топика
Ответ на: комментарий от JAkutenshi

Это плохо или хорошо с т.з. подхода

Может быть по-разному, в зависимости от конкретной ситуации.

судя по всему, так никто не делает

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

no-such-file ★★★★★
()

Во-первых, многие ко многим при проектировании БД под запретом. Так делать не надо.

Во-вторых, а где у вас тут многие ко многим? У вас же к одному post могут быть привязаны многие employee, но у одного employee всегда один post? Или нет?

В третьих, в sqlite по умолчанию foreign keys отключены, их надо включать специальной прагмой. Без неё - вообще не проверяется.

И в четвертых, во всех базах данных, умеющих в FK, сначала бы создавался post, а уж потом заполнялись его сотрудники, то есть insert'ов было бы два.

Или я вас непрваильно понял?

anonymous
()
Ответ на: комментарий от anonymous

Если у вас POST.SECURITY_ID ссылается на EMPLOYEE - то тут JAkutenshi все верно сказал, нужна еще одна таблица. Даже если не учитывать то, что пишут в умных книжках - что вы будете делать, когда у вас заведется второй security_id, junior_security_id, и т.д. - еще столбцы добавлять?

anonymous
()
Ответ на: комментарий от no-such-file

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

Ну, я как раз не знаю «как обычно». SQLite не запрещал — так и делал, пока не столкнулся с H2. Про промежуточные таблицы видел, но было лень их выделять.

JAkutenshi ★★
() автор топика
Ответ на: комментарий от anonymous

Во-первых, многие ко многим при проектировании БД под запретом. Так делать не надо.

А можно уточнить почему? Различные варианты представления сущностей (я обычно ER-диаграммы делаю) описывают этот случай и запрета я не встречал.

Во-вторых, а где у вас тут многие ко многим?

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

в sqlite по умолчанию foreign keys отключены

Всмысле проверка на валидность?

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

Да-а-а, я как раз в H2 портировал схему из SQLite-а и выяснил что я как-то не так понимал мир много лет. Например, в том же примере я ставил в CREATE сразу FK, отчего H2 не видел нижеопределенную таблицу и не воспринимал мою портянку, из-за чего сначала описывал схему, а потом через ALTER пришлось добавлять FK. Потом я подумал, что все позади, но пришел ко вставкам и тут понял, что скорее-всего дело не в диалекте.

Или я вас непрваильно понял

Да нет, в целом все так, да.

JAkutenshi ★★
() автор топика
Ответ на: комментарий от anonymous

то тут JAkutenshi все верно сказал

Ну, не я, а no-such-file, я в две таблицы делал.

еще столбцы добавлять

Ну, формально-то это дело одной команды. Как раз в моей ситуации, если всего 2 таблицы — на пост и охрану, то будет проблема, добавлять к посту столбец. Если завести отдельную таблицу из пересечений поста и охранника — сначала main, потом junior, если понадобится. Вроде бы все хорошо.

JAkutenshi ★★
() автор топика
Ответ на: комментарий от Legioner

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

JAkutenshi ★★
() автор топика
Ответ на: комментарий от Legioner

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

Спасибо~

JAkutenshi ★★
() автор топика
Ответ на: комментарий от JAkutenshi

Смешно то, что тут не многие ко многим

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

no-such-file ★★★★★
()

в одной транзакции же!

bvn13 ★★★★★
()
Ответ на: комментарий от no-such-file

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

JAkutenshi ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.