php - MySQL 处理通过 AJAX 和 PHP 对喜欢/不喜欢系统进行投票

标签 php mysql database pdo

我有一个网站,其中包含其内容的投票系统。因此,我设置了一个名为 votes 的 MySQL 表,其中包含 uidpidvalue 列,对应于用户投票的 UUID、帖子的基于文本的 ID 和投票的 bool 值(01 表示不喜欢和喜欢)。

我见过几个与此相关的类似问题,尽管似乎没有一个问题直接涉及在 PHP 和 MySQL 数据库之间的通信中插入和操作投票。大多数似乎是指database structureSELECTing values 。我能找到的似乎都没有模仿我想要最终得到的系统。

与其交互的数据库和 PHP 工作正常 - 我设置了某些页面,这些页面生成 JSON,其中包含该帖子的每种类型的投票数量以及给定用户的个人投票。我遇到的问题是优化用户输入投票的过程 - 我在投票时寻找的“规则”如下:

  • 如果输入的确切投票已存在(即给定的 uidpidvalue 均作为相同记录存在),请删除从表中投票;
  • 如果当前没有对该帖子和该用户进行投票,请使用所有三个值向表格添加投票;
  • 如果该用户对此帖子进行了投票,但投票结果相反(不喜欢而不是喜欢,反之亦然),请更新记录以使投票匹配。

页面通过 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/

相关文章:

php - Laravel Queue 是否可以防止并发请求插入重复记录?

mysql - 'localhost.localdomain' 中的未知列 'field list'

Mysql 数据类型使空值 '0' 和非空值 '1'

mysql - 如何将同一表中的总值显示为一行(在 case 语句中)?

php - PHP 和 MySQL 的重音字符错误

php - Laravel 5 : How to use findOrFail() method?

mysql - 将更改迁移到模型时出现 South 错误

php - 无法使用 PHP 将数据插入我的 MySQL 数据库

java - 在 hibernate 中加载百万行

php - Laravel 白屏 - 可能的 Mcrypt 问题?