官方文档:https://dev.mysql.com/doc/refman/5.7/en/json-function-reference.html
软件版本:mysql5.7
从5.7开始,mysql提供了一些查询、操作的json函数,这些函数不仅仅可作用于json类型的字段,而且能支持text类型,只要保证是json字符串。只是如果text字段中含有不是json格式的字符串,mysql就直接报错,直接异常反馈是项目中接受不了的,另一方面,缺乏json内多级的查询功能,所以json函数显得有点鸡肋,很多开发更愿意在业务层操作json串,以便于抛出具体的异常提示。
在8出世之后,有一条重要的更新就是json增强,在此json的存在意义就像mongodb的document嵌套document,很明显mysql想用json来兼容nosql,或者说借用nosql的优点。然后什么场景比较适合使用mysql的json呢。
案例:学生分数排行
数据准备:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`student_name` varchar(36) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `student` VALUES (1, '黄大');
INSERT INTO `student` VALUES (2, '李二');
INSERT INTO `student` VALUES (3, '韩三');
INSERT INTO `student` VALUES (4, '冯四');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `score2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) DEFAULT NULL,
`grade` int(8) DEFAULT NULL,
`subject` varchar(36) DEFAULT NULL,
`score` smallint(4) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of score2
-- ----------------------------
BEGIN;
INSERT INTO `score2` VALUES (1, 1, 1, 'maths', 90);
INSERT INTO `score2` VALUES (2, 1, 1, 'english', 60);
INSERT INTO `score2` VALUES (3, 1, 1, 'language', 55);
INSERT INTO `score2` VALUES (4, 1, 1, 'physic', 100);
INSERT INTO `score2` VALUES (5, 2, 1, 'maths', 90);
INSERT INTO `score2` VALUES (6, 2, 1, 'english', 60);
INSERT INTO `score2` VALUES (7, 2, 1, 'language', 65);
INSERT INTO `score2` VALUES (8, 2, 1, 'physic', 100);
INSERT INTO `score2` VALUES (9, 2, 2, 'maths', 90);
INSERT INTO `score2` VALUES (10, 2, 2, 'english', 60);
INSERT INTO `score2` VALUES (11, 2, 2, 'language', 65);
INSERT INTO `score2` VALUES (12, 2, 2, 'physic', 100);
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
总分排行及其各科成绩组成:
mysql> select student_id,student_name,grade,json_objectagg(subject,score) as item,sum(score) as sum_score from score2 join student on student.id=score2.student_id group by student_id,grade order by sum_score desc;
同理,一张订单包含多个分项也可以用这个方式来查询。
还有。。。。一时间想不到了,上面说的那种情况也是可以用一对多的记录方式来存储,所以说当前在下觉得除非是旧项目二次开发,针对已有的数据结构可能会用到,新项目新数据结构就显得很鸡肋了。欢迎大佬有新的想法来之指正。