用户发表一篇文章,插入图片之前先上传图片到了服务器,但他并未发布就把网页关掉了,怎么处理?

2014-04-26 19:17:03 +08:00
 vvniu
目前的思路是每上传一张图片就在数据库里建立一个一数据,加一个字段0,当发表时正则过滤所有文章里的图片然后改写数据库里相应图片的字段为1,然后在夜深人静没人上网的时候刷新一遍数据库把所有字段为0的都给清空了。但是自己觉得是一个好不靠谱的方法啊。。。。any idea?
8121 次点击
所在节点    程序员
36 条回复
vvniu
2014-04-27 00:00:02 +08:00
@raincious 这样倒是确实可行,试试看
odirus
2014-04-27 00:05:27 +08:00
@vvniu 查找一遍所有的文件md5可以采用缓存的方法,redis里面时间复杂度为常数,不过一个大的系统每次都要在全局范围内查找的话,最终整个缓存会无比庞大,甚至不可控,这个时候可以参考关系数据库中的分库思路,按照图片类型、时间段等进行分别缓存,保存在不同的缓存服务器上。运算量最大的地方就是服务器计算文件的MD5值。不过很多时候都可以在WEB前端计算,上传图片之前先查询该文件是否已经被上传过了,我想会好一些。
raincious
2014-04-27 00:07:08 +08:00
@vvniu 嗯……我可能没说清楚,我的意思是,将文件算好MD5之后的文件名放在按照时间周期算出的目录下。不是将时间作为文件名。刚着急上床所以打错了,特此更正下。
yueyoum
2014-04-27 00:27:41 +08:00
以前我的处理方式是:

简化一下


附件表
topic_attachment

+------+---------+--------------+-----------+
| id | name | upload_date | topic_id |
+------+---------+--------------+-----------+


上传图片会先存入 topic_attachment 表,

insert into topic_attachment (topic_id) values (0)
注意这里把 topic_id 设置为0

当帖子发布成功后,就把 topic_id 设置为当前发表的帖子ID。





如果 上传完附件 ,但是帖子没发表。
当下次打开网页的时候,
就把 select * from topic_attachment where topic_id = 0;的结果返回
并提示 这些附件 需要处理,如果不处理,多少天之后会删除。


用户如果顺着提示点进去,再发贴的时候,就可以勾选这些列出来的附件。
发表完,就把那些勾选的 attachment topic_id 设置为当前发布帖子的ID。


整个流程就是这样, 既方便了用户,也给予了明确提示(如果不处理,多少天要删除)。
顺便也清理了服务器上的无用文件。



————————————————————————————————————————————————————————————————————


如果现在让我重新设计,

我会用redis。

用户只要是在编辑帖子,javascript 就不停的 ajax post 帖子的内容到 server。
server 将这些内容塞进redis,当然post的文件还是存磁盘。

如果用户编辑到一半,关闭了浏览器,再打开帖子i编辑器的时候,
javascript会向server 查询是否有帖子缓存在redis中,如果有,server会返回帖子内容,
javascript自动填充, 这样就有了自动保存的功能。

当用户点击了发表按钮后,POST到server,server再去存mysql,清理redis。

如果用户编辑到一半,然后在也不打开帖子编辑了怎么办?
用定时任务来处理,比如对于已经缓存了1周的帖子,就清除,连同它的附件。
vvniu
2014-04-27 00:54:37 +08:00
@raincious 理解的
@yueyoum 我的最终设计方式就是你这种,只不过不是过一定时间再删而是参考了一楼的方法,用户自动保存的功能我倒是觉得加一个放入草稿的按钮,让用户自己选择来得好点,要不很多时候保存一大堆没用的东西还得让用户自己删
vvniu
2014-04-27 00:57:41 +08:00
@yueyoum 刚刚看了下redis,感觉还是有必要学的,有什么好的(经验/文章/网站)指导一下吗?ps:基本不会用数据库,只会最简单的几个语句
xgod
2014-04-27 06:16:45 +08:00
先存储到临时tmp目录,保存数据库时进行从临时目录移动到正式目录,没有什么性能问题,临时目录基本不用删除,撤消带附件的记录占实际业务比例很小的,而且硬盘很便宜的,基本不用纠结。
ijse
2014-04-27 09:39:48 +08:00
楼上们说的很受用~~ 多谢大家。

我觉得保存用户正在编辑中的帖子,可以把内容保存在用户本地,比如用LocalStorage什么的,页面打开时检查本地存储的内容,如果有的话,可以提示恢复;这样用户在编辑时不必频繁与服务器通信。

对于用户上传的文件,一般也会先保存在系统临时目录中,等用户保存后再移动到存档目录中。
临时目录下的文件系统会自动清理,比如RHEL 默认会每30天清理一次旧文件,因此一般不必担心文件夹太大。

用户在上传文件前先发一个请求比对下md5是不错的方法,可以只检查最近一段时间内重复的文件,这样也可以节省用户上传文件的等待时间。

不过我还是习惯自己在确认文件没用的前提下自己清理。
learnshare
2014-04-27 11:15:39 +08:00
shinebay
2014-04-27 23:02:46 +08:00
把它C盘格式化了
lm902
2014-04-28 06:38:53 +08:00
图片缓存到浏览器local storage,点击发布才上传
dong3580
2014-04-28 11:17:03 +08:00
@ijse
保存在用户本地不可靠,某一次我编辑v2ex的帖子,回复了很长。。。然后。。。然后谷歌浏览器突然崩溃了。。。
leafgray
2014-04-28 12:07:58 +08:00
@vvniu
上传的文件有时间可以区分。。。。

定时删就是只删某个时间前的,在临时目录呆了三五天还没移到正式的应该可以认为是放弃了吧?
===
不差存储的话,就用户空间,标识下用没用。
sun019
2014-04-28 14:50:09 +08:00
别走远了 discuz 的方法挺靠谱的 但是也要看用到什么场景了
zstxt1989
2014-04-29 09:35:21 +08:00
还是先上传到临时目录,保存时移动到存储区吧。
如果要建立附件归属关系,就得用dz的方法了。
lygmqkl
2014-04-29 21:42:29 +08:00
大数据时代 分开做个单独的图床就行了。。。。 不要那么洁癖。。。。

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

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

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

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

© 2021 V2EX