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));
}

我遇到的问题是更新,最简单的方法是删除该用户的所有现有条目,然后插入新条目。

$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. 使用array_diff()两次(新旧之间的差异,以及相反的一个),您将获得 2 个需要删除和添加的语言数组
  4. 根据 3 中的数组,您执行INSERT一一DELETE查询
于 2011-04-13T09:02:42.780 回答
0

这个问题似乎来自于上面示例中的 id 是人为的,解决方案是使用多列主键,也称为复合键,当我问这个问题时我不知道。

然后解决方案变成使用这样的表:

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

这提高了数据完整性,因为单个用户不能再拥有相同语言的 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 回答