آلاف الصور، كيف يجب علي تنظيم بنية الدليل؟ (لينكس)

StackOverflow https://stackoverflow.com/questions/900512

  •  23-08-2019
  •  | 
  •  

سؤال

أحصل على الآلاف من الصور التي تم تحميلها من قبل الآلاف من المستخدمين على خادم Linux الخاص بي، والتي استضافتها 1and1.com (أعتقد أنها تستخدم Centos، لكنني غير متأكد من الإصدار). هذا هو سؤال لغة غير مرجعية، ومع ذلك، فإنني أستخدم PHP.

كانت فكرتي الأولى هي مجرد تفريغهم جميعا في نفس الدليل، ومع ذلك، أتذكر منذ فترة قصيرة، وكان هناك حد لو-- يمكن إسقاط العديد من الملفات أو الدلائل في دليل.

فكرتي الثانية هي تقسيم الملفات داخل الدلائل المستندة إلى عنوان البريد الإلكتروني للمستخدمين (كما هو ما أستخدمه لاسم المستخدم على أي حال) لكنني لا أريد تشغيله إلى الحد الأقصى للدليل في دليل ....

Anyhow، بالنسبة للصور من User@domain.com، كنت سأقوم بذلك:

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

هل هذا ذكي للقيام به، ماذا لو قال الآلاف من المستخدمين "gmail" ربما يمكن أن أذهب أعمق، مثل هذا

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

لذلك بالنسبة mike@gmail.com سيكون ...

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

هل هذا نهج سيء؟ ما يمكن أن يفعل الآخرون؟ لا أريد أن أجري مشاكل مع الكثير من الدلائل أيضا ...


متعلق ب:

هل كانت مفيدة؟

المحلول

سأقوم بما يلي:

  1. خذ تجزئة MD5 لكل صورة كما يأتي.
  2. اكتب أن MD5 Hash في قاعدة البيانات حيث تتبع هذه الأشياء.
  3. قم بتخزينها في هيكل الدليل حيث تستخدم أول بايت بايت من سلسلة HEX HEX MD5 كاس دير. لذلك إذا كان التجزئة هو "ABCDEF1234567890"، فأنت ستتخزينها ك "A / B / ABCDEF1234567890".

يتيح لك استخدام Hash أيضا دمج الصورة نفسها التي تم تحميلها عدة مرات.

نصائح أخرى

للتوسع في نهج جو Beda:

  • قاعدة البيانات
  • قاعدة البيانات
  • قاعدة البيانات

إذا كنت تهتم بتجميع أو العثور على ملفات من قبل المستخدم، أو اسم الملف الأصلي، أو تاريخ التحميل، أو تاريخ التقاط الصور (exif)، وما إلى ذلك، قم بتخزين البيانات الوصفية هذه في قاعدة بيانات واستخدام الاستعلامات المناسبة لاستلام الملفات المناسبة.

استخدم مفتاح قاعدة البيانات الرئيسية - سواء كان علامة تجزئة الملفات أو رقم AutoinCrality - لتحديد موقع الملفات بين مجموعة ثابتة من الدلائل (بدلا من الدلائل) استخدام أقصى عدد ممكن من الملفات N لكل دليل، وعندما تملأ الذهاب إلى واحد القادم، مثل كيجب تخزين الصورة في {somepath}/aaaaaa/bbbb.jpg حيث aaaaaa = floor (k / n)، منسق كمرض عشري أو عرافة، و bbbb = mod (k، n)، منسق كرقم عشري أو عرافة. إذا كان هذا هو تسلسل هرمي للغاية بالنسبة لك، فاستخدم شيئا مثل {somepath}/aa/bb/cc/dd/ee.jpg)

لا تعرض هيكل الدليل مباشرة للمستخدمين. إذا كانوا يستخدمون متصفحات الويب للوصول إلى الخادم الخاص بك عبر HTTP، فمنسعهم عنوان URL مثل www.myserver.com/images/mismary key} وتشفير النمط المناسب في رأس نوع المحتوى.

فيما يلي وظيفتان كتبته أثناء ظهوره بالضبط هذا الموقف. لقد تم استخدامها لأكثر من عام على موقع مع الآلاف من الأعضاء، لكل منها الكثير من الملفات.

