界定程序资源文件和数据文件

  • 作者:KK

  • 发表日期:2017.1.13


要点速读

通常我向同事们强调这个,是为了让他们能有一个明确的原则去区分绝大部分文件该放在哪个目录,特别是上传文件、数据文件这类东西


程序资源文件

程序自身的代码文件就不用说了,根据程序的结构定义好相关目录和命名空间保存,本文章不是针对这个讲

可是程序往往会用到界面,比如一个CSS文件会用到一个bg.png,那这个png图片就是程序的资源文件,因为程序要顺利地把界面显示出来,需要这个背景,一旦缺了这个背景,界面就会明显残缺,甚至用户都不容易识别出操作位置和相关信息、示意等

一般做Web项目的话程序资源文件大家都会在web目录下建立jscssimg这样的目录放相关的资源文件,这其实也没啥问题

可是程序资源文件不要跟数据文件放在一起!下面我再讲讲我理解的数据文件


数据文件

比如项目里有个业务对象叫“商品”,那商品自然就有商品图片啦,可是商品图片放哪里呢?

商品有商品表,没商品时,商品表是空的,有商品时,商品表就满满的都是数据

这是一个可有可无的数据,它并不影响程序的运行,只是影响产品运营而已

我们要着眼于“一个数据的有无是否会对程序运行产生影响”这个原则来进行数据相关文件的界定

那商品通常是个可有可无不影响程序正常运行的数据,则商品相关的图片也是可有可无的了,所以我们就说 商品的图片是一种 数据文件


界定出数据文件后,接下来要谈论的是数据文件的保存目录,我一般会保存在WEB主机的/data/product这个目录下

但绝对不会放在/img/product这个目录下,因为img目录存放着一些与程序界面紧密的相关文件,它们不是数据文件,这样分开会比较合理一点

其实就像有的人也会专门起一个upload目录一样,只是我定义的概念会更加抽象,所以叫data,其实后台添加商品时,上传的目录也是传到data/product里的,跟upload的完全是一样,只是命名问题!

甚至还包括前台用户的上传头像,一切数据相关的文件


数据文件的子目录

首先一般不会把所有数据相关的文件都挤在data下,之所以上面一直说data/product其实就是说我会在data下再建一个目录来分开,这个目录的命名就按照业务对象的英文来命名,则商品这种业务对象我自然是命名为product


太多数据文件时要适当再分子目录

比如用户头像啊,用户数量有几十万甚至几百、几千万这样的级别,如果全部头像都挤在/data/user/avatar下就坑爹了,一个目录里有太多文件的话,一旦这个目录被读取,会很消耗磁盘性能的

所以要再分一下子目录,简单的方法就是针对当前时间+随机数计算出一个MD5,取前面或后面两个(或多个)字符作为子目录的名称,甚至按照用户ID什么的来分都行,最后得出的目录结构就是这样的:

然后再把文件存到这个子目录里


数据文件不要加入到版本库

数据文件通常都不应该被加入SVN或Git等版本控制仓库中

这是新手要清楚的一个道理,比如测试环境有员工测试上传头像,传到data/user/avatar下后,一般是不会自动加入到版本库的是吧?所以这个文件就不属于版本库的控制范围了

就算上传后自动加入到了版本库,难道用户删除、更换头像时又自动删除、更新版本库的图片吗,甚至你更新版本库时把这些文件更新下来后,除了占用更多的项目容量,还对项目代码有什么实质性的意义呢?

如果说为了测试时能看到这个头像那可能太牵强了,其实能绕一下方法实现看到这个头像的,这是无关痛痒的事情,不必牺牲版本库的容量去达到这种目的

甚至代码上线时是直接把这些文件也复制上线,还是专门进入这些目录删除相关的数据图片再上线?


在版本库里,固定的数据目录应该存在并留空

数据文件不传到版本库而已,但是文件目录还是要先创建好的,比如data/user/avatardata/product什么的

首先我觉得用户每次上传文件给后端处理时,如果程序都检测data/product目录是否存在(不存在再创建?),这是很没必要的事情

商品这个业务对象在项目里是存在了的,那必然就会有商品图片,所以必然要提供data/product目录来存放,所以这个目录就应该预先创建好,而不是只留一个空的data目录叫人家自己创建product

简单地说,从效率上看,每次上传都判断product目录是否存在的话,干嘛不在项目初始化时就建好product目录让上传代码少一个判断?


而如果product里又会有几千几万张图片要再按MD5或ID什么的分子目录的话,这些子目录要不要先创建好放在版本库里就见人见智了,看自己的具体情况来定吧