我闺女上小学三年级了,上个月学校发了个通知,说要建立学生健康档案,我当时就想,这玩意要是用Excel管,等到六年级估计得乱成一锅粥,后来一琢磨,干脆用Go写个管理系统得了,说实话,Go语言写这种数据管理的东西,比Python感觉清爽不少,咱今天就聊聊怎么用Go捣鼓一个学生健康档案表,别嫌啰嗦,想到哪儿写到哪儿。

为什么要用Go?这事儿得说清楚
很多人一听学生档案,第一反应是Python或者Java,但我要说,Go的优势在于它的结构体(struct)和并发处理,你想想,一个学校几千号学生,每个学生每年体检两次,光身高体重肺活量这些字段就十几个,用Go的结构体来定义,清晰得跟课本似的。
Go结构体比Excel强在哪?
Excel表格你打开还得加载,数据多了还卡,Go直接操作内存,配合SQLite或者MySQL,查询起来刷刷快,而且Go编译出来的二进制文件小得很,丢到服务器上就能跑,不用装什么虚拟机。
我给自己闺女学校写这个的时候,就用的这个结构体定义:
type StudentHealthRecord struct {
ID int64 `json:"id"`
StudentID string `json:"student_id"`
Name string `json:"name"`
Gender string `json:"gender"`
BirthDate string `json:"birth_date"`
Height float64 `json:"height"` // 厘米
Weight float64 `json:"weight"` // 公斤
VisionLeft float64 `json:"vision_left"`
VisionRight float64 `json:"vision_right"`
LungCapcity int `json:"lung_capacity"` // 肺活量,毫升
CheckDate string `json:"check_date"`
}
你看,每个字段类型都写死,不会像Excel那样一个单元格里既填数字又填文字,乱得没边。
数据存储怎么搞?别想得太复杂
我试过几种方案,最后用了SQLite,为啥?因为学生健康档案表这玩意,一般就是一个学校自己用,没必要上MySQL那么重,一个文件搞定,备份也方便,拷贝走就行了。
建表语句我也贴出来,虽然老套但实用:
CREATE TABLE IF NOT EXISTS health_records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
student_id TEXT NOT NULL,
name TEXT NOT NULL,
gender TEXT CHECK(gender IN ('男', '女')),
birth_date TEXT,
height REAL,
weight REAL,
vision_left REAL,
vision_right REAL,
lung_capacity INTEGER,
check_date TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
这里有个小坑——性别字段我用了检查约束,只允许“男”或“女”,别问我为什么没考虑其他情况,学校系统就这两种,别给自己找麻烦。
写入数据时的注意事项
你想想,每年体检一次,同一个学生的身高体重都会变,所以这个表的主键是自增ID,而不是学生ID,同一个学生可以有多个记录,按检查日期排序就能看到成长曲线,这个设计思路,是我翻了两天《数据库设计与实现》那本书才想通的,书挺老旧,但道理不过时。
查询功能这么做才顺手
写了个简单的查询接口,按学生ID查所有记录,或者按班级查,我给你们看看核心代码:
func QueryRecordsByStudentID(db *sql.DB, studentID string) ([]StudentHealthRecord, error) {
rows, err := db.Query(
"SELECT id, student_id, name, gender, height, weight, vision_left, vision_right, lung_capacity, check_date FROM health_records WHERE student_id = ? ORDER BY check_date DESC",
studentID,
)
if err != nil {
return nil, err
}
defer rows.Close()
var records []StudentHealthRecord
for rows.Next() {
var record StudentHealthRecord
err := rows.Scan(
&record.ID, &record.StudentID, &record.Name, &record.Gender,
&record.Height, &record.Weight, &record.VisionLeft,
&record.VisionRight, &record.LungCapcity, &record.CheckDate,
)
if err != nil {
return nil, err
}
records = append(records, record)
}
return records, nil
}
写法有点啰嗦,但胜在稳当。rows.Scan的时候每个字段都对应好,顺序错一个就报错,但错不了总比数据乱好。
那些年我们踩过的坑
写的过程中,最大的坑是浮点数精度,身高体重用float64,存到数据库里有时候会变成179.999999999这种奇葩数字,后来我学乖了,读取的时候用math.Round四舍五入到一位小数。
另一个坑是日期格式,Go的日期格式化用的是2006-01-02这个魔幻参考值,不是常见的yyyy-mm-dd,我第一次写就栽这儿了,死活格式不对,气得差点摔键盘,后来发群里吐槽,老程序员们都在笑,说这个坑他们都踩过。
| 常见错误 | 正确写法 | 说明 |
|---|---|---|
2024-01-01直接传字符串 |
time.Parse("2006-01-02", "2024-01-01") |
Go的时间解析必须用这个参考时间 |
| 用float64存视力 | 用float32也行 | 视力就小数点后一位,没必要double |
| 学生ID用int | 改成string | 有些学校学生ID带字母,int坑死人 |
界面的事咱回头再说
现在这个系统没有前端界面,就是用终端跑,或者接个简单的HTTP接口,我打算下次用Go的html/template写个简单的Web页面,就不用整天对着黑框敲命令了,不过那都是后话了,先把数据逻辑跑通再说。
我闺女学校那个健康档案,现在跑在我那台旧笔记本上,每天定时备份到网盘,校长看了说不错,就是界面丑了点,我说等暑假再美化,先把功能整稳了。
要我说,不管你用Go还是Python还是别的,关键是把数据结构和业务流程先想清楚,像学生健康档案这种长期积累的数据,一个不小心就得重来,我建议你动手之前,先拿张纸把字段画一遍,想清楚怎么查询、怎么更新、怎么防止重复录入,比直接敲代码强十倍。
前两天帮隔壁班老师查一个孩子连续三年的视力变化,SQL一跑出来,那个折线图看得清清楚楚,老师说,这比翻纸质册子快多了,我就觉得,这代码没白写。
本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://www.yikaoba.cn/jiankang/555.html
评论列表(4条)
我是be365的签约作者“kyadmin”!
希望本篇文章《用Golang写学生健康档案表?这事儿我琢磨了好几天》能对你有所帮助!
本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名
本文概览:我闺女上小学三年级了,上个月学校发了个通知,说要建立学生健康档案,我当时就想,这玩意要是用Excel管,等到六年级估计得乱成一锅粥,后来...