Гость
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Создание двух связанных записей / 20 сообщений из 20, страница 1 из 1
16.04.2019, 10:32
    #39801927
Tar_As
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Долго искал где открыть тему, ну да ладно...

Собственно вопрос к знатокам.
Как классически грамотно решается стандартная задача.
Человек делает покупку. В покупке несколько товаров.
Есть таблица orders и таблица orders_items.
В таблице orders лежат заказы, а в таблицу orders_items нужно положить единицы каждого заказа, привязанные к id заказа таблицы orders.
Как правильно создать заказ и получить его уникальный id, сгенерированный автоинкрементом, чтобы потом с этим id ложить единицы в таблицу orders_items?
...
Рейтинг: 0 / 0
16.04.2019, 11:26
    #39801983
Serguei
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Tar_AsДолго искал где открыть тему, ну да ладно...

Плохо искали. Есть раздел Программирование.
...
Рейтинг: 0 / 0
16.04.2019, 11:31
    #39801990
s_ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Tar_AsДолго искал где открыть тему, ну да ладно...

Собственно вопрос к знатокам.
Как классически грамотно решается стандартная задача.
Человек делает покупку. В покупке несколько товаров.
Есть таблица orders и таблица orders_items.
В таблице orders лежат заказы, а в таблицу orders_items нужно положить единицы каждого заказа, привязанные к id заказа таблицы orders.
Как правильно создать заказ и получить его уникальный id, сгенерированный автоинкрементом, чтобы потом с этим id ложить единицы в таблицу orders_items?
Думаю, вам вот это надо использовать:
https://docs.oracle.com/cd/B28359_01/server.111/b28310/views002.htm#ADMIN11792
...
Рейтинг: 0 / 0
16.04.2019, 18:36
    #39802364
Tar_As
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
s_ustinovДумаю, вам вот это надо использовать:
https://docs.oracle.com/cd/B28359_01/server.111/b28310/views002.htm#ADMIN11792

А можно, так сказать, в двух словах - чего он хочет (классика)...?
О чем там, о каком механизме?
...
Рейтинг: 0 / 0
16.04.2019, 18:48
    #39802367
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Tar_AsКак правильно создать заказ и получить его уникальный id, сгенерированный автоинкрементом,
чтобы потом с этим id ложить единицы в таблицу orders_items?

а) returning
б) выкинуть автоинкремент
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
17.04.2019, 01:05
    #39802416
Tar_As
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Dimitry Sibiryakovа) returning
б) выкинуть автоинкремент


Это вроде как только для сохраненных функций? Или нет?

А если без функций, то ничего лучше в голову не лезет

Код: sql
1.
2.
3.
4.
START TRANSACTION;
INSERT INTO orders (a,b,c) VALUES(1,2,3);
SELECT MAX(id) as max_id FROM orders;
COMMIT;



т.е. без транзакции никак?

еще пишут про С API
https://dev.mysql.com/doc/refman/8.0/en/mysql-insert-id.html

Других решений нет?
А ведь задача с автоинкрементом не только частая, но я бы сказал постоянная. Такое впечатление, что разрабы как страусы, головы в песок воткнули и типа не видят и не знают о страданиях....
...
Рейтинг: 0 / 0
17.04.2019, 01:44
    #39802419
Relic Hunter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Tar_As,
for MySQL
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE TABLE a_table1 (
  id INT(11) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
  name VARCHAR(50) DEFAULT NULL,
  PRIMARY KEY (id),
  UNIQUE INDEX id (id)
);

insert into a_table1(name) values('123');SELECT LAST_INSERT_ID();
...
Рейтинг: 0 / 0
17.04.2019, 11:18
    #39802601
s_ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Люди, вы чего?
Sequences именно для таких задач и придуманы. Нафиг автоинкремент и потом читать последнее значение?

Получаем новое значение последовательности и присваиваем переменной. И потом делаем ДВА инсерта в ДВЕ таблицы в одной транзакции, используя эту переменную как значение ID. Всё.
И автоинкремент из таблицы убрать, разумеется.
...
Рейтинг: 0 / 0
17.04.2019, 13:38
    #39802763
skyANA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
s_ustinovЛюди, вы чего?
Sequences именно для таких задач и придуманы. Нафиг автоинкремент и потом читать последнее значение?
Так ведь речь про MySQL, там Sequence через AUTO_INCREMENT
...
Рейтинг: 0 / 0
17.04.2019, 14:05
    #39802804
