请问各位从数据库 SELECT *拉到程序内存里的数组,如何保证删除元素的无误和高效?

2020-01-22 12:55:26 +08:00
 Newyorkcity

有一个学生表,主键 id 是 int,对应的 java 里的数据实体里的 id 成员变量也是 int。

再这样一个 mybatis 接口

@Select("Select * from students")
List<Student> getAllStudents();

然后程序就能通过这个方法获得这个数组,就叫它studentList吧。。

现在要实现响应前端按退学按钮,退学对应学生的功能。修改数据库是很简单的。但调整程序内存中的 studentList,删除对应的学生这件事上我有点困惑,想请问各位在实际项目中是如何做的?

=======以下内容是自己一些想法,以免伸手党之嫌=========

第一种: 前端返回的如果是 Student.id (在数据库和实体对象中均是 int ),也就是数据库学生表中的主键字段的值,由于之前可能已经有删除过(即之前的删除让数据库中的主键字段值不是连续的),故直接studentList.remove(id)显然不妥。

那干脆,遍历 studentList,比较主键值,直到碰到对等的那个,然后用这个时候计数器i的值来studentList.remove(i)

第二种: 不真正地在数据库中删除这条记录,而是添加一个enable之类功能的字段,所谓的删除只是把 enable 设为 0 或者 false。

但这样的话,随着表渐渐增大,特别是其中被删掉的记录越来越多,程序就不得不带着大量无用数据在跑。同时返回给前端以供前端展示的时候,发过去的数据里这种无效的记录也很多。

第三种: 数据库里的删除仍然是真的删除,但不让前端返回 Student.id ,而是让前端在展示前根据 Student.id 排序,然后按下按钮提交上来的数据不是 student.id ,而是 student.index,也就是对应的 student 对象在数组的位置。这样借助数组的有序性,就能直接studentList.remove(index)了。。

但这个方法的问题在于,网页展现的数据如果是旧的,在这个旧的网页上让一个同学退学前,别的管理员已经让一个同学退了学,那可能会导致这次退学退了个不相干的人,想想还有点牛逼。。。那这种问题要怎么解决呢。。

谢谢

1545 次点击
所在节点    问与答
8 条回复
Raymon111111
2020-01-22 13:31:51 +08:00
让 id 是自增的, 用过的 id 不会再被用, 就不会出现那种删除-新增-删除的错误场景

是不是要真的删除? 为了防止表无限增长, 可以这么干. 但是你可以算一下究竟会有多少数据. 如果不是特别多, 可以直接用 valid = 0/1 去判断是不是被删除的数据. 如果实在需要, 最好弄一个新的表记录这些被删除的数据, 以防后续想查而没有查的地方

查的时候太多怎么办? 分页, 不要一次性全部拿出来.

最后对于学生这种场景和具体的例子, 可以有些优化去加速查询(也避免上述数据无限增长导致查询慢的问题), 比如表里可以有入学时间, 去拿在校学生时可以拿入学时间大于某个时间点的那些, 这样历史数据就不会影响查询了.

至于大表的问题, 定期归档比如十年前的学生就好了.
registerrr
2020-01-22 13:33:45 +08:00
大哥硬盘不值钱的,现在做硬删除的很少了吧.
硬删除重建索引,还浪费性能呢你不也得考虑考虑?
shenlanAZ
2020-01-22 13:39:19 +08:00
为啥要这么做?

你删掉某个数据之后需要刷新表格 重新查询的。

重要的数据是要做假删除的( isDel ),查询的时候带上条件 and is_del = 0.
kawowa
2020-01-22 13:40:22 +08:00
数据库查询不做过滤是错误的做法,至少的至少也要做数据库分页查询
前端请求:
分页大小,当前页码,搜索关键词
后端返回:
当前页码,数据总数,分页大小的 List
EminemW
2020-01-22 14:01:04 +08:00
你为什么会有这种问题?你删掉一条记录,就重新查一遍啊,为什么要一直用那个 list
Newyorkcity
2020-01-22 15:21:52 +08:00
@Raymon111111
@registerrr
@shenlanAZ
@kawowa
@EminemW

感谢几位解答!
ipwx
2020-01-22 15:27:04 +08:00
XYProblem
msg7086
2020-01-22 21:12:48 +08:00
studentList.remove,找到主键对应的记录删除就行了。
你一页才多少数据,我算你想不开一页放一万个学生的数据吧,一万条记录遍历查询主键要多久?能用得掉几毫秒吗。

如果真介意这几毫秒,那就开个哈希表做索引就行了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/639840

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX