我为我的网站中的产品提供了like
表格。
问题是,我使用这个表:
CREATE TABLE IF NOT EXISTS `likes` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`user` varchar(40) NOT NULL,
`post` int(11) UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
喜欢的用户,帖子是产品ID。
like按钮向这个php发送ajax请求:
session_start();
$user = $_SESSION["user"];
$pinsid=$_POST['id'];
$stmt = $mysqli_link->prepare("SELECT * FROM likes WHERE post=? AND user=?");
$stmt->bind_param('is', $pinsid, $user);
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
$chknum = $result->num_rows;
if($chknum==0){
$stmt = $mysqli_link->prepare("INSERT INTO likes (user, post) VALUES (?,?)");
$stmt->bind_param('si', $user, $pinsid);
$stmt->execute();
$stmt->close();
$response = 'success';
}
echo json_encode($response);
我的问题是,我有来自同一个人的双重插入。例如:
1 josh 5
2 josh 5
但只有当MySQL引擎设置为InnoDB时才会发生,如果我将其更改为MyISAM,我只有1个插入。
发生了什么事?我该怎么做才能让它正常工作?
答案 0 :(得分:1)
这样做的一种方法是为用户设置一个唯一的密钥,并在like表中发布(参见https://dev.mysql.com/doc/refman/5.0/en/constraint-primary-key.html)。
如果存在,数据库将确保没有重复的用户和帖子。但是,对于已经在表中的数据,如果已经存在重复,则可能会出现问题
答案 1 :(得分:1)
但只有当MySQL引擎设置为InnoDB时才会发生,如果我将其更改为MyISAM,我只有1个插入。 怎么了?我该怎么做才能让它正常工作?
MyISAM引擎使用表级锁定,这意味着如果某个操作正在表上执行,则所有其他操作都会等待执行直到该操作完成。
InnoDb是事务性的并且使用行级锁定,因为您没有使用事务,所以没有锁定。
正如评论和答案中所提到的,最简单的解决方案是在用户和帖子上创建一个唯一约束,在这种情况下,您可以将两者都用作主键,因为自动增量列没有附加值。
创建唯一约束:
ALTER TABLE likes ADD UNIQUE KEY uk_user_post (user,post);
关于你的问题:
但它会减慢我的插入速度吗?
如果我们只谈论表中的插入操作,是的,它确实会减慢,因为在插入,更新或删除操作之后必须重建每个索引。它减慢了多少取决于索引的大小和表中的行数。
但是在当前的表结构中,user
和post
上根本没有索引,并且在您的应用程序中,您执行select并在两个列上执行查找,这将生成一个完整的表扫描。
使用唯一索引(user,post)
,您可以跳过选择,因为当违反唯一约束时,您将收到SQL错误。
此外,user
和post
是外键,因此无论如何都要编制索引。
唯一索引(user,post)
涵盖user
FK,因此您还需要post
分离的索引