12/27 UPD: 下一代OIerDb前端项目在 https://github.com/OIerDb-ng/OIerDb
引言
OI巨神虞皓翔同学开发的下一代OIerDb项目现在在GitHub上开源,访问该项目的方法是前往OIerDb-ng/OIer中的oierdb-ng分支或点击此链接。新项目采用了浏览器前端存储的方式存储数据,在每次用户尝试询问时不需要访问服务器,但在数据更新或第一次访问时需要下载所有数据。
这个项目目前实现的逻辑和当前的OIerDb差不多,但新的项目的代码更加工程和正规,因此对于新人更友好,更适合进行扩展。新项目也处在还没有前端的开发的中间阶段,我感到因此这个项目可以从头就做的更好。这就需要更多选手参与进这件事情。由于我时间比较有限,我在此打一个广告呼吁广大对信息学竞赛感兴趣的朋友们积极参与开发OIerDb-ng,并发表一点我对新项目开发的一点看法。
数据存储结构以选手、获奖记录、学校分别同等对待
当前OIerDb数据存储结构有两个表,其中一个表为选手表,存储着形如(UID,姓名,拼音,年级,(获奖记录 1,获奖记录2,获奖记录3,…)…)的信息,另一表为学校表,存储着形如(省份,地市,学校名称,学校获奖统计,学校分数,…)的信息。
我感觉如果可以所有数据都在浏览器处理,可以在选手表和学校表之外另建一获奖记录表,存储形如(UID,姓名,学校,排名,分数,比赛,年级,奖项,…)的信息,而不直接存在选手表对应选手内。
这样有一点好处,就是可以处理以获奖记录为中心的询问:(显示NOIP2021中山东大学附属中学的获奖记录)。另外有可能可以使得每次数据更新时产生的diff更可控(?)
统一询问的逻辑,添加以获奖记录为中心询问的功能
感觉前端实现时,如果不同的表是分开的逻辑比较清晰,大概就是“给出一定的限定信息,查询某个表”。比如查询信息学竞赛选手,无论“限定信息”是如何给出的,大体逻辑还是要找到对应的选手。在当前的OIerDb上点击选手时,显示了选手的所有获奖记录,这个逻辑在获奖记录不和选手存储在一起时也非常简单:“询问所有当前点击的UID的获奖记录”。
对应的,对于获奖记录和学校也可以这么做。这么一来,就可以查询获奖记录了,如“查询济南市NOIP获奖记录”,“查询某年NOI获奖记录”,“查询某校全部NOI获奖记录”等等。查询学校也可以类似做,我们可以发现这么一来查询的能力是严格比当前的OIerDb优的,因为当前查询学校只能按照省份和地市选。
对应的,如果点击获奖记录的姓名栏,逻辑可同“询问所有当前点击的UID的获奖记录”一样,跳转到查询人,点击学校栏,可以直接查询对应学校。这样非常符合逻辑。
在数据更新时,充分利用数据更新差异较小的特性
据我观察OIerDb-ng的数据压缩之后只有不到2M,其实已经很小了。但是考虑到有些机器和情况网络连接确实较慢,除了想办法把服务器搞快之外也可以考虑采取一些措施使得“获取新数据”这一步传输远小于2M的量,如只传输一个“区别”文件再在客户端实现具体的“区别”。
感觉上如果希望服务器端静态实现的话,可以在生成数据时维护“当客户端数据的hash为某个版本时,应当执行什么操作”的文件。感觉逻辑上当数据差距不大,就说“将某个地方如何修改一下,再重新解释数据”,差距大时就说“直接重新解释如下的数据”。
结语
希望广大对信息学竞赛感兴趣的朋友们积极参与开发OIerDb-ng,想到更多使得项目变好的方法并开发出一个能用的用户界面,共同为信息学竞赛选手作出贡献。
发表回复