从数据库查到的数据,是这种JSON格式,建和值都是双引号包裹
[ [ { id: 21, name: 'why', password: 'e10adc3949ba59abbe56e057f20f883e', createAt: 2024-03-11T06:55:35.000Z, updateAt: 2024-03-11T06:55:35.000Z } ], [ `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(30) NOT NULL UNIQUE_KEY, `password` VARCHAR(50) NOT NULL, `createAt` TIMESTAMP(19) NOT NULL, `updateAt` TIMESTAMP(19) NOT NULL ON UPDATE CURRENT_TIMESTAMP ] ]
要解构[ ]返回这个,[values]
获取第一个是我们需要的,第二个不需要,是表数据的相关信息
例如
[ { id: 21, name: 'why', password: 'e10adc3949ba59abbe56e057f20f883e', createAt: 2024-03-11T06:55:35.000Z, updateAt: 2024-03-11T06:55:35.000Z } ]
第二个是这样的[values,xxx ]
[ { id: 21, name: 'why', password: 'e10adc3949ba59abbe56e057f20f883e', createAt: 2024-03-11T06:55:35.000Z, updateAt: 2024-03-11T06:55:35.000Z } ] [ `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(30) NOT NULL UNIQUE_KEY, `password` VARCHAR(50) NOT NULL, `createAt` TIMESTAMP(19) NOT NULL, `updateAt` TIMESTAMP(19) NOT NULL ON UPDATE CURRENT_TIMESTAMP ]
若要拿到数据的对象形式,前端需要的话把JSON对象转为字符串
还要解构[ ]
{ id: 21, name: 'why', password: 'e10adc3949ba59abbe56e057f20f883e', createAt: 2024-03-11T06:55:35.000Z, updateAt: 2024-03-11T06:55:35.000Z }
实操
1. ---- 创建用户表 CREATE TABLE IF NOT EXISTS`user`( id int PRIMARY KEY AUTO_INCREMENT, name VARCHAR(30) UNIQUE NOT NULL, password VARCHAR(50) NOT NULL, createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); -- 发表动态表 CREATE TABLE IF NOT EXISTS`moment`( id int PRIMARY KEY AUTO_INCREMENT, content VARCHAR(1000) NOT NULL, user_id INT NOT NULL COMMENT '评论者外键,来寻找评论者', createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY(user_id) REFERENCES user(id) ); 2.
SELECT m.id id,m.content content, m.createAt createTime, m.updateAt updateTime, JSON_OBJECT('id',u.id,'name',u.name,'createTime',u.createAt,'updateTime',u.updateAt) user FROM moment m LEFT JOIN user u ON m.user_id=u.id LIMIT 10 OFFSET 0;
据外键组织数据
数据关系
一对一、一对多、多对多都是关系型数据库中常见的数据关系类型。以下是对每种关系的举例:
一对一关系
例子:一个公民有一个唯一的身份证。
解释:在这个例子中,每个公民都与一个唯一的身份证相关联,同时每个身份证也只与一个公民相关联。这是一种典型的一对一关系。
一对多关系
例子:一个班级有多个学生。
解释:在这个例子中,每个班级可以有多个学生,但每个学生只能属于一个班级。班级与学生之间形成了一对多的关系。
多对多关系
例子:一个学生可以选修多门课程,同时一门课程也可以被多个学生选修。
解释:在这个例子中,学生和课程之间形成了多对多的关系。一个学生可以选择多门课程,而每门课程也可以被多个学生选择。这种关系通常需要通过中间表(例如选课表)来实现。
注意事项
在设计数据库时,要根据实际需求确定实体之间的关系类型。
对于多对多关系,通常需要使用一个额外的关联表来存储关系数据。
在实际应用中,可能还需要考虑其他因素,如数据的完整性、查询效率等。
通过理解这些基本的数据关系类型,可以更好地设计和优化数据库结构,以满足实际应用的需求。
数据拼接
{ "code": 0, "message": "查询成功", "data": [ { "id": 3, "content": "春天,是一个充满希望和梦想信息的季节。它让大地焕发出新的生机,让万物复苏。在这个季节里,我们可以x感受到生命的力量", "createTime": "2024-03-11T15:41:33.000Z", "updateTime": "2024-03-12T13:24:14.000Z", "user": { "id": 21, "name": "why", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" }, "comments": [ { "id": 1, "user": { "id": 21, "name": "why" }, "comment": null, "content": "使用 SQL 编辑器或 IDE 的语法高亮和错误检查功能来帮助识别潜在的错误", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" }, { "id": 6, "user": { "id": 21, "name": "why" }, "comment": null, "content": "使用 SQL 编辑器或 IDE 的语法高亮和错误检查功能来帮助识别潜在的错误", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" }, { "id": 7, "user": { "id": 21, "name": "why" }, "comment": null, "content": "使用 SQL 编辑器或 IDE 的语法高亮和错误检查功能来帮助识别潜在的错误", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" }, { "id": 8, "user": { "id": 21, "name": "why" }, "comment": 1, "content": "如果可能的话,将 SQL 语句分解为更小的部分,并逐一测试它们,以找到具体的错误位置。", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" }, { "id": 18, "user": { "id": 21, "name": "why" }, "comment": null, "content": "使用 SQL 编辑器或 IDE 的语法高亮和错误检查功能来帮助识别潜在的错误", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" } ] } ] }
-- 在此基础继续增加字段 -- 也可以分别查询,然后在代码中做拼接,合在一起 -- 6.1这样查询会出现问题,因为动态下评论有5条,左连接再左连接labels会重复5次 -- SELECT m.id id,m.content content, m.createAt createTime, m.updateAt updateTime, -- JSON_OBJECT('id', u.id, 'name', u.name, 'createTime', u.createAt, 'updateTime', u.updateAt) user, -- ( -- JSON_ARRAYAgg(JSON_OBJECT( -- 'id',c.id,'content',c.content,'comment',c.comment_id,'createTime', u.createAt, 'updateTime', u.updateAt, -- 'user',JSON_OBJECT('id',cu.id,'name',cu.name) -- )) -- ) comments, -- ( -- JSON_ARRAYAGG(JSON_OBJECT( -- 'id', l.id,'name',l.name,'createTime',l.createAt,'updateTime', l.updateAt -- )) -- ) labels -- FROM moment m LEFT -- JOIN user u ON m.user_id=u.id -- LEFT JOIN comment c ON c.moment_id=m.id -- LEFT JOIN user cu ON cu.id=c.user_id -- LEFT JOIN moment_label ml ON ml.moment_id=m.id -- LEFT JOIN label l ON l.id=ml.label_id -- WHERE m.id=3 -- GROUP BY m.id; -- -- 解决方案 -- 1.不要一次性查询,写两条SQL;2. -- 2.写一条SQL,查询数据重复后去重操作; -- 3.SQL完善
单独查询没问题
多个左连接会出现重复问题,会在后续字段基础上再拼接
产生重复问题
[ { "id": 1, "name": "篮球", "createTime": "2024-03-12 22:21:15.000000", "updateTime": "2024-03-12 22:21:15.000000" }, { "id": 8, "name": "电影", "createTime": "2024-03-12 22:26:12.000000", "updateTime": "2024-03-12 22:26:12.000000" }, { "id": 9, "name": "Rap", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" }, { "id": 10, "name": "动漫", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" }, { "id": 1, "name": "篮球", "createTime": "2024-03-12 22:21:15.000000", "updateTime": "2024-03-12 22:21:15.000000" }, { "id": 8, "name": "电影", "createTime": "2024-03-12 22:26:12.000000", "updateTime": "2024-03-12 22:26:12.000000" }, { "id": 9, "name": "Rap", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" }, { "id": 10, "name": "动漫", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" }, { "id": 1, "name": "篮球", "createTime": "2024-03-12 22:21:15.000000", "updateTime": "2024-03-12 22:21:15.000000" }, { "id": 8, "name": "电影", "createTime": "2024-03-12 22:26:12.000000", "updateTime": "2024-03-12 22:26:12.000000" }, { "id": 9, "name": "Rap", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" }, { "id": 10, "name": "动漫", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" }, { "id": 1, "name": "篮球", "createTime": "2024-03-12 22:21:15.000000", "updateTime": "2024-03-12 22:21:15.000000" }, { "id": 8, "name": "电影", "createTime": "2024-03-12 22:26:12.000000", "updateTime": "2024-03-12 22:26:12.000000" }, { "id": 9, "name": "Rap", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" }, { "id": 10, "name": "动漫", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" }, { "id": 1, "name": "篮球", "createTime": "2024-03-12 22:21:15.000000", "updateTime": "2024-03-12 22:21:15.000000" }, { "id": 8, "name": "电影", "createTime": "2024-03-12 22:26:12.000000", "updateTime": "2024-03-12 22:26:12.000000" }, { "id": 9, "name": "Rap", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" }, { "id": 10, "name": "动漫", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" } ]
正确的
SELECT m.id id,m.content content, m.createAt createTime, m.updateAt updateTime, JSON_OBJECT('id', u.id, 'name', u.name, 'createTime', u.createAt, 'updateTime', u.updateAt) user, ( SELECT JSON_ARRAYAgg(JSON_OBJECT( 'id',c.id,'content',c.content,'comment',c.comment_id,'createTime', u.createAt, 'updateTime', u.updateAt, 'user',JSON_OBJECT('id',cu.id,'name',cu.name) )) FROM comment c LEFT JOIN user cu ON c.user_id=cu.id WHERE c.moment_id=m.id ) comments, ( JSON_ARRAYAGG(JSON_OBJECT( 'id', l.id,'name',l.name,'createTime',l.createAt,'updateTime', l.updateAt )) ) labels FROM moment m LEFT JOIN user u ON m.user_id=u.id LEFT JOIN moment_label ml ON ml.moment_id=m.id LEFT JOIN label l ON l.id=ml.label_id WHERE m.id=3 GROUP BY m.id;
结果
1. { { "code": 0, "message": "查询成功", "data": [ { "id": 3, "content": "春天,是一个充满希望和梦想信息的季节。它让大地焕发出新的生机,让万物复苏。在这个季节里,我们可以x感受到生命的力量", "createTime": "2024-03-11T15:41:33.000Z", "updateTime": "2024-03-12T13:24:14.000Z", "user": { "id": 21, "name": "why", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" }, "comments": [ { "id": 1, "user": { "id": 21, "name": "why" }, "comment": 1, "content": "使用 SQL 编辑器或 IDE 的语法高亮和错误检查功能来帮助识别潜在的错误", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" }, { "id": 6, "user": { "id": 21, "name": "why" }, "comment": null, "content": "使用 SQL 编辑器或 IDE 的语法高亮和错误检查功能来帮助识别潜在的错误", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" }, { "id": 7, "user": { "id": 21, "name": "why" }, "comment": null, "content": "使用 SQL 编辑器或 IDE 的语法高亮和错误检查功能来帮助识别潜在的错误", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" }, { "id": 8, "user": { "id": 21, "name": "why" }, "comment": 1, "content": "如果可能的话,将 SQL 语句分解为更小的部分,并逐一测试它们,以找到具体的错误位置。", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" }, { "id": 18, "user": { "id": 21, "name": "why" }, "comment": null, "content": "使用 SQL 编辑器或 IDE 的语法高亮和错误检查功能来帮助识别潜在的错误", "createTime": "2024-03-11 14:55:35.000000", "updateTime": "2024-03-11 14:55:35.000000" } ], "labels": [ { "id": 1, "name": "篮球", "createTime": "2024-03-12 22:21:15.000000", "updateTime": "2024-03-12 22:21:15.000000" }, { "id": 8, "name": "电影", "createTime": "2024-03-12 22:26:12.000000", "updateTime": "2024-03-12 22:26:12.000000" }, { "id": 9, "name": "Rap", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" }, { "id": 10, "name": "动漫", "createTime": "2024-03-13 10:48:45.000000", "updateTime": "2024-03-13 10:48:45.000000" } ] } ] }