如何在文件系统中存储图像

发布于 2024-07-06 08:01:33 字数 1236 浏览 6 评论 0原文

目前,我已将图像(最大 6MB)作为 BLOB 存储在 InnoDB 表中。 随着数据大小的增长,夜间备份变得越来越慢,阻碍了正常性能。

因此,二进制数据需要进入文件系统。 (指向文件的指针将保留在数据库中。)

数据具有树状关系:

- main site
  - user_0
    - album_0
    - album_1
    - album_n
  - user_1
  - user_n
etc...

现在我希望数据通过目录结构均匀分布。 我应该如何实现这个目标?

我想我可以尝试 MD5('userId, albumId, imageId'); 并将结果字符串切片以获取我的目录路径:

  /var/imageStorage/f/347e/013b/c042/51cf/985f7ad0daa987d.jpeg

这将允许我将第一个字符映射到服务器并均匀分布多个服务器上的目录结构。

然而,这不会按用户组织图像,可能会将 1 个相册的图像分散到多个服务器上。

我的问题是:
在将用户/相册数据保持在一起的同时,以平衡的方式将图像数据存储在文件系统中的最佳方法是什么?

我的思考方向正确吗? 或者这是完全错误的做事方式?

更新:
我将使用 md5(user_id) 字符串切片来进行最高级别的拆分。 然后将所有用户数据放入同一个存储桶中。 这将确保数据的均匀分布,同时保持用户数据紧密存储。

  /var
   - imageStorage
     - f/347e/013b
       - f347e013bc04251cf985f7ad0daa987d
         - 0
           - album1_10
             - picture_1.jpeg
         - 1
           - album1_1
             - picture_2.jpeg
             - picture_3.jpeg
           - album1_11
             - picture_n.jpeg
         - n
           - album1_n

我想我会使用从后面分割的albumId(我喜欢这个想法!)来保持每个目录的专辑数量更小(尽管对于大多数用户来说这不是必需的)。

谢谢!

Currently, I've got images (max. 6MB) stored as BLOB in a InnoDB table.
As the size of the data is growing, the nightly backup is growing slower and slower hindering normal performance.

So, the binary data needs to go to the file system. (pointers to the files will be kept in the DB.)

The data has a tree like relation:

- main site
  - user_0
    - album_0
    - album_1
    - album_n
  - user_1
  - user_n
etc...

Now I want the data to be distributed evenly trough the directory structure. How should I accomplish this?

I guess I could try MD5('userId, albumId, imageId'); and slice up the resulting string to get my directory path:

  /var/imageStorage/f/347e/013b/c042/51cf/985f7ad0daa987d.jpeg

This would allow me to map the first character to a server and evenly distribute the directory structure over multiple servers.

This would however not keep images organised per user, likely spreading the images for 1 album over multiple servers.

My question is:
What is the best way to store the image data in the file system in a balanced way, while keeping user/album data together ?

Am I thinking in the right direction? or is this the wrong way of doing things altogether?

Update:
I will go for the md5(user_id) string slicing for the split up on highest level.
And then put all user data in that same bucket. This will ensure an even distribution of data while keeping user data stored close together.

  /var
   - imageStorage
     - f/347e/013b
       - f347e013bc04251cf985f7ad0daa987d
         - 0
           - album1_10
             - picture_1.jpeg
         - 1
           - album1_1
             - picture_2.jpeg
             - picture_3.jpeg
           - album1_11
             - picture_n.jpeg
         - n
           - album1_n

I think I will use albumId splitted up from behind (I like that idea!) as to keep the number of albums per directory smaller (although it won't be necessary for most users).

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花开柳相依 2024-07-13 08:01:33

只需从后面分割您的用户ID即可。 例如

UserID = 6435624 
Path = /images/24/56/6435624

,对于备份,您可以使用 MySQL Replication 并备份从属服务器
数据库以避免备份时出现问题(例如锁定)。

Just split your userid from behind. e.g.

UserID = 6435624 
Path = /images/24/56/6435624

As for the backup you could use MySQL Replication and backup the slave
database to avoid problems (e.g. locks) while backuping.

§对你不离不弃 2024-07-13 08:01:33

将文件名分发到不同的目录中的一件事是,如果您考虑将 md5 文件名拆分到不同的子目录中(这通常是一个好主意),我建议将完整的哈希值保留为文件名,并将前几个字符复制为目录名。 这样,您可以更轻松地识别文件,例如当您必须移动目录时。

例如

abcdefgh.jpg -> a/ab/abc/abcdefgh.jpg

如果您的文件名分布不均匀(不是哈希),请尝试选择获得均匀分布的分割方法,例如,如果它是递增的用户 ID,则选择最后一个字符

one thing about distributing the filenames into different directories, if you consider splitting your md5 filenames into different subdirectories (which is generally a good idea), I would suggest keeping the complete hash as filename and duplicate the first few chars as directory names. This way you will make it easier to identify files e.g. when you have to move directories.

e.g.

abcdefgh.jpg -> a/ab/abc/abcdefgh.jpg

if your filenames are not evenly distributed (not a hash), try to choose a splitting method that gets an even distribution, e.g. the last characters if it is an incrementing user-id

久隐师 2024-07-13 08:01:33

我正在使用这个策略,给定一个唯一的图片 ID,

  • 反转字符串
  • 零,如果有奇数个数字,则用前导零填充它,
  • 将字符串分成两位数的子字符串
  • 构建如下路径

    <前><代码>17>> 第71话 /71.jpg
    第163章 第0361章 /03/61.jpg
    6978>> 8796>> /87/96.jpg
    1687941>> 01497861>> /01/49/78/61.jpg

此方法可确保每个文件夹最多包含 100 张图片和 100 个子文件夹,并且负载均匀分布在最左侧的文件夹之间。

而且,只需要图片的ID即可到达文件,无需读取包含其他元数据的图片表。
用户数据确实不是紧密存储在一起的,并且 ID-Path 关系是可预测的,这取决于您的需求。

I'm using this strategy given a unique picture ID

  • reverse the string
  • zerofill it with leading zero if there's an odd number of digits
  • chunk the string into two-digits substrings
  • build the path as below

    17 >> 71 >> /71.jpg
    163 >> 0361 >> /03/61.jpg
    6978 >> 8796 >> /87/96.jpg    
    1687941 >> 01497861 >> /01/49/78/61.jpg
    

This method ensures that each folder contains up to 100 pictures and 100 sub-folders and the load is evenly distributed between the left-most folders.

Moreover, you just need the ID of the picture to reach the file, no need to read picture table containing other metadata.
User data are not stored close together indeed and the ID-Path relation is predictable, it depends on your needs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文