前言
这篇文章,主要用最基础的方式进行多表联查,实现类似朋友圈好友动态的那种案例
这里只是做了最简单的动态的列表展示,锻炼编写SQL思路
一、需求分析
有这么个项目,类似朋友圈,需要展示用户好友和自己发布的动态。
1.每条动态需要展示头像、昵称、内容(文字、图片、视频)
2.最新发布的在最前面展示
3.动态列表中包括用户自己的动态
4.朋友圈需要动态分页
二、创建数据库表.
需要三个数据表:用户表 users,用户好友关联表 friends,用户动态表 dynamic
用户表 users:用户id、昵称、头像
用户-好友关联表 friends:关联id、用户id、好友id
用户动态表 dynamic:动态id、发布人id、文字内容、视频内容、图片内容
用户表 users
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`nick_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户昵称',
`avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户头像',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户表'
-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES (1, '大娃', '1.jpg');
INSERT INTO `users` VALUES (2, '二娃', '2.jpg');
INSERT INTO `users` VALUES (3, '三娃', '3.jpg');
INSERT INTO `users` VALUES (4, '四娃', '4.jpg');
SET FOREIGN_KEY_CHECKS = 1;
用户-好友关联表 friends
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for friends
-- ----------------------------
DROP TABLE IF EXISTS `friends`;
CREATE TABLE `friends` (
`id` int(11) NOT NULL COMMENT '用户和好友的关联id',
`user_id` int(11) DEFAULT NULL COMMENT '用户id',
`friend_id` int(11) DEFAULT NULL COMMENT '好友id',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户-好友关联表'
-- ----------------------------
-- Records of friends
-- ----------------------------
INSERT INTO `friends` VALUES (1001, 1, 2);
INSERT INTO `friends` VALUES (1002, 2, 1);
INSERT INTO `friends` VALUES (1003, 1, 3);
INSERT INTO `friends` VALUES (1004, 3, 1);
INSERT INTO `friends` VALUES (1005, 2, 3);
INSERT INTO `friends` VALUES (1006, 3, 2);
INSERT INTO `friends` VALUES (1007, 2, 4);
INSERT INTO `friends` VALUES (1008, 4, 2);
INSERT INTO `friends` VALUES (1009, 3, 4);
INSERT INTO `friends` VALUES (1010, 4, 3);
SET FOREIGN_KEY_CHECKS = 1;
用户动态表 dynamic
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for dynamic
-- ----------------------------
DROP TABLE IF EXISTS `dynamic`;
CREATE TABLE `dynamic` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL COMMENT '发布人id',
`content` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '文字内容',
`image` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '图片内容',
`video` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '视频内容',
`create_time` datetime(0) DEFAULT CURRENT_TIMESTAMP COMMENT '发布动态时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1011 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '动态表'
-- ----------------------------
-- Records of dynamic
-- ----------------------------
INSERT INTO `dynamic` VALUES (1001, 1, '我是大娃,发布第1条动态', NULL, NULL, '2020-06-30 16:39:25');
INSERT INTO `dynamic` VALUES (1002, 2, '我是二娃,发布第1条动态', NULL, NULL, '2020-06-30 16:39:28');
INSERT INTO `dynamic` VALUES (1003, 3, '我是三娃,发布第1条动态', NULL, NULL, '2020-06-30 16:39:30');
INSERT INTO `dynamic` VALUES (1004, 4, '我是四娃,发布第1条动态', NULL, NULL, '2020-06-30 16:39:33');
INSERT INTO `dynamic` VALUES (1005, 1, '我是大娃,发布第2条动态', NULL, NULL, '2020-06-30 16:39:36');
INSERT INTO `dynamic` VALUES (1006, 1, '我是大娃,发布第3条动态', NULL, NULL, '2020-06-30 16:39:40');
INSERT INTO `dynamic` VALUES (1007, 2, '我是二娃,发布第2条动态', NULL, NULL, '2020-06-30 16:39:44');
INSERT INTO `dynamic` VALUES (1008, 3, '我是三娃,发布第2条动态', NULL, NULL, '2020-06-30 16:39:47');
INSERT INTO `dynamic` VALUES (1009, 4, '我是四娃,发布第2条动态', NULL, NULL, '2020-06-30 16:39:49');
INSERT INTO `dynamic` VALUES (1010, 2, '我是二娃,发布第3条动态', NULL, NULL, '2020-06-30 16:39:52');
SET FOREIGN_KEY_CHECKS = 1;
三、关联思路
朋友圈每条动态需要展示:用户昵称、头像、内容,发布时间
用户昵称和头像存储在用户表;
内容和发布时间存储在动态表;
列表展示与当前用户及好友的动态;
用户表:存储每个用户的基本信息,例如:姓名、头像、手机号、年龄、家庭住址......
用户-好友关联表:存储用户与用户之间的好友关系
动态表:存储用户发布的动态信息,包括:文字内容、图片内容、视频内容
四、解决方案
查询user_Id = 1 的朋友圈,分页查询
由于,个人动态与好友的动态获取逻辑是不同的,所以给出下面两种思路
方案一
先查用户好友的动态,再查自己的动态,然后使用 union函数,合并列表
SELECT
id, user_id, content, video, image, nick_name, avatar, create_time
FROM (
SELECT
i.id, i.user_id, i.content, i.video, i.image, u.nick_name, u.avatar, i.create_time
FROM
dynamic i
LEFT JOIN users u ON u.id = i .user_id
LEFT JOIN friends f ON f.friend_id = u.id
WHERE
f.user_id = 1
UNION
SELECT
i.id, i.user_id, i.content, i.video, i.image, u.nick_name, u.avatar, i.create_time
FROM
dynamic i
LEFT JOIN users u ON u.id = i.user_id
WHERE
i.user_id = 1
) dynamic
ORDER BY create_time DESC
LIMIT 1,5
方案二
直接查询用户好友的动态和自己的动态
SELECT
i.id, i.user_id, i.content, i.video, i.image, u.nick_name, u.avatar, i.create_time
FROM
dynamic i
LEFT JOIN users u ON u.id = i .user_id
LEFT JOIN friends f ON f.friend_id=u.id
WHERE
f.user_id = 1
OR
f.friend_id = 1
ORDER BY i.create_time DESC
LIMIT
1, 5