我正在为我正在工作的投资组合网站创建一个“赞”按钮,但我被自己的一些代码所困扰!
我有两个MySQL表:
我的系统布局方式。当用户“喜欢”一张图片时,我将该图片的ID保存到登录表的一列中。
UPDATE login SET likes = CONCAT(likes,':$img_id:') WHERE user_key = $user_id;
当他们与图片不一样时:
UPDATE login SET likes = REPLACE(likes,':$img_id:','') WHERE user_key = $user_id;
这将在 likes 列中输出类似于以下内容的字符串:
:456093:475829:203944:789203:
我的问题从这里开始。我正在创建一个页面,该页面允许用户查看他们喜欢的所有图片(我们将此文件称为“ Likes.php”)。 但是,喜欢的图片列表保存在登录表中,而实际的图片信息保存在 img_all 中。
那我该如何从我的登录表中获取列表并将其转换以从 img_all 中选择那些图像?我当时正在考虑使用以下混合物:
SELECT user_key FROM login WHERE likes LIKE '%:$img_id:%';
和
while();
我也想到了一个SQL查询。我知道这行不通。但是,希望它也可以帮助传达我要完成的工作!
SELECT * FROM
img_all WHERE id =
SELECT likes FROM login
WHERE likes LIKE '%:$img_id:%' AND user_key = '$user_id';
感谢您的宝贵时间!如果您对代码还有其他疑问,请告诉我!
答案 0 :(得分:1)
您快到了。除了使用子查询,您还可以将查询变成JOIN
,例如:
SELECT i.*
FROM img_all i
INNER JOIN login l ON l.likes LIKE CONCAT('%:', l.img_id, ':%')
WHERE user_id = ?
尽管这可能会解决您的问题,但请注意,将值列表存储在单个列中几乎总是表示设计不良。
访问和修改数据需要操作字符串,这对于SQL来说不容易,容易出错并且效率很低。另外,正如Bill Karwin所评论的那样,您可以为单个用户存储的点赞次数受字符串列的最大大小限制。
根据tim的评论,您应该使用单独的表存储likes
,并使用login
和img_all
表的外键。
CREATE TABLE likes (
like_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
img_id INT NOT NULL,
PRIMARY KEY (like_id),
FOREIGN KEY fk_likes_login(user_id) REFERENCES login(user_id),
FOREIGN KEY fk_likes_img(img_id) REFERENCES img_all(img_id)
);
NB:严格来说,自动递增的主键不是必需的,可以用两个外键上的复合唯一索引代替。
然后,您可以通过简单的JOIN
ed查询检索用户喜欢的所有图像:
SELECT i.*
FROM likes
INNER JOIN img_all ON img_all.img_id = likes.img_id
WHERE likes.user_id = ?