java - 二进制数据存储方案(保存用户上传的文件)

标签 java file-io binaryfiles binary-data

在我们的应用程序中,我们目前正在将二进制数据保存到数据库中(这很糟糕,我知道;但这是遗留的东西,这不是我的决定)。我们正在尝试将这些数据迁移到外部设备,我正在尝试想出一个方案来保存这些文件。

我们有多个租户,我希望每个租户都有一个目录。我的方案是使用租户的前三个字母构建路径。所以如果你有一个租户叫apple ,其文件位于 /a/p/p/apple .在这些目录中,我将保存文件。对于这些文件,我想生成一个随机的 6 个字符的字母数字名称(由于内部原因,暂时只有小写字符)。因此,如果我们生成一个名为 6a8jxo 的文件名, 它将存储为 <tenant>/6/a/6/6a8jxo .使用此策略,每个租户最多可以拥有大约 9160 亿个唯一文件(并不是我们试图保存那么多),每个目录最多有 46,656 个文件。如果我选择 5 个字符的名称,我们将拥有最多 605 亿个唯一文件,每个目录有 1,296 个文件。

这种方法有什么缺点吗?我意识到某些目录可能只包含一个或两个文件,但在我看来这不是一个大问题。

我的同事不想这样做;他想在数据库中使用一个自动递增字段,然后将目录结构基于该字段的十六进制值(我假设为 32 位),而不是使用租户。按照他的策略,十六进制值将按如下方式使用:文件将存储在位于 <tenant>/aa/bbb 的目录中。其中 aa是十六进制值的前两个字符(最重要的半字节),bbb就是接下来的三个。他的理由是,他只想在一个目录已满时创建新目录,而不是拥有许多、部分填满的目录。

这种方法在代码方面带来了很多困难,我不认为拥有完全填充的目录是证明为此需要付出额外努力的理由。

是否还有其他我没有考虑过的策略或方法?

最佳答案

我认为您没有考虑的主要问题是您的随机文件名发生冲突的可能性。

使用如此小的名称,您只有 36 ^ 6 = 2,176,782,336 个唯一文件,这意味着您很可能在达到 50,000 个文件 ( http://en.wikipedia.org/wiki/Birthday_problem ) 之前发生冲突 - 这不是一个很大的数字 (当然,总是有机会更早地得到一个)。

我喜欢你同事的方法,因为它保证了唯一的名称,无论它如何影响文件系统。

如果你绝对不想依赖数据库来生成一致的序列,你可以使用UUIDs对于名字。

您似乎也在为非常深的树做计划——您希望有多少文件(和租户)?一个合理的经验法则是每个目录有 10,000 个文件(实际的,不仅仅是可能的),现代文件系统可能更多。三级子目录几乎肯定是矫枉过正。

此外,如果您确实需要将租户拆分到多个目录中,请先对它们进行哈希处理(或使用数据库 ID)- 使用自然名称会导致非常不平衡的“桶”(这里可能不是什么大问题,但它不会'正确地做这件事不需要任何成本)。

最后,文件有多大?根据您的实际用例,将它们存储在数据库中可能是一种完全合理的方法。

关于java - 二进制数据存储方案(保存用户上传的文件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20501610/

相关文章:

Golang - 为什么在相似的机器上编译会导致二进制文件大小明显不同?

Java Action 监听器和 Images 在一个类中

string - 从 excel 中将字符串读入 Matlab?

c - 如何在 C 中读取 fortran 二进制文件?

c++ - 如何更快地扫描数据CD?

file-io - 为什么我尝试使用 open for write 打开文件失败?

java - 编辑二进制文件中的特定字节 - Java

java - 如何将文本设置为 ListView 中的多个选定项目

java - 带有 xml 配置的 Struts2 validator 不起作用

java - Swing 显示多个子 jframe