Skip to content

Latest commit

 

History

History
312 lines (220 loc) · 9.81 KB

design_ideas.md

File metadata and controls

312 lines (220 loc) · 9.81 KB

运动会分数统计系统设计思路

当咱第一次抽到这题的时候,其实咱是拒绝的……因为咱觉得,这题目不够有趣,不够神必,你不能让咱写,咱就去写,甚至网上本身就能搜到十万甚至九万个n年前的c程序代码。咱还看过有些代码,那个c++它是这样写的,lable,GO

经过咱简单的分析,本题是经典的关系数据库题(x),所以只需要按照关系数据库的思路来写大概就没有问题了(x)

关系模型

其中,最小实体集是存储数据所必须的实体属性集合,扩展实体集是用户可能查询的实体属性集合

最小实体集

实体 属性名 属性类型 属性说明
school id int 学校编号
school name string 学校名称
student id int 运动员编号
student name string 名字
student gender char 性别
student schoolid int 所属学校
event id int 运动项目编号
event name string 运动项目名称
event gender char 性别
rankinfo eventid int 运动项目号
rankinfo studentid int 学生id号
rankinfo rank int 排名
rankinfo score int 分数

扩展实体集

实体 属性名 属性类型 属性说明
school student_count int 学校获取名次的人数
school score int 学校总积分
school rank int 学校总积分排名
student score int 运动员总积分
student rank int 运动员总积分排名
event student_count int 运动项目参加人数

一些说明和完整性约束

  • 所有编号从1开始
  • 本系统不考虑男女都可以参加的项目与团体参加的项目
  • 不赋分的运动员属于冗余记录,不存储与查询
  • 基于系统的功能,并不需要存储成绩
  • 本系统本版本不支持无法存储的非int型虚拟列(即仅支持部分计算型的查询)

数据规模分析

本系统需要分析的关键大概有三点:学校数、运动员数、运动项目数

注意,由于系统结构的大幅修改,以下分析已经不适用,但数量级仍可参考

  1. 学校数

    由于本项目是运动会分数统计系统,所以按照参加单个运动会的最大学校数就可以了。以下记学校数为n,粗略估计n < 256

    因此,学校的编号采用2B存储即可(但是,在学校的数据文件中并不需要存储,因为这是和位置直接相关的,下同),学校名称的长度暂定为32*4B(如果按照UTF8最大字节长)

  2. 运动员数

    根据本系统每个项目只记前5名的的原则,运动员的个数 <= 项目数*5 = 1280

    因此,运动员的编号采用2B存储即可,运动员姓名暂定为16*4B,运动员性别采用1B存储,学校编号2B

  3. 项目数

    根据不可靠消息,即将到来的东京奥运会共设34个大项、339个小项比赛。由此估算运动会的项目数 e < 256

    为统一类型,编号采用2B存储,项目名称32*4B,项目性别1B,前五名赋分5*1B,运动员编号5*2B

  4. 存储空间计算

    按照基础数据存储,学校需要128B,运动员需要64+1+2=67B,项目需要128+1+5+10=144B。

    则紧凑不压缩最大数据文件大小约为 128 * 256 + 67 * 1280 + 144 * 256 = 155392B ≈ 155KB

    如果按照扩展数据存储,则其大小计算变得较为复杂,难以使用定长存储,这里不再计算

    所以说,本问题数据规模完全大不起来,(大概)完全不需要上B+什么的,直接内存hash就完事了

    而且这排序规模俺寻思着O(n^2)也妹有问题啊

    所以这题的意义到底在哪啊(摔)

    不过,如果数据规模小的话,那么性能和空间方面的某些限制大概可以宽松些了?

功能结构

基础功能

建立数据文件

系统需要建立自己的数据文件

Load数据

系统需要从通用格式导入数据

目前计划允许XML格式数据导入,或许咱还要再学一次XML验证

注意,Load会导致覆盖而不是在原基础上增加

检验Load数据合法性

需要检验以下几点:

  1. XML
  2. 编号规则
  3. 数据类型
  4. 录入的成绩?
  5. 待定(应该还有好多。。。)

插入/删除/修改功能

根据题目要求,既然编号与学校总数已经确定,那么不可能有插入需求,项目同理。由于这两者已经确定,余以为学生变动的可能性也不大。

需要考虑的是删除和更改。

