我有一个网站,其中包含其内容的投票系统。因此,我设置了一个名为 votes
的 MySQL 表,其中包含 uid
、pid
和 value
列,对应于用户投票的 UUID、帖子的基于文本的 ID 和投票的 bool 值(0
或 1
表示不喜欢和喜欢)。
我见过几个与此相关的类似问题,尽管似乎没有一个问题直接涉及在 PHP 和 MySQL 数据库之间的通信中插入和操作投票。大多数似乎是指database structure或SELECTing values 。我能找到的似乎都没有模仿我想要最终得到的系统。
与其交互的数据库和 PHP 工作正常 - 我设置了某些页面,这些页面生成 JSON,其中包含该帖子的每种类型的投票数量以及给定用户的个人投票。我遇到的问题是优化用户输入投票的过程 - 我在投票时寻找的“规则”如下:
- 如果输入的确切投票已存在(即给定的
uid
、pid
和value
均作为相同记录存在),请删除从表中投票; - 如果当前没有对该帖子和该用户进行投票,请使用所有三个值向表格添加投票;
- 如果该用户对此帖子进行了投票,但投票结果相反(不喜欢而不是喜欢,反之亦然),请更新记录以使投票匹配。
页面通过 session 变量接收 $currentUid
,并且 $cid
和 $_GET["v"]
(显然)通过获取参数。
通过在两个 MySQL 调用中使用 PDO,我已经能够在 PHP 中产生此行为(假设 $con
是通用 PDO 对象):
$test = $con->prepare("SELECT * FROM `votes` WHERE uid=UNHEX(:uid) AND pid=:pid AND value=:value");
$test->bindValue(":uid", $currentUid);
$test->bindValue(":pid", $pid, PDO::PARAM_INT);
$test->bindValue(":value", $_GET["v"], PDO::PARAM_BOOL);
$test->execute();
if($test->rowCount() > 0) {
$query = $con->prepare("DELETE FROM `votes` WHERE uid=UNHEX(:uid) AND pid=:pid AND value=:value LIMIT 1");
$query->bindValue(":uid", $currentUid);
$query->bindValue(":pid", $pid, PDO::PARAM_INT);
$query->bindValue(":value", $_GET["v"], PDO::PARAM_BOOL);
$query->execute();
} else {
$query = $con->prepare("INSERT INTO `votes` (uid, pid, value) VALUES (UNHEX(:uid), :pid, :value) ON DUPLICATE KEY UPDATE value = :value");
$query->bindValue(":uid", $currentUid);
$query->bindValue(":pid", $pid, PDO::PARAM_INT);
$query->bindValue(":value", $_GET["v"], PDO::PARAM_BOOL);
$query->execute();
}
是否有任何方法可以通过一次较大的 MySQL 调用来达到相同的效果,并且它会以任何方式影响系统的性能吗?我过去发现使用较长的 MySQL 语句可能比简单地使用 PHP 和 MySQL 混合制定解决方案花费更长的时间。可以假设系统将经常处理投票,因此性能在这里很重要。
目前,此过程大约需要 0.05 秒(通过简单的 microtime()
基准测试),如果有多个并发用户,这肯定会增加。
感谢您的帮助!请注意,我不是 SQL 语法专家,我刚刚学会了如何执行 INNER JOIN - 这就是我决定在这里发帖的原因,就好像有一些 MySQL 函数可以正是这样做的,我很难找到它。
最佳答案
似乎不太可能在一次 mysql 调用中执行相同的操作。
第一步,删除 SELECT 查询,除非您绝对需要它供以后使用。您的 ON DUPLICATE KEY 语句将为您完成此操作。
但是 DELETE 是必要的。没有 ON DUPLICATE KEY DELETE 语法。
但是,您可以编写一个在 AFTER INSERT 上运行的触发器,并删除重复项(如果有)。这是一种粗略的方法,但它会减轻 PHP 的负担。如果您绝对坚持在单个查询中完成任务,请执行此操作
关于php - MySQL 处理通过 AJAX 和 PHP 对喜欢/不喜欢系统进行投票,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31105886/