附件系统应该怎么设计比较好?

2021-12-15 12:46:17 +08:00
 dssxzuxc
假如我有 20 张以上的业务表,每张表需要一个或多个附件字段,比如 xxx 信息表,有一个证明材料字段,有个验收材料字段,都是可以上传多个附件的。那我该怎么设计附件系统比较好?
我的初步设想是,首先一个附件主表 file,一个附件从表 file_detail,一对多,从表存文件的路径和具体信息,每个业务表的附件字段存 file_id,这样就能关联起来。但是开发的时候又犯难了,上传的时候,我这么设计文件上传又没办法关联到业务表(上传和表单提交是分开的)。我想到文件上传之后,我把 file_id 返回给前端,前端提交表单再一起提交上来。但是这样又有新的问题,如果用户想要分次上传,比如两张图片,他先上传了 1 张,然后再传另 1 张,就会返回两个 file_id 过来。
我看了公司之前有个项目也涉及到附件,他是这么做的,附件表每多一个业务表就加一个字段,20 张业务表就是 20 个 idxxx 、idxxx 这样的字段,上传的时候把自己的主键存到对应字段,不过这样没办法业务表多附件字段,除非 idxxx 字段加后缀接着细分,而且数据库一堆 null 有点蛋疼。
各位有什么好的建议吗?
4357 次点击
所在节点    Java
32 条回复
thinkershare
2021-12-15 13:28:23 +08:00
这个问题不是很容易解决吗? 文件上传只做上传, 不要做任何逻辑就好了, 逻辑交给业务接口处理, 文件只返回临时存储的地址, 后面的文件上的业务由业务接口处理
Ayanokouji
2021-12-15 13:38:11 +08:00
minio
eason1874
2021-12-15 13:39:27 +08:00
用户要填表,进入表单,你就初始化表单,就是往数据库插入一条空信息,返回业务 form_id 给前端(要检查有没有历史空表单,有应该直接返回或者删除后再创建,防止用户每次进入都创建一个空表单)

用户填表时,单独上传文件,你连着表单名、字段名一起上传,成功写入文件后就把 file_id 关联到 form_id ,返回状态时也返回字段名,根据字段名填充 file_id 到表单,提交时再验证一下
dssxzuxc
2021-12-15 16:09:51 +08:00
@eason1874 这样能实现,但是流程一下子复杂了好多
aliveyang
2021-12-15 16:37:18 +08:00
业务表中为什么要有附件字段?不是一对多么
xuelu520
2021-12-15 16:41:22 +08:00
首先你想复杂了。
1 、附件上传是独立的,存附件表信息,返回附件表的 id 。
2 、可以弄个通用关联表
例如:
业务类型 业务类型 ID 附件类型 附件 ID
A 业务 1 A1 file_id
B 业务 2 B1 file_id

这样就不用动到业务表那边去
gengchun
2021-12-15 16:47:38 +08:00
@Ayanokouji OP 也没有提他用的是 S3 ,也没有提对象存储,也没有提自己做的是分布式应用。这是怎么联想到的?
nekoneko
2021-12-15 17:22:12 +08:00
字段给个数组类型不行吗?
Mac
2021-12-15 17:34:10 +08:00
是表设计还是存储设计?

表就是简单的关联子表呗,分类完全可以用字段来替代,只记录上传后的文件名和上传者 ID ,文件直接放到存储目录下。

存储设计我现在是用 /UPLOAD/上传人 /业务号 /随机文件名.xxx 来做存储的
cp19890714
2021-12-15 17:37:07 +08:00
## 一张表即可

`id`
`batch_no`
`file_name`
`file_type`
`file_size`
`url`
`business_type`
`expire_at`
`active_flag`
`del_flag`


## interface

//打开新的 BatchNo, 返回 batchNo
openBatchNo

//添加文件到 BatchNo, 返回所有文件的执行结果
upload(String batchNo, List<File> files));

//可多次 commit. 每次 commit,激活本次提交的 file,其他 file 失活
commitBatchNo(String batchNo, List<String> fileIds)

get(String batchNo);

delete(String batchNO)


## 说明
* 1 个 batchNo 可以添加多个 file
* file 可以无限次的追加到已有的 BatchNo 中.
* 通过 active_flag 实现事务,只有 commit 后,file 才有效. 无效的 file 会被定时删除.
* 业务表使用 batchNo 关联
zoharSoul
2021-12-15 19:16:16 +08:00
业务表直接存附件(文件)地址不完事了.
弄个附件表干啥?
fpure
2021-12-15 19:38:44 +08:00
建议直接存成一个 json 到数据库里
Huelse
2021-12-15 19:59:24 +08:00
我觉得怎么设计都是家常便饭,像提交表单一样,重要的是文件放在那里,建议一开始就做好独立存储的准备
815979670
2021-12-15 20:06:08 +08:00
一个附件表即可,附件表存储 附件 id ,附件路径,附件的业务表,关联业务 id 信息。
第一步,图片上次成功,写入附件路径,得到附件 id ,返回给客户端。
第二步,业务执行保存操作,根据附件 id 附件业务表明和业务 id 写回附件表。

第一步实现了通用上传附件,第二部实现了附件的信息补全。

最后做一个定时任务,当附件表的附件上传超过一定时间(如 24 小时),但是没有回写 业务 id 的就是脏数据(上传了福附件但是没有保存的),定时清除数据和对应文件。
janus77
2021-12-15 20:31:30 +08:00
附件只需要一张表,file 表就不要了,业务表就包含了 file 的功能。
为什么业务表和附件表不能一对多?
hingbong
2021-12-15 21:16:37 +08:00
MySQL blob 直接存😏
Valid
2021-12-15 22:12:08 +08:00
minio 直接用 s3 的 sdk
dssxzuxc
2021-12-16 00:14:14 +08:00
@nekoneko 那样展示整页的表单数据就有点麻烦了,每行的多个数组分别做一次查询?还是一次性把所有的数组合并然后查出所有的附件,然后再多次遍历放到各自的业务列表里去?
857681664
2021-12-16 09:12:52 +08:00
把附件信息以 json 数组的形式存进附件表,同时用 id 和 type 字段与相对应的业务表进行关联
nekoneko
2021-12-16 10:34:04 +08:00
@zoharSoul #11 附件删除了怎么办

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

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

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

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

© 2021 V2EX