Your plan 1 is good to go, but here is a bit of variation to consider :
The db table will have s3 link to file.
If your backend application requires only one bucket , it is not necessarily to store the same bucket link for each row to your database table, instead you can keep the bucket link as constant variable in code implementation, unless the backend application requires several buckets based on your design. Also note that one bucket can store unlimited amount of objects (files)
I am using a table for more requirements like attaching thumbnails which are processed and updated after the photo is uploaded, asynchronously.
It depends on the requirement of your frontend user interface. Typically fixed number of picture thumbnails are predefined, that is, each thumbnail comes with different shape (width and height , e.g. 2 types of thumbnails could be applied, one is 30x30 for mobile app, the other is 70x70 for web frontend .. etc). In such case it is OK to generate all the thumbnails when storing the uploaded picture.
However if your frontend requires variable number of thumbnails in terms of its shape, (e.g. Let end-users determine the shape of the thumbnail), it would be good to :
- generate thumbnail on the fly when your backend application receives the first request to a thumbnail along with specific height and width parameter, e.g.
https://PATH/TO/FILE_ID?width=123&height=234 - store the generated thumbnail back to cloud storage like s3
- and then cache the generated thumbnail, for subsequent requests to the same file,
For dynamic downsizing picture approach and fast lookup , you can also apply some kinds of naming conventions to these thumbnail files rather than store them to your database table, e.g. the original picture is MY_IMAGE_<FILE_ID>.jpg , a specific thumbnail of the picture could be MY_IMAGE_<FILE_ID>_<HEIGHT_PX>_<WIDTH_PX>.jpg where <HEIGHT_PX> and <WIDTH_PX> are the pixel value of the height and width accordingly.