优化 Amazon S3 上的照片存储命名法
Optimize photo storage nomenclature on Amazon S3
我需要存储很多照片(+1 000 000,一张最大 5MB)并且我有一个数据库,每条记录有 5 张照片,那么最好的解决方案是什么:
- 为每条记录创建目录 slug/id,并在其中上传照片
- 将所有照片放在一个目录下,名称中包含id或slug of record
- 将所有照片放在一个目录下,在数据库中为每条记录添加照片名称字段。
我使用 Amazon S3 服务器。
这在很大程度上取决于您的用例,例如将如何使用数据库和照片。这里没有足够的信息来给出明确的答案。
但是,存储方面的一些建议...
最简单的选择就是为每张照片使用 UUID。这实际上是一个没有意义的 随机名称 。将该名称存储在您的数据库中,您的系统将知道哪个图像与哪个记录相关。无需重命名图像,因为名称只是唯一 ID,不传达更多信息。
当您想要提供对特定图像的访问权限时,您的应用程序可以生成一个 Amazon S3 pre-signed URL 来授予 对对象 的限时访问权限。过期时间后,URL 不起作用,因此该对象仍然是私有的。以这种方式授予访问权限意味着不需要按 "owner" 将图像分组到目录中,因为访问权限是按对象授予的,而不是按所有者授予的。
此外,请注意 Amazon S3 实际上并不支持文件夹。相反,对象的 Key ("filename") 是整个路径(例如 user-2/foo.jpg
)。这使它更易于阅读(因为对象 'appear' 位于文件夹中),但实际上并不影响数据在幕后的存储方式。
底线: 如何存储图像并不重要。重要的是您将图像名称存储在数据库中,这样您就知道哪个图像与哪条记录匹配。避免需要重命名图像的情况 - 只需给它们命名并保留即可。
我建议你在批量上传时这样命名你的照片:
user1/image1.jpeg
user2/image2.jpeg
虽然这些名称不会影响对象在 s3 上的存储方式,但这些名称将只是 'keys' of 'objects' ,因为在 s3 中没有像层次结构这样的文件夹,但是这样做会使对象出现在文件夹中,如果您以后想要这样做,这将有助于轻松地分离图像。
例如,假设您存储了所有具有唯一名称的图像,并且您正在使用唯一的 UUID 将数据库中的记录映射到存储桶中的图像。
但稍后假设您想要特定用户的所有 5 张照片,那么您要做的是
- 扫描特定用户名的数据库
- 检索该用户图像的 UUID
- 然后使用 UUID 从 s3 获取图像
但是如果你通过在用户名前加上前缀来命名图像,你可以直接从 s3 中获取图像而不需要引用你的数据库。
例如,要列出 user1 的所有照片,您可以在 python 中使用这个小代码片段:
import boto3
s3 = boto3.resource('s3')
Bucket=s3.Bucket('bucket_name')
for obj in Bucket.objects.filter(Prefix='user1/'):
print(obj.key)
而如果您不在对象的键中使用任何用户 ID,那么您必须引用数据库来在照片和记录之间进行映射,即使只是为了获取特定用户的图像列表
我需要存储很多照片(+1 000 000,一张最大 5MB)并且我有一个数据库,每条记录有 5 张照片,那么最好的解决方案是什么:
- 为每条记录创建目录 slug/id,并在其中上传照片
- 将所有照片放在一个目录下,名称中包含id或slug of record
- 将所有照片放在一个目录下,在数据库中为每条记录添加照片名称字段。
我使用 Amazon S3 服务器。
这在很大程度上取决于您的用例,例如将如何使用数据库和照片。这里没有足够的信息来给出明确的答案。
但是,存储方面的一些建议...
最简单的选择就是为每张照片使用 UUID。这实际上是一个没有意义的 随机名称 。将该名称存储在您的数据库中,您的系统将知道哪个图像与哪个记录相关。无需重命名图像,因为名称只是唯一 ID,不传达更多信息。
当您想要提供对特定图像的访问权限时,您的应用程序可以生成一个 Amazon S3 pre-signed URL 来授予 对对象 的限时访问权限。过期时间后,URL 不起作用,因此该对象仍然是私有的。以这种方式授予访问权限意味着不需要按 "owner" 将图像分组到目录中,因为访问权限是按对象授予的,而不是按所有者授予的。
此外,请注意 Amazon S3 实际上并不支持文件夹。相反,对象的 Key ("filename") 是整个路径(例如 user-2/foo.jpg
)。这使它更易于阅读(因为对象 'appear' 位于文件夹中),但实际上并不影响数据在幕后的存储方式。
底线: 如何存储图像并不重要。重要的是您将图像名称存储在数据库中,这样您就知道哪个图像与哪条记录匹配。避免需要重命名图像的情况 - 只需给它们命名并保留即可。
我建议你在批量上传时这样命名你的照片:
user1/image1.jpeg
user2/image2.jpeg
虽然这些名称不会影响对象在 s3 上的存储方式,但这些名称将只是 'keys' of 'objects' ,因为在 s3 中没有像层次结构这样的文件夹,但是这样做会使对象出现在文件夹中,如果您以后想要这样做,这将有助于轻松地分离图像。
例如,假设您存储了所有具有唯一名称的图像,并且您正在使用唯一的 UUID 将数据库中的记录映射到存储桶中的图像。
但稍后假设您想要特定用户的所有 5 张照片,那么您要做的是
- 扫描特定用户名的数据库
- 检索该用户图像的 UUID
- 然后使用 UUID 从 s3 获取图像
但是如果你通过在用户名前加上前缀来命名图像,你可以直接从 s3 中获取图像而不需要引用你的数据库。
例如,要列出 user1 的所有照片,您可以在 python 中使用这个小代码片段:
import boto3
s3 = boto3.resource('s3')
Bucket=s3.Bucket('bucket_name')
for obj in Bucket.objects.filter(Prefix='user1/'):
print(obj.key)
而如果您不在对象的键中使用任何用户 ID,那么您必须引用数据库来在照片和记录之间进行映射,即使只是为了获取特定用户的图像列表