Существуют ли какие-нибудь конвенции о том, как сражаться с 1 до N, с базой данных?MySql

Форум по Mysql
Ответить
Anonymous
 Существуют ли какие-нибудь конвенции о том, как сражаться с 1 до N, с базой данных?

Сообщение Anonymous »

Я регулярно сталкиваюсь с вариантом использования в нашем бэкэнд-приложении, что ему необходимо сохранить множество данных одновременно, которые разбросаны по нескольким таблицам, но в основном это связаны с 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «MySql»