前语

最近工作中处理了一次客户的数据导出暂时需求,因该功能产品中没有完成,采用直接从数据库导出的方法救急。进程中有两点心得,本文聊作记载。

需求背景

设有如下的答题记载表:

一次MySQL数据导出复盘

需求补充阐明的是,这儿的id是自增的。因为每道题同一学生可能有屡次提交,所以数据记载可能是这样的:

一次MySQL数据导出复盘

现在需求导出每个人每道题最后一次答题记载相关信息。

曲线救国SQL

上面表里用数据库存储问题和答案,可能是不太合理的,这儿暂时不管。简单想到,要处理这个问题,必然要对question_idstudent_id分组,再取最大创立时间,然而这样操作后只能取到最大时间,无法指定其所在记载。当然,咱们能够先把这些数据查出来,在内存中运用其它言语分组计算获取相关数据,这儿暂时不管。

仅运用SQL完成这个需求似乎较为困难,走运的是,id字段是自增的,因而最大创立时间的记载一起也是最大id取值的记载。所以咱们有如下查询:

select student_id , question_id , question_content , answer_content
from question_answer_record_tbl qart
where id in (
    select max(id)
    from question_answer_record_tbl qart
    group by student_id , question_id
);

结果如下:

一次MySQL数据导出复盘

Base64的价值

上面咱们查到了需求的数据,接下来需求导出成Excel表格或CSV文件方式。因为出产环境Mysql不支持Dbeaver之类的可视化工具,因而只能借助Mysql自带的一些工具。简单找到如下的导出句子

select student_id , question_id , question_content , answer_content
INTO OUTFILE '/tmp/result.csv'
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
from question_answer_record_tbl qart
where id in (
    select max(id)
    from question_answer_record_tbl qart
    group by student_id , question_id
);

然而新的问题呈现了,因为question_contentanswer_content字段可能是大段的文本内容,这些内容很可能含有导出句子中的字段分隔符,形成导出文件格局紊乱。实践中结构更杂乱的分隔符也未能处理格局紊乱问题。

有没有办法能确保导出字段内容不含有字段分隔符呢?简单想到,将简单形成格局紊乱的字段Base64编码即可。项目中运用的Mysql版别正好也支持TO_BASE64()函数,最终的导出句子如下:

select student_id , question_id , to_base64(question_content) , to_base64(answer_content)
INTO OUTFILE '/tmp/result.csv'
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
from question_answer_record_tbl qart
where id in (
    select max(id)
    from question_answer_record_tbl qart
    group by student_id , question_id
);

当然,这样导出的数据需求再进行Base64解码,这儿从略。

我开始接触Base64编码就有疑问,既不能对数据进行加密,还会增加编码内容的长度,这一进程在实践中有何意义?通过此次运用,我对这一问题有了些微体会。