Files
spark_project_20260921/README.md
T
KennethCheng 0f521d58bf docs: 新增 README 与代码审查
- README.md:项目结构、技术栈、三条业务需求、MySQL 表、构建运行步骤、已知问题
- CODE_REVIEW.md:分三级(严重/主要/次要)列出 11 个发现,含密码硬编码、空类、Any 分发等

本次仅提交两份文档;工作树里 App.scala 的 data path 切换与 ratings_all.csv 由用户后续单独提交
2026-09-21 22:24:35 +08:00

165 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# spark_project
MovieLens 风格数据集上的三条聚合分析练习项目:基于 Spark SQL + MySQL,把三条统计结果写入数据库。
> 学习 / 练手项目;不是生产系统。详见 `CODE_REVIEW.md`。
---
## 项目简介
读取两份 CSV:
- `data/movies.csv`:电影元数据(`movieId, title, genres`)
- `data/ratings_all.csv`(或 `data/ratings.csv`,小样本):用户评分(`userId, movieId, rating, timestamp`)
完成三条业务需求:
| 编号 | 描述 |
| :--: | :-- |
| 需求 1 | 评分次数 > 5000 的电影中,按平均分 Top 10,输出 `movieId / title / avgRating` |
| 需求 2 | 按 `genres` 拆分后,每个类别计算平均评分 |
| 需求 3 | 按评分次数 Top 10 的电影,输出 `movieId / title / ratingCount` |
三条结果分别写入 MySQL 表 `top_ten_avg_ratings` / `genres_average_rating` / `movie_rating_count`,使用 `REPLACE INTO`(基于各自 unique key 做 upsert)。
---
## 技术栈
| 组件 | 版本 |
| :-- | :-- |
| Scala | 2.11.12 |
| Apache Spark | 2.4.3(Spark Core + Spark SQL)|
| MySQL Connector/J | 8.0.28 |
| HikariCP | 4.0.3 |
| Commons DBUtils | 1.6 |
| 构建工具 | Maven 3.x + `scala-maven-plugin` 4.8.1 |
| Java 目标 | 8 |
---
## 目录结构
```
spark_project/
├── pom.xml
├── README.md
├── CODE_REVIEW.md
├── data/
│ ├── movies.csv # 电影元数据
│ ├── ratings.csv # 小样本评分
│ └── ratings_all.csv # 全量评分
└── src/
├── main/
│ ├── resources/
│ │ ├── create_table.sql # MySQL DDL
│ │ └── log4j.properties # 日志配置(stdout only,error 级别)
│ └── scala/com/example/
│ ├── spark/
│ │ ├── App.scala # 入口,三个 SQL 需求
│ │ └── Entitys.scala # case class:Movie / Rating / 三种结果
│ └── utils/
│ └── JDBCUtil.scala # HikariCP + DBUtils 写入 MySQL
└── test/ # 空
```
---
## 数据约定
- `data/movies.csv` 字段:`movieId, title, genres`
- `genres` 多个类别用 `|` 分隔(如 `Adventure|Animation|Children|Comedy|Fantasy`)
- `data/ratings.csv` / `data/ratings_all.csv` 字段:`userId, movieId, rating, timestamp`
- 默认入口读 `ratings_all.csv`;开发期可在 `App.scala:9` 切回 `ratings.csv`
---
## MySQL 表结构
详见 `src/main/resources/create_table.sql`。三张表统一字段:`id` 自增主键、`update_time` 默认当前时间、业务字段 + 唯一键。
```sql
-- 需求 1 结果
create table top_ten_avg_ratings (
id int(11) not null AUTO_INCREMENT,
movie_id int(11) not null,
title varchar(200) not null,
avg_rating decimal(10, 2) not null,
update_time datetime default current_timestamp,
primary key (id),
unique key movie_id_unique (movie_id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
```
> ⚠️ 实际库 / 表创建请先用 `create_table.sql` 跑一遍。
---
## 配置
`JDBCUtil.scala` 当前把连接信息硬编码:
```scala
private val user = "root"
private val password = "root123456"
private val url = "jdbc:mysql://192.168.48.10:3306/test"
```
**生产前必须改成外部配置**(application.conf / 环境变量 / 命令行参数)。详见 `CODE_REVIEW.md` 第 1 条。
`App.scala:14` 的 `master("local[2]")` 也是硬编码,集群提交前请改为从参数传入。
---
## 构建与运行
### 前置条件
- JDK 8
- Maven 3.6+
- MySQL 8.x(本地或局域网),能访问 `192.168.48.10:3306`
### 步骤
```powershell
# 1. 建表
mysql -h 192.168.48.10 -P 3306 -u root -p < src/main/resources/create_table.sql
# 2. 编译 + 打 fat-jar(assembly 插件已配置)
mvn -P dev clean package
# 3. dev profile:spark-core / spark-sql 是 compile 作用域,IDE 直接跑 App.main 即可
# build_pkg profile:provided 作用域,打成可提交到集群的 jar
# 4. 本地跑(也可直接 java -jar)
java -cp target/spark_project-1.0-SNAPSHOT-jar-with-dependencies.jar com.example.spark.App
```
### Maven Profile 说明
| profile | 用途 | Spark 依赖 scope |
| :-- | :-- | :-- |
| `dev` | IDE 本地跑、单元测试 | `compile` |
| `build_pkg` | 打胖包丢到集群跑 | `provided` |
---
## 已知问题 / TODO
详见 [`CODE_REVIEW.md`](CODE_REVIEW.md) 完整清单,优先级最高的:
- 🔴 MySQL 密码硬编码
- 🔴 `create_table.sql` 中 `avg_rating` 字段注释残留
- 🟠 `Entitys.scala` 死类 + 字段类型与 SQL 不一致
- 🟠 `insert2Mysql(res: Any)` 用 Any 做运行时分发
- 🟠 `SparkSession` 未 `stop()`;CSV `inferSchema=true`
- 🟡 无单元测试(JUnit 依赖已引但 `src/test/` 空)
---
## 参考
- MovieLens 数据集:<https://grouplens.org/datasets/movielens/>
- Spark SQL 文档(2.4.x):<https://spark.apache.org/docs/2.4.3/sql-programming-guide.html>
- HikariCP 配置:<https://github.com/brettwooldridge/HikariCP>