ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Django与MySQL的B站青少年模式数据分析系统实战

基于Django与MySQL的B站青少年模式数据分析系统实战 每年毕业季都会收到一批特征明显的求助消息最常见的就是这种学长这个标题写着Java毕设基于Django的Bilibili青少年模式使用情况的数据分析系统设计与实现还带源码、MySQL、文档能做吗先别说能不能做光是这个标题信息量就够大的——Java、Django、MySQL、数据分析四个词往一起放很多同学第一眼就懵了。其实拆开看这是一道非常典型的Web数据分析综合题Django负责Web框架MySQL管数据存储Python负责采集、清洗和分析最后把青少年模式的行为数据用图表展示出来。这篇分享就围绕这个选题从技术选型、业务拆解、数据采集、数据库建模、可视化到答辩准备完整讲一遍正在选毕设题或者准备复现类似系统的同学可以直接照着走。1. 标题里的Java和Django并不冲突先把技术主线定下来1.1 为什么会出现挂着Java标签的Django项目在各大毕设平台和源码店铺里Java毕设是最能吸引点击的标签很多商家会把所有热门的Web项目统一挂上Java关键词只为让搜Java的同学看见。但Django是Python生态最经典的Web框架和Java语言没有直接关系。所以这个标题的正确读法是一个挂了Java搜索标签的Python数据分析毕设。如果一开始就打算用纯Java实现Django这套代码是搬不动的要么换技术栈要么改题目。这不是坏事反而提醒你先确认学校的要求题目里有没有强制指定语言如果没写死PythonDjango做主技术栈完全合理。如果题目有Java字样但允许自选实现方式那答辩时一定要主动说明这个背景解释清楚为什么用Django而不是Java反而能展示你对技术选型的思考。最怕的是自己都没弄明白标题来源被评委一问就慌以为题目有问题。1.2 DjangoMySQL组合在数据分析毕设里的优势数据分析这条链路在Python生态里几乎是闭环的pandas负责清洗matplotlib/seaborn可以做探索性图表Django负责把分析结果变成可交互的Web页面MySQL负责持久化。对比Java系省掉大量配置和编译成本。Django自带ORM、Admin后台和模板引擎一个学生从零搭起一个完整系统通常一周内能跑通核心功能。毕设评审看的是需求分析→系统设计→实现→测试的逻辑是否完整而不是框架有多新所以Django的成熟和稳定反而是加分项。还有个很实际的好处Python写数据分析逻辑比Java短一大截。比如计算每小时观看时长分布pandas里一句groupby就能完成Java要写很多样板代码。对于只有几个月时间的毕设来说把精力花在业务和可视化的打磨上远比耗在语言细节里划算。MySQL在这里也不是陪跑角色它承担了行为记录的持久化、统计表的预聚合、以及Django Admin后台的数据管理属于整个系统的数据底座。1.3 如果导师必须让你用Java该怎么平移方案这种标题Java、实际想做数据分析的情况我也遇到过。我的建议是不要硬套Django直接平移成Spring Boot MyBatis MySQL ECharts。后端用Spring Boot的RestController提供统计JSON前端用Vue或Thymeleaf渲染图表数据分析部分可以在Java里手写统计类也可以把核心算法用Python脚本跑完导出CSV再让Java读。虽然多了一步但能满足必修Java约束。不过要提醒一句如果把题目改成Java实现就别再宣称自己用了Django文档、源码、答辩都要保持一致。很多学生在这个环节翻车就是因为题目和实现脱节评委随便一查源代码就穿帮了。所以先确认规则再决定路线这是整个项目最不该省的一步。2. 青少年模式使用情况的正确拆法从现象到指标2.1 青少年模式里的可分析点青少年模式不是一个按钮而是一组行为约束。理解这一点就能推出系统要采集和分析的数据。核心逻辑是谁user_id、在什么时间start_time、以什么模式mode看了什么内容video_id、看了多久watch_duration、有没有触发超时提醒timeout_flag以及之后是否切换了模式mode_switch。基于这些原始数据可以定义三类指标指标类别具体指标业务含义使用规模使用人数、新增用户、日活/周活/月活、人均在线时长判断青少年模式整体使用热度内容偏好内容分类分布、Top视频、Top UP主、时段热力分析模式下的内容消费结构模式状态开启率、自动退出率、提醒触发率、切换频率评估模式限制是否被规避或过度打扰这些指标就是系统的需求清单。很多同学上来就画界面结果页面做了一堆答辩时问这个指标代表什么答不上来。建议先拿一张纸把上面三类指标全部列出来再反推每个页面展示什么图表这样系统逻辑就顺了。2.2 功能模块怎么划分按数据采集→清洗→存储→分析→展示的标准流水线落到Django建议拆成几个独立app而不是写成一个巨型views.py。我习惯这样分data_collect负责导入外部数据、调用采集脚本、接收CSV/JSON上传。data_clean跑清洗任务过滤异常值、统一时间格式、去重。stats_core负责聚合统计输出给前端使用的JSON。dashboards页面渲染放模板和路由。accounts登录、权限至少给管理员区分普通查看者。这样拆分之后每个app的职责都很单一代码量不大但结构非常清晰。答辩时评委问你这个系统怎么分层的你直接把这几个app的作用讲一遍逻辑就拉满了。2.3 整体数据流原始日志CSV、JSON或数据库导入→ 清洗脚本 → 写入MySQL → Django ORM聚合查询 → 生成JSON → 前端图表展示。这个数据流不需要复杂的消息队列毕设阶段用脚本加手动触发就够。如果想让系统更上档次可以加一个每日零点自动更新统计汇总表的任务用APScheduler或者系统的定时任务都行。要注意的是这个数据流里最容易出问题的环节是清洗到入库之间。很多人把清洗逻辑写在Django的视图函数里页面每次加载都重新洗一遍数据性能差不说逻辑也乱。正确做法是把清洗做成一次性脚本或者独立管理命令数据洗好入库后页面只做查询。3. 数据从哪来三条路线和一套清洗方案3.1 数据获取的三条路线真实数据稀缺是这个题目最常见的障碍。建议按优先级尝试三种方式第一公开数据集。Kaggle和其他社区有一些视频平台用户行为数据集虽然不完全等于青少年模式但字段可以迁移。比如把用户年龄、观看时长、内容分类这些结构套过来再结合青少年模式的约束去构造特征。第二合规接口采集。B站开放的视频信息接口可以拿到视频分类、弹幕、播放量等公开信息抓取时严格控制频率、遵循网站规则只用于学习研究不绕过登录与技术限制。重点强调一下采集公开信息没有问题但不要大规模并发抓取也不要去碰需要账号权限才能看的非公开数据。毕设阶段完全没必要冒这个风险。第三业务模拟数据。如果题目明确要求青少年模式专属数据真实场景几乎不可能拿到最稳妥的办法是自己构造符合业务逻辑的模拟数据。这个不丢人很多正式的数据分析项目在测试阶段同样会用模拟数据。3.2 清洗细节原始数据往往很脏常见的几种情况user_id为空、时间戳格式不统一、观看时长大于一天、同一条记录重复出现。清洗规则要写成独立脚本别揉进视图函数里。一般我会写四个步骤先统一时间字符串为datetime类型再过滤缺失关键字段的记录然后按user_id video_id start_time去重最后剔除时长异常的记录比如观看时长小于3秒或大于24小时的那些。清洗这一步决定了统计分析的质量。很多同学拿到原始数据直接用结果统计出来人均时长100小时一查才发现是脏数据在作妖。答辩前一定要把清洗前后数据量、异常值处理情况整理成表这也是系统测试的一部分评委很爱问你怎么保证数据可靠性。3.3 用模拟数据兜底利用Faker生成用户数据再手动构造观看记录尽量符合晚上7-9点峰值、周末更多等真实规律from faker import Faker fake Faker(zh_CN) for _ in range(200): user User( user_idfake.uuid4(), age_groupfake.random_element([7-12, 13-15, 16-17]) ) user.save()先造用户再造行为记录。watch_duration按照正态分布生成start_time偏向晚高峰时段。模拟数据不是瞎编要尽量贴近真实业务才能在答辩时经得起问。造数据时尤其要想清楚青少年模式超时提醒怎么体现比如设置一个字段记录是否触发过15分钟或30分钟的限制后续分析提醒触发率就靠它。4. MySQL表结构与Django ORM建模把统计分析落到数据层4.1 核心表设计数据库表不宜太多但要能覆盖完整业务链路。我的做法是四张基础表加一张统计汇总表表名关键字段作用usersuser_id、age_group、created_at用户基础信息videosbvid、title、category、duration视频元数据view_recordsuser_id、video_id、watch_duration、start_time、timeout_flag核心行为流水mode_switch_logsuser_id、switch_time、mode_type、reason模式切换记录daily_statisticsstat_date、hour、total_duration、record_count、active_users预聚合统计结果daily_statistics是性能优化的重要设计。如果每次打开首页都扫描view_records全表数据量稍大就会变慢。提前把按小时和按天聚合的结果存起来页面查询就是简单的SELECT速度会快很多。这也是实际项目中常用的空间换时间思路。4.2 Django模型与关系映射Django模型直接对应上面这些表重点关注外键关系和索引from django.db import models class User(models.Model): user_id models.CharField(max_length64, uniqueTrue) age_group models.CharField(max_length16, blankTrue) created_at models.DateTimeField(auto_now_addTrue) class Meta: db_table users class VideoInfo(models.Model): bvid models.CharField(max_length32, uniqueTrue) title models.CharField(max_length255) category models.CharField(max_length32) duration models.PositiveIntegerField() class Meta: db_table videos class ViewRecord(models.Model): user models.ForeignKey(User, models.CASCADE) video models.ForeignKey(VideoInfo, models.CASCADE) watch_duration models.PositiveIntegerField() start_time models.DateTimeField(db_indexTrue) timeout_flag models.BooleanField(defaultFalse) class Meta: db_table view_records indexes [models.Index(fields[start_time, watch_duration])]外键关系能让统计时join非常方便比如查询青少年模式用户观看的视频分类分布直接跨表查就行。注意在Meta里设置db_table让Django建表时和MySQL设计保持一致避免migrate生成一串看不懂的默认名。4.3 聚合查询与性能注意事项常见需求统计每天各小时观看时长分布用TruncHour函数非常顺手from django.db.models import Sum, Count from django.db.models.functions import TruncHour hourly ( ViewRecord.objects .annotate(hourTruncHour(start_time)) .values(hour) .annotate(total_durationSum(watch_duration), record_countCount(id)) .order_by(hour) )只要把start_time截断到小时配合values分组再用Sum和Count聚合一条查询就搞定了。但要记住查询条件必须带时间范围比如start_time__range否则表一大就会很慢。这也是我在start_time上加db_index的原因索引配范围查询才有效。还有一个容易被忽略的点清空测试数据时ViewRecord.objects.all().delete()会级联删除关联数据做演示前如果手滑执行了这条命令整个看板就空了。建议给关键行为记录加软删除字段比如is_active或者每次清理前先备份免得现场翻车。5. 可视化与后端统计接口把图表串成一条演示主线5.1 后端统计接口设计不要每个图表单独写一个专用视图那样页面一多代码就失控。我的习惯是一个总览接口加几个明细接口。总览接口返回核心卡片数据明细接口返回某个图表的数据项。比如from django.http import JsonResponse from django.db.models import Sum, Count def overview_stats(request): records ViewRecord.objects.all() total_duration records.aggregate(totalSum(watch_duration))[total] or 0 total_count records.count() return JsonResponse({ total_duration: total_duration, total_count: total_count, })返回JsonResponse给前端Django模板只负责放容器。这样前后端职责清楚而且答辩时可以说我把统计逻辑和展示逻辑分离了显得更专业。如果用了前后端分离方案直接写Django的API接口即可逻辑一样的。5.2 前端图表选型ECharts是目前最稳的选择折线图、饼图、热力图都成熟文档例子多学生上手快。选图表类型也有讲究时段分布用折线图内容分类占比用饼图用户活跃热力用日历热力图模式切换时间点用散点图。不要一个页面塞太多图表挑三到五个核心图就够了。展示逻辑上建议按总体一句话→趋势一张图→维度交叉一张图的节奏来。比如先显示今日总观看时长xx小时环比xx%再展示最近7天观看时长趋势最后展示各内容分类观看占比。这个节奏和答辩讲稿是吻合的演示时顺着页面讲下来很自然。5.3 模板集成主要坑Django模板加ECharts有几个容易卡住的点。第一个是Ajax POST请求需要携带CSRF tokenDjango默认会校验不带的话直接403。解决方案是先读取csrftoken cookie再用请求头带回。第二种情况是静态文件路径配置ECharts的js文件要放到STATICFILES_DIRS里开发时用debugTrue能直接访问部署时一定要先collectstatic。第三个细节是投屏演示时图表字体太小默认12px在投影上根本看不清记得在option里把字号统一调到16px以上。6. 毕设交付物从项目文档到答辩演示完整准备链路6.1 文档怎么写规范的文档结构一般分五章需求分析背景、用户角色、功能和非功能需求、系统设计总体架构、模块划分、数据库设计、系统实现关键代码说明、核心界面截图、系统测试测试用例、测试结果、异常场景、部署说明环境要求、启动步骤。写文档最忌讳变成代码说明书大段贴源码没有任何意义。重点是解释为什么这么设计。比如数据库为什么要加daily_statistics预汇总表就是因为直接查行为流水表会慢。把这个设计思路写清楚比贴十个函数都有价值。每年都有学生系统做完了文档却因为逻辑混乱被扣分这个环节必须重视。6.2 环境搭建最容易卡住的几个点环境问题在毕设阶段消耗的时间比想象中多。经验上要盯住这几个点Python版本和Django版本要匹配建议Python 3.10或3.11配Django 4.x比较稳。MySQL 8的驱动是个经典坑。Windows下装mysqlclient经常编译失败换PyMySQL并在__init__.py里写pymysql.install_as_MySQLdb()通常就解决了。MySQL 8默认认证方式是caching_sha2_password有些客户端会报ssl连接错误检查连接配置。django创建app后一定要手动加到INSTALLED_APPS否则migrate不生效。执行查询和删除对象的操作要小心级联修改models后必须makemigrations再migrate。换机器演示前最好用pip freeze requirements.txt把依赖锁定到新环境一键恢复依赖。很多同学在现场环境里因为缺某个Python包打不开页面这种事太亏了。6.3 答辩演示的标准路径演示顺序建议这样走首页项目介绍 → 数据看板核心指标 → 时段分布图表 → 内容偏好图表 → 模式切换记录 → Django Admin后台 → 现场筛选一个时间范围。每个页面都要准备一个能被追问的点比如为什么这个指标这么定义数据是怎么清洗的。代码讲解时千万不要逐行念挑三个核心函数讲清楚就能过关数据清洗函数、聚合统计函数、图表接口函数。讲的时候说明输入什么、输出什么、为什么这么写评委一般就会点头。答辩前至少练两遍完整流程时间控制在10分钟左右流畅度比技术深度更重要。7. 验收前的高频坑位与全bao的正确打开方式7.1 MySQL与中文数据建库时字符集一定要用utf8mb4settings.py里的DATABASES配置也要带上OPTIONS指定charsetutf8mb4。中文乱码有九成是客户端连接编码问题不是数据本身坏了。还有一点改了MySQL配置以后要注意确认配置文件加载位置Windows用户经常改了my.ini没重启服务怎么看都是旧的。7.2 时区与统计口径Django开启USE_TZTrue后写入数据库的时间统一是UTC。统计今天的数据时如果直接用datetime.now()去过滤会发现每天少了几个小时的数据。正确做法是把本地时间范围转换成UTC范围再查询或者查询后在渲染层按Asia/Shanghai转换。这个坑特别隐蔽因为开发数据量小看不出异常等数据一多日报口径就乱了。7.3 关于附源码、调试代码讲解全bao的真心话这类服务本质上是把路铺好但你得自己走。源码拿到手后我的建议是用三天把它们拆成三层来理解第一层能跑第二层能改第三层能讲。如果所有部分都依赖别人答辩现场一句这个函数返回什么就能露馅。找服务救急不丢人丢人的是交付之后连项目启动命令都说不清楚。所以最终提交前一定自己在干净机器上从零搭一遍环境、导入数据库、启动服务、走完演示流程。整个过程不需要太多时间却能把绝大多数部署问题提前暴露掉。验证通过后再提交是对自己负责也是对项目质量负责。这些年我带过的学生里真正拿高分的不一定是代码最炫的一定是能把青少年模式为什么要这种统计口径讲清楚的人。数据分析类题目和纯开发题不一样它讲究的是从问题到指标再到图表的一步步推导。如果你也准备选这个题我建议把一半时间花在业务理解和数据准备上别急着写页面。页面是最后几天就能补的数据和逻辑想不清楚后面全是返工。
返回列表