mysql - 插入或更新,但不确定我是否可以进行重复的密钥更新
问题描述
创建一个书签系统。用户可以为要关注的玩家添加书签或取消添加书签。从表面上看,我认为重复的密钥更新可以与 playerID 一起使用。但是,一个玩家可能有几个用户为他添加书签。
所以它必须将 playerID 与 userID 配对。如果该对不存在,则插入。如果该对确实存在,请更新。
以下是我对重复密钥更新的内容。我将如何检查一对两列?康卡特?
$query = "INSERT INTO a_player_bookmark (playerID,bookmark,userID,username)
VALUES ('". $pid ."','". $bookmark ."','". $userID ."','". $user ."')
ON DUPLICATE KEY
UPDATE bookmark = '". $bookmark ."'
";
解决方案
对,所以通过外键关联每一列(为了完整起见),然后在2 列上创建一个唯一键,包括playerID
(follower) 和userID
(followed)。然后你可以有a -> b
, 和b -> a
,但是再次添加会导致重复键错误。这允许您使用ON DUPLICATE KEY UPDATE follower=follower
跳过插入或bookmark = VALUES(bookmark)
更新书签值。
为简洁起见,我还重命名了您的表格bookmarks
。
-- the sql query (plain text / string)
INSERT INTO bookmarks (playerID, bookmark, userID, username)
VALUES (:playerID, :bookmark, :userID, :username)
ON DUPLICATE KEY UPDATE bookmark = VALUES(bookmark)
现在在 PHP 中,我已经演示了使用 PDO 运行准备好的语句的基本概念。如果您不愿意执行 PDO,那么您可以相应地连接到查询中(自己替换占位符),但我强烈反对这样做。
//within php
$con = /* a PDO connection reference, see PDO docs for creating one */;
$query = /* our earlier statement, in string form */;
$stmt = con->prepare($query); //creates a PreparedStatement
//bind our values to the placeholders in the sql statement
$stmt->bindValue(':playerID', $pid, PDO::PARAM_INT);
$stmt->bindValue(':bookmark', $bookmark, PDO::PARAM_STR);
$stmt->bindValue(':userID', $userID, PDO::PARAM_STR);
$stmt->bindValue(':username', $user, PDO::PARAM_STR);
$stmt->execute(); //run the query
$updated = $stmt->rowCount(); //number of updated rows
展望未来,我将username
作为一列删除(似乎多余,为什么不直接引用 users 表来获取名称?),然后根据我的目的,bookmark
我什至可能会放弃它。
但在此之前,您需要确保正确的钥匙在您的桌子上。
-- I suggest removing any existing constraints beforehand
-- Relate playerID to the users table
ALTER TABLE bookmarks ADD CONSTRAINT `FK_follower` FOREIGN KEY (`playerID`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
-- Relate userID to the users table
ALTER TABLE bookmarks ADD CONSTRAINT `FK_followed` FOREIGN KEY (`userID`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
-- Relate username to the users table, if you decide to keep it
ALTER TABLE bookmarks ADD CONSTRAINT `FK_followed_name` FOREIGN KEY (`username`) REFERENCES `users` (`username`) ON UPDATE CASCADE ON DELETE CASCADE
-- Add your UNIQUE KEY for the two columns defining the relationship, aka a composite key
ALTER TABLE bookmarks ADD UNIQUE INDEX `following` (`playerID`, `userID`)
推荐阅读
- npm - 在 Linux Mint 18.3 中安装 npm
- sql-server - 如何在具有事务和回滚的单个存储过程中使用多个插入/更新/删除查询
- python - 在 Python 中操作目录的最简单方法?
- java - 在本地调试 Heroku Spring 启动应用程序?
- c++ - sprintf 和 char 数组 vs std::string
- c# - 如何从数据库制作这个可滚动的瓷砖列表的近似版本?
- cassandra - Cassandra:节点添加/删除是否需要所有集群节点都存在?
- ibm-cloud - 当 IBM Cloud 关闭时,IBM Cloud Availability Monitoring 是否工作?
- bash - 如何在 Travis CI 中触发失败?
- javascript - 如何在选择中添加选项并防止下拉框在选择标签的点击事件中消失