PHP PDO中如何按JSON格式存储的文章分类查询数据?
嘿,这个问题我之前也碰到过!主要是因为你用了JSON格式存分类,普通的等值查询没法匹配数组里的元素,我给你几个可行的解决方案:
解决方案:按JSON分类查询文章
先纠正JSON格式(重要!)
首先你写的{"cat1","cat2","cat3"}是无效的JSON格式——这不是合法的JSON对象(对象要求键值对结构,比如{"name":"cat1"}),你应该用JSON数组来存储多个分类,也就是["cat1","cat2","cat3"],这样MySQL才能正确解析和处理。
方案一:用MySQL JSON函数直接查询(适合快速解决)
如果你用的是MySQL 5.7及以上版本(现在大部分生产环境都是这个版本了),可以用内置的JSON函数轻松实现查询:
方法1:JSON_CONTAINS(最直观)
这个函数用来检查JSON字段里是否包含指定元素,用法如下:
SELECT * FROM articles WHERE JSON_CONTAINS(categories, '"cat1"');
注意第二个参数"cat1"需要用双引号包裹(符合JSON字符串的格式要求),外面再用单引号括住整个JSON值。
方法2:JSON_SEARCH
这个函数会返回匹配元素的路径,我们可以通过判断它是否非空来筛选数据:
SELECT * FROM articles WHERE JSON_SEARCH(categories, 'one', 'cat1') IS NOT NULL;
这里'one'表示只找第一个匹配的元素,如果需要匹配所有符合条件的元素可以换成'all',不过对于基础查询来说'one'就足够了。
方案二:更规范的多对多表设计(适合长期维护)
虽然JSON存储很方便,但如果你的文章数量较多,或者以后需要做分类统计、复杂关联查询等操作,JSON字段的性能和灵活性就不如传统的关系型设计了。推荐你用三张表来实现多对多关系:
articles表:存储文章核心信息(比如id,title,content,create_time等)categories表:存储分类信息(比如id,category_name等)article_category表:存储文章和分类的关联关系(article_id,category_id,这两个字段可以加联合索引提升查询速度)
然后查询指定分类的文章就可以用JOIN语句:
SELECT a.* FROM articles a JOIN article_category ac ON a.id = ac.article_id JOIN categories c ON ac.category_id = c.id WHERE c.category_name = 'cat1';
这种方式的好处是:
- 可以给关联字段加索引,查询速度更快
- 方便统计每个分类的文章数量、做复杂分类筛选等操作
- 符合关系型数据库的设计规范,数据更严谨
注意事项
- 如果你的MySQL版本低于5.7,那没法用JSON函数,这种情况下强烈建议用方案二的多表设计,不要用字符串匹配(比如
LIKE '%cat1%',这样会误匹配到cat12这类无关分类,准确率很低) - 用JSON字段的时候,一定要确保存入的是合法JSON,不然查询时会报错,可以用
JSON_VALID()函数验证格式:
SELECT JSON_VALID(categories) FROM articles;
返回1表示格式合法,0表示无效。
内容的提问来源于stack exchange,提问作者Dwayne Walsh
相关产品推荐
相关产品推荐