في جوهرها، تتمثل الفكرة في استخدام الأرقام الأخيرة من معرف قاعدة البيانات الفريد لكل عضو لحساب بنية دليل، مع دليل فريد للجميع. باستخدام الأرقام الأخيرة، بدلا من الأول، يضمن المزيد من الانتشار حتى الدلائل. دليل منفصل لكل عضو يعني مهام الصيانة هي أكثر بساطة، بالإضافة إلى أنه يمكنك معرفة أين تكون أشياء الناس (كما في بصريا).

// 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 () هي وظيفة داعمة لإدخال التنظيف وضمان ذلك الرقمي، $ Globals ['site_path'] هو المسار المطلق للخادم. نأمل أن يكونوا من التفسير الذاتي بطريقة أخرى.

ما اعتدت على شرط آخر ولكنه يمكن أن يصلح احتياجاتك هو استخدام اتفاقية بسيطة.

زيادة بنسبة 1 واحصل على طول الرقم الجديد، ثم بادئة مع هذا الرقم.

علي سبيل المثال:

افترض "A" هو Var الذي تم تعيينه مع المعرف الأخير.

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

ثم، يمكنك استخدام Timestamp للدليل، باستخدام هذه الاتفاقية:

20092305 (yyyymmdd)

ثم يمكنك تطبيق مسارك مثل هذا:

2009/23/05/3565.jpg

(او اكثر)

من المثير للاهتمام لأنه يمكنك الاحتفاظ بترتيب الترتيب حسب التاريخ، وعن طريق في نفس الوقت (مفيد في بعض الأحيان) ويمكنك أن تظل تحلل مسارك في المزيد من الأدلة

جو إجابة جو Beda مثالية تقريبا، لكن يرجى ملاحظة أنه ثبت أن MD5 قد تم ترويضه في IIRC 2 ساعة على كمبيوتر محمول؟

ومع ذلك، إذا كنت ستستخدم فعلا التجزئة MD5 MD5 في الطريقة الموصوفة، فستصبح خدمتك عرضة للهجمات. كيف يشبه الهجوم؟

  1. القراصنة لا يحب صورة معينة
  2. يضمن أن هذا هو عادي MD5 الذي تستخدمه (MD5 من الصورة + Secret_String يمكن أن يخيفه)
  3. يستخدم طريقة سحرية لتصميم صورة (استخدم خيالك هنا) التجزئة مع الصورة التي لا يحبها
  4. يحتفظ الصورة كما لو كان يفعل عادة
  5. خدمتك الكتابة فوق القديم مع واحد جديد ويعرض كليهما

يقول أحدهم: دعونا لا نكتتبه بعد ذلك. ثم، إذا كان من الممكن التنبؤ بأن شخصا ما سيتم تحميل شيء ما (قد يتم تحميل صورة شائعة على الويب)، فمن الممكن أن تأخذ "مكان التجزئة" أولا. سيكون المستخدم سعيدا عند تحميل صورة كيتي، سيجد أنه يظهر بالفعل باسم (استخدم خيالك هنا). أقول: استخدم Sha1، كما ثبت أنه قابل للقرصنة في IIRC 127 عاما بواسطة مجموعة 10.000 جهاز كمبيوتر؟

قد تكون متأخرة إلى اللعبة في هذا. ولكن حل واحد (إذا كان يناسب حالة استخدامك) يمكن أن يكون اسم الملف. إنها طريقة لإنشاء مسار ملف استنساخ سهل الاستخدام باستخدام اسم الملف أثناء إنشاء بنية دليل موزعة جيدا. على سبيل المثال، يمكنك استخدام البايتات من Hashcode اسم الملف كما هو المسار:

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

هذا من شأنه أن يؤدي إلى الطريق يجري:

/172/029/cat.gif

يمكنك بعد ذلك العثور cat.gif في هيكل الدليل عن طريق إعادة إنتاج الخوارزمية.

باستخدام Hex كأسماء الدليل سيكون سهلا لتحويل int القيم:

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

مما يسبب:

/AC/1D/cat.gif

كتبت مقالة حول هذا منذ بضع سنوات وانتقلت مؤخرا إلى المتوسطة. لديها عدد قليل من التفاصيل وبعض رمز العينة: اسم الملف Hashing: إنشاء هيكل دليل هش. وبعد أتمنى أن يساعدك هذا!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top