Storage holds the bytes; your database holds the meaning. The pattern: store the file’s key on a record and build the URL when you need it.

Store the key, not the URL

A URL can change (a signed link expires, a domain moves). A key doesn’t. Keep the key in a column such as avatar_key and build the link on read. First add the column in Studio: Data → profiles → Columns → Add column avatar_key, type Text (short), and apply the migration (Columns and types).
Upload first, then save the key, so a record never points at a file that doesn’t exist.

Replace a file

Give the new file a new key, update the record, then delete the old key. A fresh key avoids stale caches.

Several files per record

Create an attachments table in Studio (Data → Create table): record_id, key, name, size, content_type. Save the name the person chose in name; the key itself should be generated. Give the table the owner quick set (Access tab) and an owner column.

Clean up

Deleting a record doesn’t delete its files. Remove them with the record:
Or set up a flow in Studio that listens for the delete event and removes the files (Automation), so cleanup happens even when the delete came from elsewhere.

Quotas

Largest file caps one file. Your plan caps total storage; uploads beyond it fail (in Python as QuotaExceededError, a kind of ForbiddenError). See usage under Project → Usage & plan in Studio.

Keeping data and files consistent

Upload

Upload and handle errors.

Patterns

Complete designs.