0

我正在重新设计我的网络应用程序,该应用程序主要来自用户照片。我们的照片量通常在数百万或每个用户高达 35 张。

无论如何,我想做的是重新设计我们如何将照片存储在文件系统上并在数据库中引用它们。我们当前的系统有效,但并非没有缺陷。

目前我这样存储它们

用户数据库表

pk 1 
photo_count 12

最终成为目录

storage/000/000/000/000/001/1_640x480.png

直通

storage/000/000/000/000/001/12_640x480.png

目录来源于用户pk

文件名中的第一个数字是排序顺序

文件名是指照片大小。

这是将照片存储在数据库中的一种非常有效的方法,但它并非没有缺陷。每当排序更改时,我们必须首先将更改写入临时目录,然后覆盖主目录中的所有照片,这并不是那么有效。我们还将照片导出到其他网站,我们当前系统的问题是,如果照片被修改,名称永远不会改变,因此第三方网站永远不会知道从提要中刷新照片。最后一个主要问题与照片计数与目录计数不同步有关。这导致我们从数据库 photo_count 生成照片 URL,这些 URL 可能存在也可能不存在,这会导致某些第三方站点在照片导入作业中失败。

我有目的的解决方案是执行以下操作,但我想要专家意见。

user database table
pk "1"
photos "stored as a comma separated list of photo names generated from SHA-1" example: 

f56c0de1c61fdb926e79e8a0a65bd12930c9.jpg,ec1c55bfb660548a6770238668c4b117d92f.jpg

我的想法是将照片排序顺序存储在列表中,所以如果顺序发生变化,我所要做的就是重新排列列表而不是重命名照片。

我想我可能会继续从用户 pk 派生我的目录结构,尽管我更喜欢使用某种哈希,但我只是不确定如何在数据库中引用它,如果这是首选方法。它只是存储在另一列中吗?例子

00e4 becomes /00/e4/

我似乎遇到的唯一另一个问题是照片大小,假设我仍然需要存储缩略图。是否建议使用 _thumb.jpg 为文件名添加后缀?

我认为这将全部解决第三方提要,因为每张照片都有一个唯一的名称,该名称总是在修改时更改。

有人对这个问题有专家意见吗?我不确定这是最好的解决方案,所以我想听听其他人在做什么。非常感谢。

4

1 回答 1

1

不确定我是否完全理解了这个问题,但我会描述他们解决相同任务的方式(唯一的区别是我们创建了一个任意文档库)。

主数据库条目是 docs 表:

Id              -- file id, pk
UserId          -- owner id
Size            -- file size in bytes
FileName        -- name to display like 'img.jpg'
ContentType     -- image/jpg
FileLocation    -- location of the file on filesystem.
                -- in our case it was something like {storage-root}/{userid}/{guid}
ThumbLocation   -- location of a preview version of the same file.
Created         -- upload time

所以上传算法:

  • 从用户那里获取文件。
  • Document创建符合上表结构的空对象。
  • 设置doc.FileName为原始文件名(“img.jpg”)。
  • 在每个模板“/files/{userid}”的文件系统中计算目标文件夹。
  • 生成唯一的文件名 (Guid.New()) 并将其值保存在doc.FileLocation.
  • 将文件写入doc.FileLocation.
  • 设置doc.Size为原始文件大小。
  • 如果是图片,生成预览文件,生成它的名字:doc.ThumbLocation = doc.FileLocation + "thumb".
  • 写拇指文件。
  • 保存doc到数据库。

当用户请求文件列表时(通过 url like /files/{userid}):

  • 从数据库中读取所有用户的文档
  • 请注意,排序选项不受物理文件及其位置的影响。所有必需的信息都已在表中)。
  • 向用户显示文档列表。
  • 每条记录显示doc.FileName,doc.Size和一个指向/files/{userid}/{fileid}

当用户通过 url 请求文件时/files/{userid}/{fileid}

  • 从数据库中读取文档
  • 从加载文件doc.FileLocation
  • 发送给用户。

结论:我们仅在上传时管理物理文件和位置。其余的操作仅基于我们放入数据库的数据。然后获取文件内容,我们依赖于写入表的路径,并且不打扰它们的确切含义。

于 2013-10-02T07:51:46.953 回答