【发布时间】:2015-09-15 08:07:06
【问题描述】:
我有一个网站,其中包含对其内容的投票系统。因此,我设置了一个名为votes 的 MySQL 表,其中包含 uid、pid 和 value 的列,对应于用户投票的 UUID、帖子的基于文本的 ID 和布尔值投票的价值(0 或 1 表示不喜欢和喜欢)。
我见过几个类似的问题,尽管似乎没有一个直接涉及在 PHP 和 MySQL 数据库之间的通信中插入和操纵投票。大多数似乎是指database structure 或SELECTing values。我找不到的似乎都模仿了我最终想要的系统。
与之交互的数据库和 PHP 工作正常 - 我设置了某些页面,这些页面生成 JSON,其中包含该帖子的每种类型的投票数量和给定用户的个人投票。我遇到的问题是优化用户输入投票的过程 - 我在投票时寻找的“规则”如下:
- 如果输入的确切投票已经存在(即给定
uid、pid和value都作为相同的记录存在),则从表中删除该投票; - 如果当前没有对此帖子和此用户的投票,请在表格中添加所有三个值的投票;
- 如果此用户对此帖子投了票,但投票结果相反(不喜欢而不是喜欢,反之亦然),请更新记录以使投票匹配。
页面通过会话变量接收$currentUid,并通过GET 参数接收$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 函数可以做到这一点很难找到它。
【问题讨论】: