Связь один ко многим в C++
Связь один ко многим означает: одна строка родителя может иметь много дочерних, а каждая дочерняя указывает ровно на одного родителя.
В таблице книг колонка author_id повторяет
один и тот же номер автора. Два автора и три книги
с общими внешними ключами оформляют так:
#include <iostream>
#include <sqlite3.h>
int main() {
sqlite3* db = nullptr;
if (sqlite3_open("otm_books.db", &db) != SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
sqlite3_exec(
db, "PRAGMA foreign_keys = ON",
nullptr, nullptr, nullptr
);
sqlite3_exec(
db,
"CREATE TABLE IF NOT EXISTS authors ("
"id INTEGER PRIMARY KEY, name TEXT NOT NULL)",
nullptr, nullptr, nullptr
);
sqlite3_exec(
db,
"CREATE TABLE IF NOT EXISTS books ("
"id INTEGER PRIMARY KEY, author_id INTEGER NOT NULL, "
"title TEXT NOT NULL, "
"FOREIGN KEY (author_id) REFERENCES authors (id))",
nullptr, nullptr, nullptr
);
sqlite3_stmt* author = nullptr;
sqlite3_prepare_v2(
db, "INSERT INTO authors (name) VALUES (?)",
-1, &author, nullptr
);
sqlite3_bind_text(author, 1, "Mira Cole", -1, SQLITE_STATIC);
sqlite3_step(author);
sqlite3_reset(author);
sqlite3_bind_text(author, 1, "Jon Reed", -1, SQLITE_STATIC);
sqlite3_step(author);
sqlite3_finalize(author);
sqlite3_stmt* book = nullptr;
sqlite3_prepare_v2(
db,
"INSERT INTO books (author_id, title) VALUES (?, ?)",
-1, &book, nullptr
);
sqlite3_bind_int(book, 1, 1);
sqlite3_bind_text(book, 2, "Quiet Harbor", -1, SQLITE_STATIC);
sqlite3_step(book);
sqlite3_reset(book);
sqlite3_bind_int(book, 1, 1);
sqlite3_bind_text(book, 2, "Stone Path", -1, SQLITE_STATIC);
sqlite3_step(book);
sqlite3_reset(book);
sqlite3_bind_int(book, 1, 2);
sqlite3_bind_text(book, 2, "Wide Field", -1, SQLITE_STATIC);
sqlite3_step(book);
sqlite3_finalize(book);
sqlite3_close(db);
return 0;
}
Подсчет книг у автора выполняют фильтром по
author_id. У первого автора в примере
получается две строки:
#include <iostream>
#include <sqlite3.h>
int main() {
sqlite3* db = nullptr;
if (sqlite3_open("otm_books.db", &db) != SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
sqlite3_exec(
db, "PRAGMA foreign_keys = ON",
nullptr, nullptr, nullptr
);
sqlite3_exec(
db,
"CREATE TABLE IF NOT EXISTS authors ("
"id INTEGER PRIMARY KEY, name TEXT NOT NULL)",
nullptr, nullptr, nullptr
);
sqlite3_exec(
db,
"CREATE TABLE IF NOT EXISTS books ("
"id INTEGER PRIMARY KEY, author_id INTEGER NOT NULL, "
"title TEXT NOT NULL, "
"FOREIGN KEY (author_id) REFERENCES authors (id))",
nullptr, nullptr, nullptr
);
sqlite3_stmt* author = nullptr;
sqlite3_prepare_v2(
db, "INSERT INTO authors (name) VALUES (?)",
-1, &author, nullptr
);
sqlite3_bind_text(author, 1, "Mira Cole", -1, SQLITE_STATIC);
sqlite3_step(author);
sqlite3_finalize(author);
sqlite3_stmt* book = nullptr;
sqlite3_prepare_v2(
db,
"INSERT INTO books (author_id, title) VALUES (?, ?)",
-1, &book, nullptr
);
sqlite3_bind_int(book, 1, 1);
sqlite3_bind_text(book, 2, "Quiet Harbor", -1, SQLITE_STATIC);
sqlite3_step(book);
sqlite3_reset(book);
sqlite3_bind_int(book, 1, 1);
sqlite3_bind_text(book, 2, "Stone Path", -1, SQLITE_STATIC);
sqlite3_step(book);
sqlite3_finalize(book);
sqlite3_stmt* count = nullptr;
sqlite3_prepare_v2(
db,
"SELECT COUNT(*) FROM books WHERE author_id = ?",
-1, &count, nullptr
);
sqlite3_bind_int(count, 1, 1);
if (sqlite3_step(count) == SQLITE_ROW) {
std::cout << sqlite3_column_int(count, 0) << "\n";
}
sqlite3_finalize(count);
sqlite3_close(db);
return 0;
}
В otm_books.db добавьте автора
"Eva Nash" и две его книги. Выведите
число книг с author_id этого автора.
Создайте otm_brands.db с таблицами
brands и models. Одной марке
сопоставьте три модели и выведите их названия.