PHPとMySQLiを使用して、異なるデータベーステーブルに変数と配列を挿入する
-
05-07-2019 - |
質問
PHPとMySQLを学習しており、学習用の映画Webサイトを作成しています。
映画情報を含む変数と配列をデータベースに挿入しますが、異なるテーブルに挿入します。
これは私が今持っているものです:
include('inc/connection.php');
$conn = dbConnect();
// create SQL
$sql = 'INSERT INTO movies (movieid, title, year, runtime, plot)
VALUES(?, ?, ?, ?, ?)';
// initialize prepared statement
$stmt = $conn->stmt_init();
if ($stmt->prepare($sql)) {
// bind parameters and execute statment
$stmt->bind_param('isiis', $movieid, $title, $year, $runtime, $plot);
$stmt->execute();
}
これにより、変数がmoviesテーブルに挿入されます。
しかし、映画のジャンル、俳優、言語なども(同時に)挿入する必要があります。それらは配列にあり、異なるテーブルに(そして、おそらく異なる行にも)入っています。たとえば、ジャンルテーブルのジャンル(アクション、犯罪、ドラマ)のジャンル、およびアクターテーブルのアクターなどを含む配列...その後、多対多および1対多のテーブルを使用して、情報を表示します。
これを行う方法を誰かが私に説明できますか?データベースに複数回接続する必要がありますか?ループが必要ですか?私はPHPとMySQLiが初めてなので、できる限り説明してください。
ありがとう。
解決
INSERT
は一度に1つのテーブルのみをサポートするため、複数のテーブルに入る複雑なデータがある場合は、必ず複数の INSERT
ステートメントを実行する必要があります。
特定の $ movieid
値を movies
に挿入した場合、参照整合性を満たすために他のテーブルの行に挿入する必要がある値がわかります。 (完全に機能する例ではなく、擬似コードが続きます):
$movies_sql = 'INSERT INTO movies (movieid, title, year, runtime, plot)
VALUES(?, ?, ?, ?, ?)';
// execute ($movieid, ...)
$actors_sql = 'INSERT INTO movie_actors (movieid, actorid)
VALUES (?, ?)';
foreach ($actorlist as $actorid) {
// execute ($movieid, $actorid)
}
$lang_sql = 'INSERT INTO movie_languages (movieid, language)
VALUES (?, ?)';
foreach ($languagelist as $language) {
// execute ($movieid, $language)
}
movies
テーブルが AUTO_INCREMENT
プライマリキーを使用する場合、最初の INSERT
で生成された値を取得するには、 href = "http://php.net/mysqli_insert_id" rel = "nofollow noreferrer"> $ mysqli-> insert_id()、または組み込み関数 LAST_INSERT_ID()
。
$actors_sql = 'INSERT INTO movie_actors (movieid, actorid)
VALUES (LAST_INSERT_ID(), ?)';
foreach ($actorlist as $actorid) {
// execute ($actorid) -- only one param in this INSERT
}
LAST_INSERT_ID()
は現在のセッション中に自動生成された最新の値を報告するため、自動主キーを使用する別のテーブルに挿入すると、値が変化することに注意してください。ただし、報告される値はセッション中は安定しています。別のクライアントセッションが同時に挿入を実行している場合、 変更されません。
他のヒント
- 必要なデータベース接続は1つだけです
- はい、ループが必要です
- 各テーブルで
auto_increment
プライマリキーフィールドを使用し、$ stmt-> insert_id()
を使用して、各insert の後に値を抽出しますcode>
- 可能であれば、MySQLサーバーで
InnoDB
を使用してトランザクションサポートを取得し、関連する更新を一緒にcommit
して、スクリプトがドロップした場合にデータベースの一貫性を確保します更新の途中でアウト。より一般的なMyISAM
データベーステーブル形式はトランザクションをサポートしていません。
複数のデータベース接続を使用する必要はありません。実際、1つのアトミックトランザクションに挿入をグループ化することができなかったため、これはまったくすべきではありません。
すべきこと(要約)は次のとおりです:
BEGIN;
INSERT INTO Genres...;
INSERT INTO Actors...;
INSERT INTO othertable....;
and so on, for referenced columns/tables.
INSERT INTO Movies....;
COMMIT;
この方法では、常に一貫したデータセットが必要です。
おそらく外部キーを使用します-ベーステーブルの1つのIDを使用して他のテーブルの他のリレーションを識別します(他のテーブルのmovieidを使用して、他の値がどのムービーに属するかなどを識別します)