12
votes

Meilleure façon de stocker une grande quantité de données des utilisateurs

Je stocke des fichiers d'utilisateurs dans leur propre répertoire de noms quelque chose comme xxx

mais si plus d'utilisateurs viennent de télécharger plus de fichiers, cela crée un problème car cela conduira à la migration de certains ou de nombreux utilisateurs. Pour un autre lecteur.Je choisissez la solution d'annuaire Nom d'utilisateur en premier lieu parce que je ne veux pas que les noms de fichiers fous soient mélangés. Je ne veux pas changer le nom de fichier aussi. De plus, si un autre utilisateur télécharge le même nom de fichier, il crée un problème, si les fichiers sont stockés avec le nom d'origine.

Quel pourrait être le meilleur moyen de le faire. J'ai une solution mais je souhaite demander à la communauté est-ce la meilleure façon.

je vais utiliser des dossiers séquentiels puis hachage le nom du fichier à quelque chose unique et à stocker dans le répertoire. Ce que je ferai, c'est stocker le nom original du fichier et le nom d'utilisateur dans la base de données et le hashvalue de nom de fichier stocké sur disque.

Lorsque quelqu'un veut accéder à ce fichier, je lirai ce fichier via PHP soit remplacer par PHP. Nom ou fera quelque chose à ce point afin que le fichier soit téléchargé comme nom de fichier original.

Je n'ai que cette solution proposée à l'esprit. Est-ce que vous avez un autre meilleur mieux que celui-ci?

EDIT:

i Utilisez le système de dossier aussi, et éventuellement pour la deuxième façon, je vais utiliser des dossiers virtuels. Ma base de données est mongodb

les gars toutes vos réponses étaient géniales et vraiment utiles. Je voulais donner une prime à tout le monde, c'est pourquoi je l'ai laissé pour que la communauté puisse fournir automatiquement. Merci tout pour vos réponses.J'ai vraiment apprécié.


11 commentaires

J'ai trouvé que l'ID utilisateur (valeur immuable) est une meilleure méthode permettant d'organiser des téléchargements. Il est plus difficile de naviguer à la main (en regardant un dossier ne vous dira pas qui télécharge), mais il permet de changer les noms d'utilisateur sans casser le dossier d'actif qui leur correspond.


@JasonsPerske hi, mais comment vais-je gérer les utilisateurs et leurs fichiers si le disque sera complet et qu'ils téléchargent continuellement.


Parce que vous créez une entrée de base de données pour chaque fichier, vous pouvez stocker un "ID de volume de stockage", que vous incrémentez chaque fois que vous manquez d'espace sur un volume de stockage. Lorsqu'un fichier est récupéré, vous obtiendrez un identifiant d'utilisateur, un nom de fichier et un nom de volume de stockage, que vous pouvez combiner pour récupérer l'actif. Je viens d'utiliser Amazon S3 et laissez-les faire affaire avec des choses comme ça


@Jasonsperske ouais mais dans mon cas. J'ai mon propre serveur pour gérer des fichiers, c'est pourquoi je dois réfléchir à cette architecture les dossiers des utilisateurs debtw dans un dossier existant est également problématique.


Vous pouvez également consulter une solution basée sur le cloud comme AWS S3 qui gérera automatiquement la mise à l'échelle pour vous. Nous utilisons une structure similaire (avec ID) pour gérer les fichiers utilisateur sur S3.


Je ne peux pas utiliser Amazon S3 comme servant le serveur de stockage, je préférerai la mienne et souhaite mettre en œuvre mon propre architecte robuste. :)


Une de mes solutions de téléchargement était de garder tout dans les dossiers en dehors du répertoire public. Sur le téléchargement, cela est enregistré dans la base de données avec le chemin de la section, c'est-à-dire: /home/user/files/1/image.png , je crée ensuite un hachage basé sur le nom du fichier et insérer l'identifiant puis enregistrer. que dans la base de données. La récupération est simplement d'utiliser php afin que nous puissions contrôler ce qui est téléchargé et le compteur de téléchargement. Tout ce qui avec le même nom de fichier n'a pas d'importance. Et regarder définitivement sur S3.


Pourquoi ne voulez-vous pas changer le nom du fichier?


@Baba pour créer un caractère unicité, je ne veux pas de noms de fichier en double dans le dir. Et pour des raisons de sécurité aussi


Sachez que si vous avez de nombreux utilisateurs (quelques milliers) que la racine I-Node peut devenir grand, une simple commande LS peut donc prendre beaucoup de temps. Donc, peut-être créer des sous-répertoires, comme / a / anakin etc. pourrait être une bonne idée.


La seule chose que je n'ai pas vue suggérée est de stocker le fichier sous un chemin / nom généré à partir d'un hachage du fichier (SHA1 ou un hachage plus peu susceptible de générer une collision et susceptible d'avoir une distribution assez même comprise entre les hachages) . Le bénéfice ici est des fichiers qui génèrent le même hachage (idéalement le même fichier téléchargé plusieurs fois) peuvent être liés à plusieurs utilisateurs via une base de données. Juste curieux s'il y a une raison ça n'a pas été suggéré.


10 Réponses :


9
votes

Pourriez-vous créer des tables de mySQL relationnelles? par exemple:

a utilisateurs code> table et a fichiers code> Table. p>

Votre table des utilisateurs garderait une trace de tout ce que vous êtes (je suppose) déjà suivi. : p>

id code>, nom code>, e-mail code>, etc. p>

alors la table des fichiers stockerait Quelque chose comme: p>

ID code>, FileExtension code>, FileSize code>, userid code> userid code> serait la clé étrangère pointant vers le champ code> ID code> dans les fichiers code> Table. p>

alors lorsque vous enregistrez votre fichier Vous pouvez l'enregistrer car il est ID code>. FileExtension Utilisez une requête pour extraire l'utilisateur associé à ce fichier ou tous les fichiers associés à un utilisateur. P>

EG: P>

SELECT users.name, files.id, files.extension
FROM `users`
INNER JOIN `files` on users.id = files.userID;


1 commentaires

, Salut je n'utilise pas MySQL à la place que j'utilise mongodb. Mais cette façon est aussi meilleure. Signifie que vous êtes en faveur de la manipulation de la base de données tous les détails des fichiers.



2
votes

Puisque le système de fichiers est un arbre, pas un graphique (classification à facettes), il est difficile de trouver un moyen de représenter facilement plusieurs entités, telles que les utilisateurs, les types de média, les dates, les événements, les types de cultures d'image, etc. L'utilisation de la base de données relationnelle est plus facile - il est convertible au graphique.

Mais depuis son autre niveau d'abstraction, vous devez écrire des fonctions qui font vous-même une synchronisation de bas niveau vous-même, notamment en évitant les collisions de noms, les noms de chemin longue, le nombre de fichiers volumineux par dossier, la facilité de transfert par entité, la mise à l'échelle horizontale, etc. Donc, cela dépend de la complexité de votre application doit être


0 commentaires

0
votes
  1. MongoDB pour stocker le nom de fichier actuel (par exemple: myImage.jpg) et d'autres attributs (par exemple: types MIME), plus $ aléatoire-text.jpg à partir de 2. & 3. ci-dessous

  2. générer un peu $ texte aléatoire , par exemple: base_convert (mt_rand (), 10, 36) ou Uniqid ($ nom d'utilisateur, true) ;

  3. stocke physiquement le fichier comme $ aléatoire-text.jpg - toujours bon pour conserver la même extension

  4. Remarque: utilisez filtre_var () pour vous assurer que le nom de fichier d'entrée ne pose pas de risque de sécurité à MongoDB.

    Amazon S3 est fiable et bon marché, soyez conscient de la "concurrence éventuelle" avec S3.


0 commentaires

2
votes

Une autre tactique consiste à créer une structure en 2 dimensions dans laquelle le premier niveau de répertoires sont les 2 premiers caractères du nom d'utilisateur, puis le deuxième niveau est les caractères restants (similaires à la manière dont git stocke ses identifiants d'objet SHA-1). Par exemple: xxx

pour l'utilisateur 'jrandomuser'.

Veuillez noter que comme les noms d'utilisateur ne seront probablement pas distribués de manière aléatoire que les valeurs SHA-1, vous devrez peut-être ajouter un autre niveau plus tard. En douteux, cependant.


1 commentaires

Votre idée est vraiment impressionnante. J'y penserai. Le problème qui reste après qu'il est toujours avec stockage de données sur disque. Comment cela peut-il être résolu si dans le cas des utilisateurs et de garder des dossiers. Comme Amazon S3 n'autorise pas les dossiers. Si ils l'ont fait, je n'aurai aucun problème à obtenir son stockage, car il leur pose son problème comment ils organisent mes fichiers.



7
votes

Je gère des métadonnées de fichier sur la base de données et rétrécissez les fichiers avec une UUID. Ce que je fais est:

  1. Identification basée sur le contenu
    1. MD5 du contenu du fichier
    2. NAMESPACED UUID: V5 Pour générer un identifiant unique basé sur l'UUID et le fichier du fichier de l'utilisateur.
    3. Fonction personnalisée pour générer un chemin basé sur "RealName".
    4. Enregistrer dans la base de données: UUID, Nom d'origineName (nom téléchargé), realName (nom généré), FileSize et MIME. (Facultatif daadded, et MD5)
    5. rétravale de fichiers.
      1. UUID pour revenir en métadonnées.
      2. Régénérer FilePath basé sur le nom de realName.
      3. OriginalName est utilisé pour afficher un nom familier à l'utilisateur qui télécharge le fichier.

        Je traite le nom du fichier qui l'attribuait une UUID de noms de noms de base de données en tant que clé primaire de base de données et génère le chemin basé sur l'utilisateur et le nom de fichier. La condition préalable est que votre utilisateur a un uuid lui attribué. Le code suivant vous aidera à éviter les collisions d'identité sur la base de données et vous aidera à identifier les fichiers par son contenu (si vous avez besoin d'avoir un moyen de repousser le contenu en double et non de noms de fichiers (/ p> xxx

        J'utilise une fonction pour générer le fichier FilePath basé sur certains paramètres personnalisés, vous pouvez utiliser $ Nom d'utilisateur et $ realName. Ceci est utile si vous implémentez une structure de dossiers distribuée que vous avez peut-être partitionnée sur le schéma de dénomination de fichiers, ou tout système personnalisé. xxx

        comme bonus supplémentaire ceci aussi:

        1. vous aide à gérer un référentiel de fichiers versé si vous ajoutez un attribut sur l'enregistrement du fichier de quel fichier (UUID), il a été remplacé.
        2. Créez une liste de contrôle d'accès aux applications si vous ajoutez des attributs de «propriétaire» et / ou de «groupe»
        3. fonctionne également sur une seule structure de dossiers.

          Remarque: j'ai utilisé $'s $ _file à titre d'exemple de la source de fichier en fonction des balises de cette question. Il peut provenir de n'importe quelle source de fichiers ou de contenu généré.


0 commentaires

5
votes

Puisque vous utilisez déjà mongodb, je suggérerais de vérifier les gridfs. C'est une spécification qui vous permet de stocker des fichiers (même s'ils sont de plus de 16 Mo) dans des collections de MongoDB.

Il est évolutif, vous n'aurez donc aucun problème si vous ajoutez un autre serveur, il stocke également des métadonnées, il est possible de lire des fichiers en morceaux et il a également intégré des fonctions de sauvegarde.


0 commentaires

0
votes

En supposant que les utilisateurs ont une carte d'identité unique (clé primaire) dans la base de données, si un utilisateur avec ID 73 télécharge un fichier, enregistrez-le comme suit:

"" Uploads / $ userid_ $ FileName. $ ext " p>

Par exemple, 73_RESUM.DOC, 73_MYPHOTO.JPG P>

Maintenant, lors de la récupération de fichiers, utilisez ce code: P>

foreach (glob("uploads/$userid_*.*") as $filename) {
    echo $filename;
}


0 commentaires

3
votes

Je générerait un GUID basé sur un hachage du nom de fichier, la date et l'heure du téléchargement et nom d'utilisateur pour le nom de fichier, enregistrer ces valeurs, ainsi que le chemin vers le fichier dans une base de données pour une utilisation ultérieure. Si vous générez un tel GUID, les noms de fichiers ne peuvent pas être devinés.

A titre d'exemple permet de prendre l'utilisateur Daniel Steiner (me) télécharge un fichier appelé resume.doc le 23 avril 2013 à 37 h à minuit et votre serveur. cela donnerait une valeur de base Daniel_Steiner + 2013/23 / 04 + 00: 37 + resume.doc qui serait alors comme 05c2d2f501e738b930885d991d136f1e de hachage MD5. veiller à ce que le fichier sera ouvert dans le programm droit, nous ajouterons ensuite le fichier à droite fin et sera donc obtenir quelque chose comme http://link.to/your/site/05c2d2f501e738b930885d991d136f1e.doc Si vos UserAccounts ont déjà un nom d'utilisateur, vous pouvez les ajouter à l'URL, par exemple, si mon nom d'utilisateur serait 123145 , l'URL serait http://link.to/your/site/123145/05c2d2f501e738b930885d991d136f1e. doc

Si vous enregistrez le nom du fichier d'origine à la base de données, vous pouvez ensuite offrir aussi un downloadscript qui fournit le fichier avec son nom d'origine pour le téléchargement, même difficile, il a un autre nom de fichier sur votre serveur.

Dans le cas où vous pouvez utiliser des liens symboliques, déplaçant les fichiers sur un autre disque dur ne devrait pas être un problème.

Si vous voulez, je pourrais trouver un exemple de PHP ainsi - ne devrait pas être trop beaucoup de code.


0 commentaires

2
votes

Je suggère d'utiliser la structure de base de données suivante:

Entrez la description de l'image ici p>

fichier code> a au moins: p>

Entrez la description de l'image ici p>

idfile code> est un auto_incrènement code> Colonne / clé primaire. userid code> est nullable code> clé étrangère. p>

pour fk_file_user code> i suggère: p>

// peform query to "File" table by given ID

list($name, $ext, $size, $md5) = $result->fetch_row();

$result->free();

header('Content-Length: ' . $size);
header('Content-MD5: ' . $md5);
header('Accept-Ranges: bytes');
header('Connection: close');
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="' . $name . '.' . $ext . '"');

// flush file content


1 commentaires

On dirait à peu près mon approche;) Et oui, je suis contre stockage de fichiers binaires dans une base de données aussi!



1
votes

Vous pouvez installer un serveur LDAP. LDAP Recherche est très rapide car il est hautement optimisé pour des opérations de lecture lourdes. Vous pouvez même interroger les données

LDAP organise les données dans un arbre comme de la mode.

Vous pouvez organiser des données comme exemple suivant "utilisateur-> adresse IP-> dossier-> nom de fichier". De ce type de fichier pourrait être étendu physiquement / géographiquement et vous pouvez récupérer l'emplacement très rapidement.

Vous pouvez également interroger à l'aide de la requête Standard LDAP pour E.G. Obtenez toute la liste du fichier d'un utilisateur particulier ou obtenez la liste des fichiers dans le dossier, etc.


0 commentaires