s_ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
skyANAs_ustinovЛюди, вы чего?
Sequences именно для таких задач и придуманы. Нафиг автоинкремент и потом читать последнее значение?
Так ведь речь про MySQL, там Sequence через AUTO_INCREMENT
Блин, я почему-то подумал, что оракл.
...
Рейтинг: 0 / 0
17.04.2019, 15:37
    #39802892
Cane Cat Fisher
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
skyANAs_ustinovЛюди, вы чего?
Sequences именно для таких задач и придуманы. Нафиг автоинкремент и потом читать последнее значение?
Так ведь речь про MySQL, там Sequence через AUTO_INCREMENT

Так там вроде сто лет назад было что-то вроде LAST_INSERT_ID() для этого случая?
...
Рейтинг: 0 / 0
17.04.2019, 17:44
    #39802998
Tar_As
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Код: sql
1.
insert into a_table1(name) values('123');SELECT LAST_INSERT_ID();



этот вариант есть и существует, но не влезет ли между ними другой insert от другого вопрошающего без транзакции?
...
Рейтинг: 0 / 0
17.04.2019, 18:38
    #39803011
Cane Cat Fisher
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Tar_As
Код: sql
1.
insert into a_table1(name) values('123');SELECT LAST_INSERT_ID();



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

Нет, не влезет. Ибо сказано:

MySQL 8.0 Reference ManualThe ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.

Правда, надо учитывать:

Is MySql's LAST_INSERT_ID() function guaranteed to be correct?
A couple caveats I'd like to point out when using LAST_INSERT_ID:

I know you mentioned single-row inserts. But when doing multiple-row inserts, LAST_INSERT_ID() will return the value of the first row inserted (not the last).

If the insert failed, LAST_INSERT_ID() would be undefined. The same is true for automatic rollbacks of transactions (due to errors).

If you do an insert in a transaction that succeeds, and you still issue a ROLLBACK, LAST_INSERT_ID() would be left as it was prior to the rollback.

There are a couple caveats when using AUTO_INCREMENT and LAST_INSERT_ID in statement-based replication. The first being when used in a trigger or function. The second being the less-common scenario where your auto_increment column is part of a composite primary key and is not the first column in the key.
...
Рейтинг: 0 / 0
17.04.2019, 18:57
    #39803015
Relic Hunter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
s_ustinovskyANAпропущено...

Так ведь речь про MySQL, там Sequence через AUTO_INCREMENT
Блин, я почему-то подумал, что оракл.

Даже если бы там был 300 раз Оракел этоже полный ппц по дизайну. В оракле поле id никак не защищено, т.к. это не автоинкремент и программеры могут залить туда любой мусор. Откуда программеры знают, какую сиквенс дергать, ведь они никак не привязаны к таблицам? Поэтому во вменяемом дизайне никtо даже права на сиквенсы не выдаёт. Второе, на поле id почти всегда есть триггер, в котором и обязано генерироваться id, и какое он там сгенерит значение - большой вопрос. insert ... returning into ... наше все. За приведенный вами метод заполнения id нужно бить линейкой по рукам, уж извините.
...
Рейтинг: 0 / 0
17.04.2019, 19:05
    #39803017
Relic Hunter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Cane Cat FisherTar_As
Код: sql
1.
insert into a_table1(name) values('123');SELECT LAST_INSERT_ID();



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

Нет, не влезет. Ибо сказано:

MySQL 8.0 Reference ManualThe ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.

Правда, надо учитывать:

Is MySql's LAST_INSERT_ID() function guaranteed to be correct?A couple caveats I'd like to point out when using LAST_INSERT_ID:

I know you mentioned single-row inserts. But when doing multiple-row inserts, LAST_INSERT_ID() will return the value of the first row inserted (not the last).

If the insert failed, LAST_INSERT_ID() would be undefined. The same is true for automatic rollbacks of transactions (due to errors).

If you do an insert in a transaction that succeeds, and you still issue a ROLLBACK, LAST_INSERT_ID() would be left as it was prior to the rollback.

There are a couple caveats when using AUTO_INCREMENT and LAST_INSERT_ID in statement-based replication. The first being when used in a trigger or function. The second being the less-common scenario where your auto_increment column is part of a composite primary key and is not the first column in the key.



