学员问答精选 – 1 – 数据库表拆分

问题

有学员提问,说他在用一个数据库,里面有一个典型的ToDoList表:

  • id
  • title:标题
  • isFinished:是否完成
  • isRemind:是否提醒
  • remindDateTime:提醒时间
  • remark:备注

因为在用户长时间使用后,已完成的任务会很多,如果把两个表写成一个,可能会有比较多的不必要的检索。

所以,他把这个表拆成两个,结构完全一样,一个叫Undone(未完成),一个叫Done(已完成),Done里面的isFinished的值是true。

可是他后续写业务逻辑的时候,发现这样的写法,当切换任务是否完成的状态的时候,需要更新该任务的isFinish,并将该项从原来的表删除,再加入新的表。

因为该数据库没有提供能直接移动该项到另一个表的方法,后来他也想了想这个结构,感觉有点问题,可是他又说不上来是什么问题。

 

大家觉得这个设计有什么优劣点?你是否能提供更好的解决方案?我下面会提供我的建议。

 

方案

一般来,这个设计没问题,毕竟随着数据量增加,如果所有数据放在同一个地方,对未完成项目的过滤会越来越慢,但是,我在课程中曾经说过,任何设计都是妥协的结果,都有trade-offs,而且,我还说过KISS,奥卡姆剃刀,不要over-engineering。

其实,如果你不想在表之间挪动数据,还有一个办法,就是不要给ToDoList分开2个表,还是一个表管理,但是,引入另外一个表,叫Undone {id},里面只放未完成的项目的id,因为一般未完成的相比越来越多的完成的,比例会越来越低,每次检索未完成,只需要从Undone那里取id,然后从ToDoList那里查Id IN ( IDs from Undone ),具体语法看具体的数据库,请自行搜索。

 

爆栈之旅

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

核心价值
  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
  • 解答各种技术问题
  • 为公司提供技术解决方案

请查看本站右边的信息联系我。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

  1. 可以按ID切割,垂直分表。
    具体做法是 ID 1~1000放到 A表,1001 ~ 2000 放到 B 表。