问题描述
|
多选选项
例如,ID为“ 10”的用户可以选择他说什么语言。
他使用\“多个选择\”或\“多个复选框\”选择每种语言,如下所示:
<input name=\"lang[]\" value=\"en\" type=\"checkbox\" />
<input name=\"lang[]\" value=\"es\" type=\"checkbox\" />
<input name=\"lang[]\" value=\"jp\" type=\"checkbox\" />
我想知道的是,存储这些选项的数据库表的外观如何,服务器端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,?)\');
foreach($_POST[\'lang\'] as $lang){
$stmt2->execute(array($lang,$user_id));
}
但是我认为,如果主动使用主ID,即使ID的上限是天文数字,它也会过度增加主ID,我不喜欢污染数据库的想法,所以我猜我\做错了,所以我想知道专业人士是如何处理的。
解决方法
您还可以使用某种差异。
算法:
用户使用所选语言发布了表单
您选择当前语言
两次使用
array_diff()
(新旧之间的区别,以及对立的相反),您将获得2种需要删除和添加的语言数组
根据3中的数组,您执行一次INSERT
和一次DELETE
查询
,这个问题似乎是由于上述示例中的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,?)\');
foreach($_POST[\'lang\'] as $lang){
$stmt2->execute(array($lang,$user_id));
}
您也可以按照zerkms的建议进行操作,选择所有语言,然后运行array_diff查找旧值和新值,然后删除旧值并插入新值,但这意味着要运行3个查询并比较结果,以防万一对于多种语言,用户说3种以上的语言非常罕见,这就是为什么仅删除和再次插入似乎是最佳选择的原因。