Ну много строчные инсерты как-то не интересны. А вот при исползовании пула соединений могут быть варианты. Поэтому нужно делать, как я написал, inset и select в одной команде, и не отпускать соединение в пул до получения id.
...
Рейтинг: 0 / 0
17.04.2019, 22:18
    #39803075
Дмитрий Мух
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Cane Cat FisherskyANAпропущено...

Так ведь речь про MySQL, там Sequence через AUTO_INCREMENT

Так там вроде сто лет назад было что-то вроде LAST_INSERT_ID() для этого случая?
Так-то за 4 сообщения до вашего пример с AUTO_INCREMENT и LAST_INSERT_ID().
Зачем на сто лет назад смотреть? :)
...
Рейтинг: 0 / 0
18.04.2019, 00:54
    #39803095
s_ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Relic Hunters_ustinovпропущено...

Блин, я почему-то подумал, что оракл.

Даже если бы там был 300 раз Оракел этоже полный ппц по дизайну. В оракле поле id никак не защищено, т.к. это не автоинкремент и программеры могут залить туда любой мусор. Откуда программеры знают, какую сиквенс дергать, ведь они никак не привязаны к таблицам? Поэтому во вменяемом дизайне никtо даже права на сиквенсы не выдаёт. Второе, на поле id почти всегда есть триггер, в котором и обязано генерироваться id, и какое он там сгенерит значение - большой вопрос. insert ... returning into ... наше все. За приведенный вами метод заполнения id нужно бить линейкой по рукам, уж извините.
То есть разработчики СУБД, специально создавшие сиквенсы именно для таких целей - идиоты, а вы крутой спец, знающий про правильный дизайн. :))
А уж про программистов, не знающих "какую сиквенс дергать, ведь они никак не привязаны к таблицам" - это вообще зашибись аргумент.
...
Рейтинг: 0 / 0
18.04.2019, 01:13
    #39803096
Relic Hunter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
s_ustinovRelic Hunterпропущено...


Даже если бы там был 300 раз Оракел этоже полный ппц по дизайну. В оракле поле id никак не защищено, т.к. это не автоинкремент и программеры могут залить туда любой мусор. Откуда программеры знают, какую сиквенс дергать, ведь они никак не привязаны к таблицам? Поэтому во вменяемом дизайне никtо даже права на сиквенсы не выдаёт. Второе, на поле id почти всегда есть триггер, в котором и обязано генерироваться id, и какое он там сгенерит значение - большой вопрос. insert ... returning into ... наше все. За приведенный вами метод заполнения id нужно бить линейкой по рукам, уж извините.
То есть разработчики СУБД, специально создавшие сиквенсы именно для таких целей - идиоты, а вы крутой спец, знающий про правильный дизайн. :))
А уж про программистов, не знающих "какую сиквенс дергать, ведь они никак не привязаны к таблицам" - это вообще зашибись аргумент.

А где я говорил про разработчиков СУБД, например? Я говорил, что конечным пользователям на сиквенсы прав выдавать нельзя. Накосячат с именами в коде так, что админа отправят на принудительное психиатрическое лечение. Сиквенсы нужно прятать в триггеры. Это многолетняя практика, мэн. Но вам можно делать и по-своему, как говорится "приятного хождения по граблям". )) Я в своей роте такого не допускал.
...
Рейтинг: 0 / 0
18.04.2019, 08:50
    #39803137
Ivan Durak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
а потом с целью оптимизации трегеры заменяются на

Create table table1
(
COLUMN_ID number default on null seq_table1,nextval not null
...
)
и получаем красивый автоинкремент как в лучших домах Ms & My сиквелов.
...
Рейтинг: 0 / 0
18.04.2019, 09:25
    #39803152
s_ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание двух связанных записей
Relic Hunters_ustinovпропущено...

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

А где я говорил про разработчиков СУБД, например? Я говорил, что конечным пользователям на сиквенсы прав выдавать нельзя. Накосячат с именами в коде так, что админа отправят на принудительное психиатрическое лечение. Сиквенсы нужно прятать в триггеры. Это многолетняя практика, мэн. Но вам можно делать и по-своему, как говорится "приятного хождения по граблям". )) Я в своей роте такого не допускал.


Ну и как к задаче, описанной ТС (запись документа с заголовком и строками) автоинкремент или триггер подойдет лучше, чем обычная последовательность? Тем, что в транзакцию нужно лишний селект добавлять? :))
...
Рейтинг: 0 / 0
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Создание двух связанных записей / 20 сообщений из 20, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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