Я хотел бы создать небольшую базу данных книг, используя Go и sqlite. Я взял основное из этого совета примеры внешнего ключа SQLite и немного переработал его.
package main
import (
"database/sql"
...
_ "github.com/mattn/go-sqlite3"
)
...
db, err := sql.Open("sqlite3", "./foo.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
sqlStmt := `
create table books (
id integer primary key autoincrement,
title text
);
create table booksauthors (
bookid integer references books(id),
uthorid integer references authors(id) ON DELETE CASCADE ON UPDATE CASCADE
);
create table authors (
id integer primary key autoincrement,
fname text,
mname text,
lname text,
unique (fname, mname, lname) on conflict ignore
);
`
Итак, я хотел бы сохранить список уникальных авторов и поддерживать связь «многие ко многим» с таблицами книг (у одной книги может быть более одного автора, и автор может написать более одной книги).
Затем я просто добавляю книги в цикл, получаю LastIndexID и помещаю его в соединительную таблицу (код уменьшен для иллюстрации, b — структура книги):
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
res, err := db.Exec("Insert into books(title) values(?)", b.Title)
if err != nil {
log.Fatal(err)
}
b_id, _ := res.LastInsertId()
for _, a := range b.Authors {
res, err = db.Exec("Insert into authors(fname, mname, lname) values(?, ?, ?)", a.Fname, a.Mname, a.Lname)
if err != nil {
log.Fatal(err)
}
a_id, _ := res.LastInsertId()
fmt.Println(a_id, b_id, a)
res, err = db.Exec("Insert into booksauthors(bookid, authorid) values(?, ?)", b_id, a_id)
if err != nil {
log.Fatal(err)
}
}
tx.Commit()
Здесь возникает проблема - a_id увеличивается, если я добавляю более одной книги одного и того же автора, но таблица соединений содержит более старое его значение. Например:
Books:
id | Title
---|--------------------
1 | Atlas Shrugged pt.1
2 | Atlas Shrugged pt.2
3 | Atlas Shrugged pt.3
Authors:
id | Fname | Mname | Lname
---|-------|-------|------
702| Ayn | | Rand
Junction table:
BookId | AuthorID
-------|---------
1 | 700
2 | 701
3 | 702
What I want - Junction table:
BookId | AuthorID
-------|---------
1 | 702
2 | 702
3 | 702
Как исправить, чтобы в таблице отображался правильный AuthorId? Я не хочу использовать GORM или любой из инструментов ORM и пытаться решить его с помощью чистого (ну, более или менее) SQL.
Одно из решений, которое я вижу сейчас, я могу сначала ВЫБРАТЬ, затем ВСТАВИТЬ, если ничего не найдено, а затем снова ВЫБРАТЬ, однако я не уверен, насколько эта идея идиоматична. Обратите внимание, что мне нужно добавить значительное количество записей.