Я регулярно сталкиваюсь с вариантом использования в нашем бэкэнд-приложении, что ему необходимо сохранить множество данных одновременно, которые разбросаны по нескольким таблицам, но в основном это связаны с 1 к N или рекурсивными структурами данных. Правильно. (См. Пример ниже) < /p>
Мне не очень нравится этот подход, потому что я понятия не имею, если: < /p>
Возвращенные идентификаторы правильно упорядочены (или если существует различное поведение, основанное на базе данных или конфигурации базы данных или других побочных эффектов, которые они не в состоянии. Заказано в операторе вставки < /li>
Мне нужно написать много кода шаблона, может быть более простое решение, которое я не вижу прямо сейчас < /li>
В худшем случае я ссылаюсь на неправильные данные < /li>
< /ul>
Так что мой вопрос: < /p>
В целом. JOOQ, не слепо полагаясь на порядок данных или как база данных под ним обрабатывает данные? (Автор 1 -> Книги, Автор 2 -> Книги ...) < /li>
Должен ли я использовать дополнительный столбец для подключения записей и заполнения их заранее, чтобы автогенерированные идентификаторы не нужны для этого шага? /> < /ul>
Пример пакета: < /strong> < /p>
+------------+ writes +-------------+
| Authors |---------------------
--MySQL
create table author
(
id bigint auto_increment primary key,
name varchar(32) not null,
bio varchar(32) not null
);
create table book
(
id bigint auto_increment primary key,
title varchar(32) not null,
author_id bigint not null,
constraint fk_author_book
foreign key (author_id) references author (id)
on delete cascade
)
< /code>
In order to persist the books, we need the author_ids first, so currently we do that:
List authors =
List.of(
new Author("Author 1", "Bio 1", List.of(new Book("Book1"), new Book("Book2"))),
new Author("Author 2", "Bio 2", List.of(new Book("Book3"), new Book("Book4"))),
new Author("Author 3", "Bio 3", List.of(new Book("Book5"), new Book("Book6")))
);
var authorIDs = jooq.insertInto(AUTHOR,
AUTHOR.ID,
AUTHOR.NAME,
AUTHOR.BIO
)
.valuesOfRecords(authors.stream()
.map(author -> new AuthorRecord((Long) null, author.name, author.bio))
.collect(Collectors.toList()))
.returningResult(AUTHOR.ID)
.fetchInto(Long.class);
var bookRecords = new LinkedList();
for (int i = 0; i < authorIDs.size(); i++) {
var authorId = authorIDs.get(i);
for (var book : authors.get(i).books) {
// Here is the culprit, we rely on the ids and inserted rows to be in the correct order,
// otherwise we link wrong data together
bookRecords.add(new BookRecord((Long) null, book.name, authorId));
}
}
jooq.insertInto(BOOK,
BOOK.ID,
BOOK.TITLE,
BOOK.AUTHOR_ID
)
.valuesOfRecords(bookRecords)
.execute();
< /code>
Sequential Approach with prepared statements
We also tried a "sequential" approach with two prepared statements, but the performance is a lot worse with a lot of data (~45 seconds vs. 1.5 seconds with 20k authors with 2 books each, the same logic without keepStatement(true) took ~56 seconds)
private void preparedStatement(List authors) {
try (var insertAuthorQuery =
jooq.insertInto(AUTHOR,
AUTHOR.ID,
AUTHOR.NAME,
AUTHOR.BIO)
.values((Long) null, null, null)
.returningResult(AUTHOR.ID)
.keepStatement(true)
) {
try (var insertBookQuery =
jooq.insertInto(BOOK,
BOOK.ID,
BOOK.TITLE,
BOOK.AUTHOR_ID
).values((Long) null, null, null)
.returningResult(BOOK.ID)
.keepStatement(true)) {
authors.forEach(author -> {
insertAuthorQuery.getBindValues();
insertAuthorQuery.bind(2, author.name);
insertAuthorQuery.bind(3, author.bio);
var authorID = insertAuthorQuery.fetchOneInto(Long.class);
author.books.forEach(book -> {
insertBookQuery.bind(2, book.name);
insertBookQuery.bind(3, authorID);
insertBookQuery.execute();
});
});
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/795 ... -to-the-da
Существуют ли какие-нибудь конвенции о том, как сражаться с 1 до N, с базой данных? ⇐ MySql
Форум по Mysql
1745498778
Anonymous
Я регулярно сталкиваюсь с вариантом использования в нашем бэкэнд-приложении, что ему необходимо сохранить множество данных одновременно, которые разбросаны по нескольким таблицам, но в основном это связаны с 1 к N или рекурсивными структурами данных. Правильно. (См. Пример ниже) < /p>
Мне не очень нравится этот подход, потому что я понятия не имею, если: < /p>
Возвращенные идентификаторы правильно упорядочены (или если существует различное поведение, основанное на базе данных или конфигурации базы данных или других побочных эффектов, которые они не в состоянии. Заказано в операторе вставки < /li>
Мне нужно написать много кода шаблона, может быть более простое решение, которое я не вижу прямо сейчас < /li>
В худшем случае я ссылаюсь на неправильные данные < /li>
< /ul>
Так что мой вопрос: < /p>
В целом. JOOQ, не слепо полагаясь на порядок данных или как база данных под ним обрабатывает данные? (Автор 1 -> Книги, Автор 2 -> Книги ...) < /li>
Должен ли я использовать дополнительный столбец для подключения записей и заполнения их заранее, чтобы автогенерированные идентификаторы не нужны для этого шага? /> < /ul>
[b] Пример пакета: < /strong> < /p>
+------------+ writes +-------------+
| Authors |---------------------
--MySQL
create table author
(
id bigint auto_increment primary key,
name varchar(32) not null,
bio varchar(32) not null
);
create table book
(
id bigint auto_increment primary key,
title varchar(32) not null,
author_id bigint not null,
constraint fk_author_book
foreign key (author_id) references author (id)
on delete cascade
)
< /code>
In order to persist the books, we need the author_ids first, so currently we do that:
List authors =
List.of(
new Author("Author 1", "Bio 1", List.of(new Book("Book1"), new Book("Book2"))),
new Author("Author 2", "Bio 2", List.of(new Book("Book3"), new Book("Book4"))),
new Author("Author 3", "Bio 3", List.of(new Book("Book5"), new Book("Book6")))
);
var authorIDs = jooq.insertInto(AUTHOR,
AUTHOR.ID,
AUTHOR.NAME,
AUTHOR.BIO
)
.valuesOfRecords(authors.stream()
.map(author -> new AuthorRecord((Long) null, author.name, author.bio))
.collect(Collectors.toList()))
.returningResult(AUTHOR.ID)
.fetchInto(Long.class);
var bookRecords = new LinkedList();
for (int i = 0; i < authorIDs.size(); i++) {
var authorId = authorIDs.get(i);
for (var book : authors.get(i).books) {
// Here is the culprit, we rely on the ids and inserted rows to be in the correct order,
// otherwise we link wrong data together
bookRecords.add(new BookRecord((Long) null, book.name, authorId));
}
}
jooq.insertInto(BOOK,
BOOK.ID,
BOOK.TITLE,
BOOK.AUTHOR_ID
)
.valuesOfRecords(bookRecords)
.execute();
< /code>
Sequential Approach with prepared statements[/b]
We also tried a "sequential" approach with two prepared statements, but the performance is a lot worse with a lot of data (~45 seconds vs. 1.5 seconds with 20k authors with 2 books each, the same logic without keepStatement(true) took ~56 seconds)
private void preparedStatement(List authors) {
try (var insertAuthorQuery =
jooq.insertInto(AUTHOR,
AUTHOR.ID,
AUTHOR.NAME,
AUTHOR.BIO)
.values((Long) null, null, null)
.returningResult(AUTHOR.ID)
.keepStatement(true)
) {
try (var insertBookQuery =
jooq.insertInto(BOOK,
BOOK.ID,
BOOK.TITLE,
BOOK.AUTHOR_ID
).values((Long) null, null, null)
.returningResult(BOOK.ID)
.keepStatement(true)) {
authors.forEach(author -> {
insertAuthorQuery.getBindValues();
insertAuthorQuery.bind(2, author.name);
insertAuthorQuery.bind(3, author.bio);
var authorID = insertAuthorQuery.fetchOneInto(Long.class);
author.books.forEach(book -> {
insertBookQuery.bind(2, book.name);
insertBookQuery.bind(3, authorID);
insertBookQuery.execute();
});
});
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79590636/are-there-any-jooq-conventions-on-how-to-batch-insert-1-to-n-relations-to-the-da[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия