Должен ли я хранить загруженное имя файла в базе данных? - PullRequest
2 голосов
/ 17 апреля 2020

У меня есть таблица базы данных с идентификатором автоинкремента в качестве первичного ключа.

Для каждой записи этой таблицы у меня может быть до 3 файлов, которые могут быть общедоступными, поэтому генерация случайных файлов не обязательна, и эти файлы не являются обязательными.

Я думаю, что у меня есть 2 возможных решения:

  • Сохраните случайное сгенерированное имя файла в 3 столбце nullable varchar и сохраните все файлы в одном и том же место:

    • столбцы: a | б | c
    • uploads / f6se54fse654.jpg
  • Не сохраняйте имена файлов, а помещайте их в определенные папки c и называйте их одинаковыми чем значение первичного ключа:

    • uploads / a / 1.jpg
    • uploads / b / 1.jpg
    • uploads / c / 1.jpg

С этим последним решением я знаю, что uploads/a/1.jpg принадлежит записи с ID 1 и является файлом типа a. Но я должен проверить, существует ли файл, потому что файлы являются необязательными.

Как вы думаете, есть ли во всем этом хорошая практика? А может, есть лучший подход?

1 Ответ

1 голос
/ 22 апреля 2020

Если файлы, о которых вы говорите, предназначены для отображения или загрузки пользователями (будь то для посетителей или для прошедших проверку пользователей, отфильтрованных по ролям (ACL) или нет), важно убедиться (IMHO), что пользователь будет не сможет угадать другую информацию, кроме содержимого соответствующего ресурса, который был ему отправлен. Не существует идеального решения, которое можно было бы применить ко всем без исключения случаям, поэтому давайте возьмем пример, чтобы дать вам больше объяснений.

Для повышения безопасности и общей непрозрачности конфиденциальных данных, например, для конкретных c в случае uploads/users/7/invoices/3.pdf, я думаю, было бы разумно убедиться, что абсолютно никто не сможет угадать количество файлов, которые потенциально связаны с пользователем или любым другим объектом (поскольку в этом примере мы могли бы представить, что потенциально есть другие доступные файлы - 1.pdf и 2.pdf). По замыслу мы обычно хотим предоставить доступ к файлам в четко определенных и определенных c случаях и контексте. Тем не менее, это может не иметь место для файла изображения, который предназначен для просмотра всеми (например, фотография профиля). Вот почему контекст имеет значение в некотором роде.

Если вы решите сохранить автоматически увеличенные идентификаторы в качестве имен для ссылок на ваши файлы, это также может дать информацию о размере данных, хранящихся в вашей базе данных (/uploads/invoices/128.pdf сообщает, что у вас уже может быть 127 счета на вашем сервере) и потенциально мотивировать недобросовестных людей, чтобы попытаться получить ресурсы, которые никогда не должны быть извлечены из определенного контекста. Этот случай может быть менее очевиден, если вы решите использовать какие-то уникальные сгенерированные идентификаторы (GUID).

Я рекомендую вам прочитать эту статью относительно генерации (G) / (U ) UID (128-битные шестнадцатеричные числа) для хранения в вашей базе данных для каждого загруженного или созданного файла. Если вы используете MySQL в его последней версии, можно даже разместить этот идентификатор в типе binary (16), который предлагает автоматическое c преобразование в UUID, я позволю вам прочитать эту интересную топи c связано с тем, что я имею в виду. Вероятно, он выведет это как /uploads/invoices/b0016303-8e4f-487a-8c30-5dddf1ebf7e9.pdf, что намного лучше, если вы убедитесь, что сгенерированный идентификатор уникален, ха sh.

Мне не кажется полезным говорить о проблемах производительности, потому что сегодня существует множество методов для кэширования файлов или путей и URL-адресов, которые позволяют избежать необходимости делать запросы каждый раз во многих случаях, когда вызывается ресурс (часто упорядоченный по рангу их популярности в случаях больших данных).

Last , но не в последнюю очередь, многие веб-приложения и приложения для мобильных платформ (я думаю о Slack, Discord, Facebook, Twitter ...), которые ежедневно хранят множество медиа-файлов, которые часто связаны с пользователями аккаунтов, как общедоступными c, так и конфиденциальными файлы и информацию, генерируйте уникальный га sh для каждого из них.

Twitter использует свой собственный генератор уникальных строк (64-бит BIGINT) с именем Twitter Snowflake , который вы может быть интересно читать тоже. Он основан на значении UNIX epoch, которое по определению уникально на каждом тике миллисекунды.

Не существует глобального и идеального решения, которое можно было бы применить ко всему, но я надеюсь, что это поможет вы, возможно, захотите глубже взглянуть на это и найти «лучшее решение» для каждого контекста и объекта, который вы будете хранить и связывать файлы.

...