一般运动会举行完成之后只可能需要调整名次了吧,又或者学校名称或者运动员名称写错了呢(

所有查询功能

  • 学校:
    • 筛选:编号/名次/积分+性别条件/项目条件
    • 排序:编号/名称/名次/积分 + 性别条件/项目条件
  • 运动员:
    • 筛选:编号/名次 + 性别条件/项目条件
    • 排序:编号/姓名/名次/积分 + 项目条件?
  • 项目
    • 筛选:编号/参加人数/赋分方式
    • 排序:编号/名称/参加人数

扩展功能

  • 帮助、提示
  • 优化存储方式
  • 异常处理

运行程序结构

由一个控制台程序和若干个数据文件组成

DSL语法词汇表

  1. 主语

    写法 意义
    school 表示查询学校
    student 表示查询学生
    event 表示查询项目
    rankinfo 表示查询排名信息
  2. 投影

    写法 意义
    投影也可以不写
    (id, name, ...) 写在主语之后,表示投影
  3. 筛选

    写法 意义
    .id(num) 用id选择
    .eq(id,num) 相等筛选
    .gt(id,num) 大于筛选
    .lt(id,num) 小于筛选
    .ne(id,num) 不等于筛选
    .gte(id,num) 大于等于筛选
    .lte(id,num) 小于等于筛选
    .contain(name,"string") 字符串含有筛选
    .regex(name,"pattern") 正则表达式筛选
  4. 排序

    注:多个排序方式将以更后面的为更优先的排序依据

    写法 意义
    .asc(id) 按照升序排列
    .desc(id) 按照降序排列
  5. 显示与流

    写法 意义
    .skip(num) 在limit之前跳过的条数
    .limit(num) 最多显示的条数
    .csv("path") 将结果导出为csv文件
  6. 全局函数

    写法 意义
    load("path") 导入合法XML文件
    clear() 清屏
    help(command) 查看某条命令的帮助
    exit() 离开
    show(`database entity
    use(database) 转移到数据库
    drop(database) 删库
  7. 更新

    写法 意义
    注:此段已被爆破
  8. 语序

    • 除了全局函数,必须要写主语
    • 只有主语相当于没有筛选条件
    • 筛选必须写在主语(含投影)后
    • 排序必须写在筛选后
    • 显示必须写在排序与筛选之后
    • 更新必须写在最后
    • 投影对更新无效
    • 流必须写在最后
  9. 数据类型

    数据类型 说明 字段
    int 可以用来和常数比较的字段 id, count, score, rank
    string 可以使用正则表达式的字段 name
    本段已经被爆破
  10. 计算与处理

    写法 意义
    .sum() 对数组求和
    .count() 求数组的长度
    .rank() 对该字段所有行计算值,并求排名
  11. 使用例

        //单表筛选查询
        //查询所有学生
        student
        //查询所有学生的姓名
        student(name)
        //查询id=1的学生
        student.id(1)
        //查询id<=5的学生
        student.lte(id,5)
        //查询id在5到10之间的学生
        student.gte(id,5).lte(id,10)
        //查询学生"李明"
        student.eq(name,"李明")
        //查询所有名字中带有信的学生
        student.contain(name,"信")
        //查询所有名字带有叠字的学生
        student.regex(name,"(.)\1")
        //查询所有名字中带有数字的学生
        student.regex(name,"一|二|三|四|五|六|七|八|九|十|百|千|万|亿|兆")
    
        //单表排序查询
        //按照学生id反序输出10名学生
        student.desc(id).limit(10)
        //输出id最大的5~10名学生
        student.desc(id).skip(4).limit(6)
    
        //多表查询
        //待写
        //“xx”学校的所有学生
        student.eq(schoolid,student.eq(name,"xx"))
        //学校xx获奖的所有项目
        rankinfo(eventid).eq(studentid,student.eq(schoolid,student.eq(name,"xx")))
        //学生xx获奖的所有项目
        rankinfo(eventid).eq(studentid,student.eq(name,"xx"))
        //xx项目的获奖学生
        rankinfo(studentid).eq(eventid,event.eq(name,"xx"))
        //xx项目的获奖学校
        student(schoolid).id(rankinfo(studentid).eq(eventid,event.eq(name,"xx")))
        //待测试项目...

(题外话,关于”如何用正则表达式检验一个正则表达式“,可以看这里

输入格式

本项目采用全局函数load导入XML文件来实现数据与元数据的导入(所以其实是有门槛的),XML文件的结构如下:

  1. 设置部分:该部分设置本系统的部分属性
  2. 元数据部分:该部分给出数据的组织形式
  3. 数据部分:该部分给出所有数据

本系统的具体XML格式类似这里

系统缺陷

  • 本系统由于没有连接查询机制,无法查询特定数据组合。例如,无法同时查询在某场比赛中获得前五名的选手姓名和他/她获得的分数。

文件存储结构

由于数据规模很小,二进制存储就完事了

测试单元

以后再写(

语言与平台选择

C# Windows控制台

关于本项目的参考价值

毕竟xy很菜,而且只是一个要在10天之内写完的一般课程设计,所以价值并不高