0

複数選択オプション

たとえば、IDが「10」のユーザーは、話す言語を選択できます。彼は、次のように「複数選択」または「複数チェックボックス」を使用して各言語を選択します。

<input name="lang[]" value="en" type="checkbox" />
<input name="lang[]" value="es" type="checkbox" />
<input name="lang[]" value="jp" type="checkbox" />

私が知りたいのは、これらのオプションを格納するdbテーブルはどのように見えるか、そしてサーバー側のphpはそれらをどのように挿入/更新するかということです。

これまでの私の推測

私が想像しているのは、テーブルが次のようになることです。

CREATE TABLE user_langs (id INT AUTO_INCREMENT PRIMARY KEY, lang VARCHAR, fk_user INT);

新しいユーザーに値を挿入する間、phpは単純な挿入ループを実行します。

$stmt = $pdo->prepare('INSERT INTO user_langs (lang,fk_user) VALUES(?,?)');
foreach($_POST['lang'] as $lang){
    $stmt->execute(array($lang, $user_id));
}

私が得ている問題はUPDATESにあります。最も簡単な方法は、このユーザーの既存のエントリをすべて削除し、新しいエントリを挿入することです。

$stmt1 = $pdo->prepare('DELETE FROM user_langs WHERE fk_user=?');
$stmt1->execute(array($user_id));
$stmt2 = $pdo->prepare('INSERT INTO user_langs (lang,fk_user) VALUES(?,?)');
foreach($_POST['lang'] as $lang){
    $stmt2->execute(array($lang, $user_id));
}

しかし、これがアクティブに使用されている場合、プライマリIDの増分が速すぎると思います。たとえ、IDの上限が天文学的なものであっても、データベースを汚染するという考えは好きではないので、何か間違ったことをしていると思います。 、だから私はプロがそれをどのように扱うのか知りたいです。

4

2 に答える 2

1

ある種の差分を使用することもできます。

アルゴリズム:

  1. ユーザーが選択した言語でフォームを投稿しました
  2. 現在の言語を選択します
  3. 2回使用するarray_diff()と(古いものと新しいものの違い、および反対の言語)、削除する必要がある言語と追加する必要がある言語の2つの配列を取得します。
  4. 3の配列に従って、INSERT1つと1つのDELETEクエリを実行します
于 2011-04-13T09:02:42.780 に答える
0

この問題は、上記の例のIDが人工的なものであるという事実に起因しているようです。解決策は、質問したときに気づかなかった複合キーとも呼ばれる複数列の主キーを使用することです。

解決策は、次のようなテーブルを使用するようになります。

CREATE TABLE user_langs (
  lang VARCHAR, 
  fk_user INT, 
  PRIMARY KEY(lang,fk_user)
);

これにより、1人のユーザーが同じ言語の2つのエントリを持つことができなくなるため、データの整合性が向上します。

値を挿入するには、同じことを行います。

$stmt = $pdo->prepare('INSERT INTO user_langs (lang,fk_user) VALUES(?,?)');
foreach($_POST['lang'] as $lang){
    $stmt->execute(array($lang, $user_id));
}

また、更新を処理する最も簡単な方法は、このユーザーにバインドされているすべてのエントリを削除し、同じ方法で正しいエントリを再度挿入することです。

$stmt1 = $pdo->prepare('DELETE FROM user_langs WHERE fk_user=?');
$stmt1->execute(array($user_id));
$stmt2 = $pdo->prepare('INSERT INTO user_langs (lang,fk_user) VALUES(?,?)');
foreach($_POST['lang'] as $lang){
    $stmt2->execute(array($lang, $user_id));
}

zerkmsが提案するように、すべての言語を選択してから、array_diffを実行して古い値と新しい値を見つけ、古い値を削除して新しい値を挿入することもできますが、これは3つのクエリを実行して結果を比較することを意味します。言語の中で、ユーザーが3つ以上話すことは非常にまれです。そのため、削除して再度挿入するだけが最良の選択肢のように思われます。

于 2012-05-19T09:39:16.663 に答える