Frage

ich Tausende von Bildern bin immer von Tausenden von Benutzern auf meinem Linux-Server hochgeladen, die von 1and1.com gehostet wird (ich glaube, sie CentOS verwenden, aber ich bin nicht sicher, welche Version). Dies ist eine Sprache Agnostiker Frage ist jedoch, für Ihre Referenz, ich bin mit PHP.

Mein erster Gedanke war nur sie Dump alle im gleichen Verzeichnis, aber ich erinnere mich vor einiger Zeit gibt es eine Grenze war, wie viele Dateien oder Verzeichnisse können in einem Verzeichnis abgelegt werden.

Mein zweiter Gedanke war es, die Dateien in Verzeichnissen auf dem Benutzer E-Mail-Adresse basierend zu partitionieren (wie es ist, was ich für die Benutzername sowieso bin mit), aber ich mag nicht in die Grenze für Verzeichnisse in einem Verzeichnis auszuführen. ...

Wie auch immer, für Bilder von user@domain.com, wollte ich dies tun:

/images/domain.com/user/images...

Ist das klug zu tun, was ist, wenn Tausende von Benutzern haben sagen ‚gmail‘ vielleicht könnte ich noch tiefer gehen, wie diese

/images/domain.com/[first letter of user name]/user/images...

so für mike@gmail.com es wäre ...

/images/domain.com/m/mike/images...

Ist das ein schlechter Ansatz? Was alle anderen tun? Ich möchte nicht, auch mit zu vielen Verzeichnissen auf Probleme stoßen ...


Siehe auch:

War es hilfreich?

Lösung

Ich würde folgendes tun:

  1. Nehmen Sie einen MD5-Hash jedes Bild, wie es kommt.
  2. Schreiben, dass die MD5-Hash in der Datenbank, wo Sie den Überblick über diese Dinge zu halten.
  3. Speichern Sie sie in einer Verzeichnisstruktur, wo Sie die ersten paar Bytes des MD5-Hash-Hex-String als Richt-Namen verwenden. Also, wenn der Hash 'abcdef1234567890' Sie es als 'a / b / abcdef1234567890' speichern würden.

Mit auch ein Hash können Sie verschmelzen das gleiche Bild mehrmals hochgeladen.

Andere Tipps

erweitern auf Joe Beda Ansatz:

  • Datenbank
  • Datenbank
  • Datenbank

Wenn Sie kümmern sich um die Gruppierung oder Dateien durch Benutzer, Dateiname, Uploaddatum zu finden, Foto-genommen-on date (EXIF) usw., speichern diese Metadaten in einer Datenbank und verwenden Sie die entsprechenden Abfragen die entsprechenden Dateien auszuwählen .

die Datenbank Primärschlüssel verwenden - ob eine Datei Hash oder eine selbstinkrementierende Nummer - Dateien unter einem festen Satz von Verzeichnissen zu finden (alternativ verwendet ein festes Maximalanzahl-Dateien N pro Verzeichnis, und wenn Sie füllen gehen Sie auf die nächste, zB k th Foto bei {somepath}/aaaaaa/bbbb.jpg gespeichert werden sollen, wo aaaaaa = floor (k / N), formatiert als Dezimalzahl oder hex, und bbbb = mod (k, N), vorformatiert als Dezimalzahl oder hex. Wenn das zu flach eine Hierarchie für Sie, verwenden Sie so etwas wie {somepath}/aa/bb/cc/dd/ee.jpg)

Sie die Verzeichnisstruktur nicht aussetzen direkt an den Benutzer. Wenn sie Web-Browser verwenden, um Ihre Server über HTTP zuzugreifen, gibt ihnen eine URL wie www.myserver.com/images/{primary key} und den richtigen Dateityp in den Content-Type-Header kodieren.

Hier sind zwei Funktionen, die ich diese Situation eine Weile zurück, genau geschrieben. Sie haben auf einer Website über ein Jahr lang im Einsatz mit Tausenden von Mitgliedern, von denen jedes eine Vielzahl von Dateien hat.

Im Wesentlichen ist die Idee, die letzten Ziffern jeden Mitglieds eindeutiger Datenbank-ID zu verwenden, um eine Verzeichnisstruktur zu berechnen, mit einem eindeutigen Verzeichnis für jedermann. Mit den letzten Ziffern, eher als die ersten, sorgt für eine gleichmäßige Verteilung von Verzeichnissen. Ein separates Verzeichnis für jedes Mitglied bedeutet Wartungsaufgaben viel einfacher sind, und man kann sehen, wo Leute Sachen ist (wie in visuell).

// checks for member-directories & creates them if required
function member_dirs($user_id) {

    $user_id = sanitize_var($user_id);

    $last_pos = strlen($user_id);
    $dir_1_pos = $last_pos - 1;
    $dir_2_pos = $last_pos - 2;
    $dir_3_pos = $last_pos - 3;

    $dir_1 = substr($user_id, $dir_1_pos, $last_pos);
    $dir_2 = substr($user_id, $dir_2_pos, $last_pos);
    $dir_3 = substr($user_id, $dir_3_pos, $last_pos);

    $user_dir[0] = $GLOBALS['site_path'] . "files/members/" . $dir_1 . "/";
    $user_dir[1] = $user_dir[0] . $dir_2 . "/";
    $user_dir[2] = $user_dir[1] . $dir_3 . "/";
    $user_dir[3] = $user_dir[2] . $user_id . "/";
    $user_dir[4] = $user_dir[3] . "sml/";
    $user_dir[5] = $user_dir[3] . "lrg/";

    foreach ($user_dir as $this_dir) {
        if (!is_dir($this_dir)) { // directory doesn't exist
            if (!mkdir($this_dir, 0777)) { // attempt to make it with read, write, execute permissions
                return false; // bug out if it can't be created
            }
        }
    }

    // if we've got to here all directories exist or have been created so all good
    return true;

}

