如何在MySQL中定义数组类型字段并向其中推入整数值(Node.js操作场景)
问题解决方案
你当前代码存在两个核心问题:
- 建表时
AUTO_INCREMENT是连写关键字,拆分书写会触发语法报错,且users_liked没有设置默认空数组,首次更新时会因为空值报错 - MySQL的JSON类型不支持直接用
+运算符追加元素,需要使用官方提供的JSON操作函数实现数组修改
1. 修正后的建表语句
CREATE TABLE post_likes ( id INT PRIMARY KEY AUTO_INCREMENT, likes INT DEFAULT 0, post_id INT UNIQUE NOT NULL, users_liked JSON DEFAULT JSON_ARRAY() );
此处给post_id加了唯一索引,保证每个帖子只有一条点赞记录;同时给users_liked设置默认空数组、likes默认值为0,避免空值参与计算报错。
2. 正确的点赞更新逻辑
原代码的SQL参数传递格式错误,参数需要放在数组中传入,同时使用JSON_ARRAY_APPEND函数向JSON数组追加元素,还要增加重复点赞判断逻辑,避免同一个用户ID被多次加入数组:
// All the values of these variables are numerical values const { like, post_id, user_id } = req.body; // 先判断用户是否已经点赞 db.query( 'SELECT JSON_CONTAINS(users_liked, ?) as is_liked FROM post_likes WHERE post_id = ?', [JSON.stringify(user_id), post_id], (err, results) => { if (err) return res.status(500).send(err); // 已经点过赞直接返回 if (results[0]?.is_liked === 1) { return res.status(400).json({ message: "你已经点过赞了" }); } // 执行点赞更新 db.query( 'UPDATE post_likes SET likes = likes + ?, users_liked = JSON_ARRAY_APPEND(users_liked, "$", ?) WHERE post_id = ?', [like, user_id, post_id], (updateErr, updateResult) => { if (updateErr) return res.status(500).send(updateErr); // 如果是首次点赞,帖子还没有点赞记录则插入新数据 if (updateResult.affectedRows === 0) { db.query( 'INSERT INTO post_likes (likes, post_id, users_liked) VALUES (?, ?, JSON_ARRAY(?))', [like, post_id, user_id], (insertErr) => { if (insertErr) return res.status(500).send(insertErr); res.status(200).json({ message: "Added a like!" }); } ) return; } res.status(200).json({ message: "Added a like!" }); } ) } )
3. 拓展:取消点赞的写法
如果需要实现取消点赞功能,可以使用JSON_REMOVE函数配合JSON_SEARCH查找用户ID对应的数组索引后删除:
db.query( 'UPDATE post_likes SET likes = likes - 1, users_liked = JSON_REMOVE(users_liked, JSON_UNQUOTE(JSON_SEARCH(users_liked, "one", ?))) WHERE post_id = ?', [user_id, post_id], (err, result) => { // 自定义后续处理逻辑 } )
内容的提问来源于stack exchange,提问作者Mukhtar
相关产品推荐
相关产品推荐

