MySQL中如何避免JSON数组插入重复值(内置机制实现)
刚好之前做项目时遇到过完全一样的需求,不用依赖任何外部脚本,纯MySQL内置函数就能搞定!核心思路就是先判断目标值是否已经存在于JSON数组中,再决定是否执行插入/追加操作,下面分几种场景给你具体的实现方案:
单值追加/插入(去重)
假设你的表名为your_table,JSON数组列名为int_array_col,要操作的行通过id定位,目标值是5:
1. 追加到数组末尾
用JSON_CONTAINS判断值是否存在,结合IF语句决定是否执行JSON_ARRAY_APPEND:
UPDATE your_table SET int_array_col = IF( JSON_CONTAINS(int_array_col, CAST(5 AS JSON)), int_array_col, -- 值已存在,保持原数组不变 JSON_ARRAY_APPEND(int_array_col, '$', 5) -- 值不存在,追加到末尾 ) WHERE id = 1; -- 替换成你的行筛选条件
2. 插入到数组指定位置
如果需要插入到数组开头(或其他位置),把JSON_ARRAY_APPEND换成JSON_ARRAY_INSERT即可:
UPDATE your_table SET int_array_col = IF( JSON_CONTAINS(int_array_col, CAST(5 AS JSON)), int_array_col, JSON_ARRAY_INSERT(int_array_col, '$[0]', 5) -- '$[0]'表示插入到数组第一个位置 ) WHERE id = 1;
批量值合并去重
如果要一次性插入多个值(比如[3,5,7]),并且自动去重,可以用JSON_MERGE_PRESERVE合并数组,再通过JSON_TABLE转成行数据去重,最后重新聚合为数组:
UPDATE your_table SET int_array_col = ( SELECT JSON_ARRAYAGG(DISTINCT val) FROM JSON_TABLE( -- 合并原数组和新数组 JSON_MERGE_PRESERVE(int_array_col, '[3,5,7]'), '$[*]' COLUMNS(val INT PATH '$') -- 将JSON数组转成单行单列的表 ) AS temp_table ) WHERE id = 1;
注意事项
- 确保JSON数组里的元素都是整数类型,如果是字符串类型的数字(比如
['1',2]),JSON_CONTAINS(..., CAST(1 AS JSON))会匹配不到,需要先统一数组元素的类型。 JSON_CONTAINS的第二个参数必须是JSON类型,所以要用CAST(值 AS JSON)转换,不能直接传数字。- 如果是插入新行同时保证数组无重复,可以结合
INSERT ... ON DUPLICATE KEY UPDATE,把上面的更新逻辑放到ON DUPLICATE KEY部分即可。
内容的提问来源于stack exchange,提问作者lgc_ustc
相关产品推荐
相关产品推荐

