从 Vue 到万物:AI 加速下的前端开发者全栈进化论【第三课】
·
Day 3 | MySQL + 数据库设计:前端视角看不到的世界
前端的数据世界 vs 后端的数据世界
前端开发者每天和数据打交道,但数据是这样的:
// 你眼里的"数据"
const accident = {
id: 1,
title: '迎泽大街交通事故',
severity: '严重',
location: { lng: 112.549, lat: 37.857 },
imageUrls: ['https://minio.../img1.jpg', 'https://minio.../img2.jpg']
}
后端眼里同一份数据,是这样的:
-- t_accident 表(事故主表)
SELECT * FROM t_accident WHERE id = 1;
+----+---------------------+---------+------------+-----------+
| id | title | severity| longitude | latitude |
+----+---------------------+---------+------------+-----------+
| 1 | 迎泽大街交通事故 | 严重 | 112.549 | 37.857 |
+----+---------------------+---------+------------+-----------+
-- t_accident_image 表(事故图片关联表)
SELECT * FROM t_accident_image WHERE accident_id = 1;
+----+-------------+------------------------------+
| id | accident_id | url |
+----+-------------+------------------------------+
| 1 | 1 | https://minio.../img1.jpg |
| 2 | 1 | https://minio.../img2.jpg |
+----+-------------+------------------------------+
前端一个对象,后端可能是三张表 + 两次 JOIN + 一次聚合查询。这就是为什么前端学后端,最难的一关是数据库设计思维。
数据库设计的核心概念(前端人听得懂的版本)
1. 表 = 类型,字段 = 属性,外键 = 关联
-- 事故表(主表)
CREATE TABLE t_accident (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL COMMENT '事故标题',
severity VARCHAR(20) NOT NULL COMMENT '严重程度:严重/一般/轻微',
longitude DECIMAL(10, 6) COMMENT '经度',
latitude DECIMAL(10, 6) COMMENT '纬度',
location VARCHAR(500) COMMENT '地点描述',
description TEXT COMMENT '事故描述',
occur_time DATETIME COMMENT '发生时间',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
2. 主键、外键、索引——为什么你的查询很慢
-- 给经纬度加索引(高频查询字段)
CREATE INDEX idx_location ON t_accident(longitude, latitude);
-- 给时间加索引(按时间范围查询)
CREATE INDEX idx_occur_time ON t_accident(occur_time);
-- 给严重程度加索引(分类统计)
CREATE INDEX idx_severity ON t_accident(severity);
前端类比: 索引就像书的目录。查"第5章"不需要翻完前4章——这就是索引的作用。给
WHERE longitude = ? AND latitude = ?经常查的字段加索引。
3. 一对多关系:事故 → 图片
CREATE TABLE t_accident_image (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
accident_id BIGINT NOT NULL,
url VARCHAR(500) NOT NULL,
type VARCHAR(20) COMMENT 'image/video',
FOREIGN KEY (accident_id) REFERENCES t_accident(id)
);
前端类比:
accident.images = []在前端是数组,在后端是一张独立的表,用accident_id关联回来。
MyBatis-Plus:让 SQL 写得像前端查询
纯手写 SQL 对前端开发者来说门槛太高。MyBatis-Plus(MyBatis 的增强工具)让这件事变得像调用方法一样简单:
// Mapper 接口(对应一张表)
@Mapper
public interface AccidentMapper extends BaseMapper<Accident> {
// MyBatis-Plus 自动生成:SELECT * FROM t_accident WHERE id = ?
// 你只需要写复杂查询
}
// Service
@Service
public class AccidentService {
@Autowired private AccidentMapper accidentMapper;
// 按 ID 查询(自动生成,不用写 SQL)
public Accident getById(Long id) {
return accidentMapper.selectById(id);
}
// 按严重程度统计(手写 SQL)
public Long countBySeverity(String severity) {
return accidentMapper.selectCount(
new LambdaQueryWrapper<Accident>()
.eq(Accident::getSeverity, severity)
);
}
}
前端类比:
accidentMapper.selectById(id)等于store.state.accidents[id]。只是数据来源从内存变成了数据库。
AI 辅助写 SQL 的实战方法
真实项目中,SQL 往往是最需要 AI 辅助的部分。以下是让 AI 帮你写 SQL 的正确姿势:
场景1:建表语句生成
Prompt:"我有一个事故记录表 t_accident(字段:id, title, severity, longitude, latitude, occur_time),
请生成 MySQL 建表语句,包含主键、自动更新时间、合适的索引,用于事故一张图的热力图查询(按经纬度范围查询)。"
场景2:复杂统计查询
Prompt:"我需要一条 SQL 统计每个严重程度的事故数量,并计算平均发生间隔。
表 t_accident,字段:id, severity(严重/一般/轻微), occur_time(DATETIME)。
MySQL 8.0 环境。"
场景3:数据迁移
Prompt:"我要把 t_accident.image_urls(JSON数组字段)里的图片URL拆分到 t_accident_image 表,
每张图片一行,用 Python pymysql 执行。表结构和数据如下:[粘贴表结构]"
今日任务清单
- 安装并启动 MySQL:Windows 上建议用 phpStudy 快速启动,验证连接:
import pymysql conn = pymysql.connect(host='localhost', user='root', password='123456', database='accident_db') print(conn.cursor().execute("SELECT 1")) conn.close() - 阅读真实项目的表结构:查看
accident_db下的所有表,理解t_accident、t_cause、t_user之间的关系 - 让 AI 生成一条 JOIN 查询:关联
t_accident和t_accident_image,返回事故及其所有图片URL(JSON 数组格式)
思维升级
数据库不是"存储数据的地方",是一个有结构、有约束、有性能要求的数据系统。
前端学后端,学会用 SQL 思考数据,而不是只学怎么 CRUD。
更多推荐

所有评论(0)