// accompanying function to above
function make_path_from_id($user_id) {

    $user_id = sanitize_var($user_id);

    $last_pos = strlen($user_id);
    $dir_1_pos = $last_pos - 1;
    $dir_2_pos = $last_pos - 2;
    $dir_3_pos = $last_pos - 3;

    $dir_1 = substr($user_id, $dir_1_pos, $last_pos);
    $dir_2 = substr($user_id, $dir_2_pos, $last_pos);
    $dir_3 = substr($user_id, $dir_3_pos, $last_pos);

    $user_path = "files/members/" . $dir_1 . "/" . $dir_2 . "/" . $dir_3 . "/" . $user_id . "/";
    return $user_path;

}

sanitize_var () ist eine unterstützende Funktion Eingang zum Schrubben und sicherzustellen, es ist numerisch, $ GLOBALS [ ‚site_path‘] ist der absolute Pfad für den Server. Hoffentlich werden sie selbsterklärend sonst.

Was ich für eine andere Anforderung verwendet, aber die Ihre Bedürfnisse passen können, ist eine einfache Konvention zu verwenden.

Schrittweite von 1 und die Länge der neuen Nummer, und dann mit dieser Nummer voranstellen.

Zum Beispiel:

Angenommen, 'a' ist ein var, die mit dem letzten id gesetzt ist.

a = 564;
++a;
prefix = length(a);
id = prefix + a; // 3565

Dann können Sie einen Zeitstempel für das Verzeichnis verwenden, mit dieser Konvention:

20092305 (yyyymmdd)

Dann können Sie Ihren Pfad so explodieren:

2009/23/05/3565.jpg

(oder mehr)

Es ist interessant, weil Sie eine Sortierreihenfolge nach dem Laufenden halten können, und durch die Anzahl an gleichzeitig (manchmal nützlich) Und Sie können immer noch Ihren Weg zersetzen sich in mehrere Verzeichnisse

Joe Beda Antwort ist fast perfekt, aber bitte beachten Sie, dass der MD5 auf einem Laptop in iirc 2 Stunden sein Collidable bewährt hat?

Das heißt, wenn Sie tatsächlich die MD5-Hash der Datei verwenden, in der beschriebenen Art und Weise, Ihr Service anfällig für Angriffe zu machen. Wie wird sich der Angriff aus?

  1. hat ein Hacker nicht ein bestimmtes Foto
  2. Er sorgt dafür, dass dies schlicht MD5, die Sie verwenden (MD5 von Bild + secret_string kann ihn erschrecken)
  3. verwendet er eine magische Methode ein Bild von (verwenden Sie Ihre Phantasie hier) Hash mit dem Foto kollidiert er nicht mag
  4. Er lädt das Foto wie er es normalerweise tun würde
  5. Ihr Service überschreibt die alten mit der neuen ein und zeigt sowohl

Jemand sagt: machen wir es dann nicht überschrieben werden. Dann, wenn es möglich ist, vorherzusagen, dass jemand etwas laden wird (F. E. ein beliebtes Bild im Web bekommen hochgeladen könnte), dann ist es möglich, die „Hash-place“ es zuerst zu nehmen. Benutzer würden glücklich sein, wenn ein Bild eines Kitty hochladen, würde er feststellen, dass es tatsächlich erscheint als (Verwenden Sie Ihre Phantasie hier). Ich sage: verwenden SHA1, wie es von einem 10.000 Computer-Cluster in iirc 127 Jahren sein hackable bewiesen ist schon

?

Könnte, um das Spiel auf diesem spät. Aber eine Lösung (wenn es Ihren Anwendungsfall paßt) konnte Dateinamen Hashing sein. Es ist eine Möglichkeit, einen leicht reproduzierbaren Dateipfad mit dem Namen der Datei zu erstellen, während auch eine gut verteilte Verzeichnisstruktur zu schaffen. Zum Beispiel können Sie das Bytes des Hash-Code des Dateinamen verwenden, da es Pfad ist:

String fileName = "cat.gif";
int hash = fileName.hashCode();
int mask = 255;
int firstDir = hash & mask;
int secondDir = (hash >> 8) & mask;

Das im Weg Wesen führen würde:

/172/029/cat.gif

Sie können dann cat.gif in der Verzeichnisstruktur finden durch den Algorithmus zu reproduzieren.

HEX Verwendung als Verzeichnisnamen würde so einfach sein wie die int Werte konvertieren:

String path = new StringBuilder(File.separator)
        .append(String.format("%02x", firstDir))
        .append(File.separator)
        .append(String.format("%02x", secondDir)
        .toString();

Resultat:

/AC/1D/cat.gif

Ich schrieb einen Artikel über das vor ein paar Jahren und vor kurzem zog sie auf Mittel. Es hat ein paar mehr Details und einige Beispiel-Code: Dateiname Hashing: Erstellen eines Hash-Verzeichnisstruktur . Hoffe, das hilft!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top