แนวปฏิบัติที่ดีที่สุดสำหรับการตั้งชื่อรูปภาพที่อัปโหลดคืออะไร


15

สมมติว่าฉันมีแบบฟอร์มในเว็บแอปพลิเคชันซึ่งผู้ใช้สามารถอัปโหลดรูปโปรไฟล์

ฉันมีข้อกำหนดเล็กน้อยเกี่ยวกับขนาดไฟล์ขนาดและอื่น ๆ แต่เมื่อผู้ใช้อัปโหลดภาพฉันจะตั้งชื่อพวกเขาในระบบของฉันได้อย่างไร ฉันคิดว่ามันจะต้องมีความสอดคล้องและไม่ซ้ำกัน

อาจเป็น GUID หรือไม่?

a5c627bedc3c44b7ae7c06a44fb3fcf8.jpg

การประทับเวลา?

129899740140465735.jpg

แฮช เช่น md5

b1a9acaf295cf14ffbc5b6538294562c.jpg

มีวิธีมาตรฐานหรือแนะนำให้ทำเช่นนี้?


7
หากเป้าหมายของคุณคือการจัดเก็บรูปโปรไฟล์เพียงรูปเดียวต่อผู้ใช้บางคนอาจกล่าวว่าตัวเลือกที่ชัดเจนจะตั้งชื่อไฟล์เหมือนกับชื่อผู้ใช้
Alan Barber

การประทับเวลาไม่ใช่ความคิดที่ดีเพราะ DateTime ขณะนี้มีการรีเฟรชทุก ๆ 15ms เท่านั้น มีโอกาสสูงที่จะเกิดการชนเช่นในระหว่างการโหลดจำนวนมากคำขอที่อยู่ในคิว ฯลฯ
jhexp

คำตอบ:


27

คุณควรพยายามบรรลุเป้าหมายสองประการคือความเป็นเอกลักษณ์และมีประโยชน์

การใช้ GUID รับประกันความเป็นเอกลักษณ์ แต่วันหนึ่งไฟล์อาจถูกแยกออกจากแหล่งดั้งเดิมแล้วคุณจะประสบปัญหา

โซลูชันทั่วไปของฉันคือการฝังข้อมูลที่สำคัญลงในชื่อไฟล์เช่น userID (ถ้าเป็นของผู้ใช้) หรืออัปโหลดวันที่และเวลา (หากเป็นสิ่งสำคัญ) หรือชื่อไฟล์ที่ใช้เมื่ออัปโหลด

สิ่งนี้อาจช่วยรักษาผิวของคุณได้ในวันหนึ่งเมื่อข้อมูลที่ฝังอยู่ในชื่อไฟล์ช่วยให้คุณสามารถกู้คืนจากข้อผิดพลาดหรือการลบระเบียนโดยไม่ตั้งใจ หากสิ่งที่คุณมีคือ GUID และสูญเสียแคตตาล็อกคุณจะมีปัญหาในการทำความสะอาด

ตัวอย่างเช่นหากอัปโหลดไฟล์ "My Holiday: Florida 23.jpg" โดย userID 98765 เมื่อวันที่ 2013/04/04 เวลา 12:51:23 ฉันจะตั้งชื่อแบบนี้โดยเพิ่มสตริงแบบสุ่มad8a7dsf9:

20130404125123-ad8a7dsf9-98765 ของฉันวันหยุดฟลอริด้า-23.jpg

  • มั่นใจได้ว่ามีความไม่ซ้ำกันตามวันที่และเวลาและสตริงแบบสุ่ม (ให้เป็นแบบสุ่มจาก / dev / urandom หรือ CryptGenRandom)
  • หากไฟล์ถูกถอดออกมาคุณสามารถระบุผู้ใช้วันที่และเวลาและชื่อเรื่องได้
  • ทุกอย่างถูกพับเก็บเป็นตัวพิมพ์เล็กและสิ่งที่ไม่ใช่ตัวอักษรและตัวเลขจะถูกลบออกและแทนที่ด้วยเครื่องหมายขีดกลางซึ่งทำให้ชื่อไฟล์ง่ายต่อการจัดการโดยใช้เครื่องมือง่าย ๆ (เช่นไม่มีที่ว่างซึ่งสามารถสร้างสคริปต์ที่เขียนไม่ดี และอื่น ๆ )

7
เพื่อประโยชน์ในการดูแลทำความสะอาดฉันขอแนะนำให้สร้างไดเรกทอรีแยกกันต่อ userID ดังนั้นถ้าคุณลบผู้ใช้คุณจะไม่ต้องไปหาภาพทั้งหมด - ดังนั้น98765/20130404125123-ad8a7dsf9-my-holiday-florida-23.jpg
Shadur

1
ความเป็นเอกลักษณ์ทางทฤษฎีไม่ได้ถูกจัดเตรียมโดยสตริงแบบสุ่ม
Kolyunya

4
@ Kolyuny นั้นเป็นเรื่องจริงในแง่ที่รับประกันความเป็นเอกลักษณ์ระดับโลกไม่ใช่ทรัพย์สินที่แม้แต่ GUID ในชีวิตจริง (แม้แต่ v1 guids ก็ถูกจับเนื่องจากการออก MAC address ซ้ำ) สิ่งที่คุณจะได้รับคือความน่าจะเป็นเชิงสถิติของความเป็นเอกลักษณ์ แต่คุณสามารถมั่นใจได้ว่าไม่ซ้ำกันโดยการตรวจสอบว่าไฟล์ที่มีอยู่แล้ว (ใช้CreateFileกับอะตอมCREATE_NEW) และใช้การสุ่มที่แตกต่างกันถ้ามัน
Ben

'ทุกอย่างจะถูกพับกรณีที่ต่ำกว่าและสิ่งที่ไม่ใช่ตัวเลขจะถูกลบออกไปและแทนที่ด้วยขีดกลาง' ฉันจะให้มันผสมกรณีลบทั้งหมดเป็นตัวเลขที่ไม่ใช่อัลฟาและแทนที่ด้วยภายใต้คะแนนยกเว้นรีบสุดท้าย
tgkprog

4

คุณไม่ต้องการเน้นแอพพลิเคชั่น (เช่น Explorer) และทำให้มันล้มเหลวเมื่อคุณเปิดไดเรกทอรี แม้ว่ามันจะไม่น่าเป็นไปได้ที่คุณจะเน้นระบบไฟล์จริง แต่คุณต้องคำนึงถึงสิ่งนี้หากคุณต้องการจัดเก็บไฟล์หลายพันไฟล์

หากคุณคาดหวังว่าจะเก็บไฟล์หลายพันไฟล์ข้อเสนอแนะของฉันคือการแบ่งพาร์ติชันลงในโฟลเดอร์ ตัวอย่างเช่นupload\silo001, upload\silo002ฯลฯ คุณสามารถสร้างความสมดุลให้กับไฟล์ของคุณหรือรอจนกว่าโฟลเดอร์จะเจอไฟล์จำนวนหนึ่งแล้วสร้างไฟล์ใหม่

สำหรับการตั้งชื่อฉันมักจะตั้งชื่อไฟล์ด้วย GUID เพราะเป็นไฟล์ที่ไม่ซ้ำกันทั่วโลก ฉันดึงส่วนขยายจากการอัปโหลดและตั้งค่าส่วนขยายของไฟล์ให้ตรงกัน แต่ชื่อจริงถูกตั้งค่าจาก Guid ใหม่

หากคุณกำลังทำเช่นนี้ร่วมกับ RDBMS และมีหลายประเภทผลิตภัณฑ์คือประเภท ฯลฯ คุณอาจมีupload\products, upload\categoriesและอื่น ๆ , และคุณสามารถใช้ ID แถวเป็นชื่อไฟล์

ในแง่ของแนวปฏิบัติที่ดีที่สุดฉันเคยดูในอดีตและไม่พบอะไรเลย ฉันมาพร้อมกับข้างต้นในขณะที่คุยกับนักพัฒนาของฉัน


2

หนึ่งในโซลูชันที่ฉันทำงานเมื่อหลายปีก่อนเราทำสิ่งนี้: โฟลเดอร์ย่อยสำหรับส่วนหนึ่งของรหัสผู้ใช้ดังนั้นหากรหัสผู้ใช้ของคุณคือ 232950192

เราจะมีภาพโฟลเดอร์ย่อย / 23/29/50/192/232950192

ในโฟลเดอร์สุดท้ายจะมีโฟลเดอร์สำหรับ albuns และโปรไฟล์ imgs เป็นต้น

แต่เราบันทึกทุกอย่างในฐานข้อมูลด้วยและเก็บไว้ในระบบไฟล์เพื่อการเข้าถึงเว็บเซิร์ฟเวอร์อย่างรวดเร็ว (ซึ่งมีการแคชด้วย)

อย่างไรก็ตามภาพสุดท้ายจะมีชื่อภาพต้นฉบับ เราไม่จำเป็นต้องเก็บเวอร์ชันไว้ แต่สำหรับสิ่งที่สามารถเก็บโฟลเดอร์ย่อยเพิ่มเติมภายใต้ชื่ออัลบั้มสุดท้ายหรือในฐานข้อมูลด้วยรหัสเวอร์ชัน ต้องคิดว่ามันจะผ่านมันไปเมื่อการผลิตจะยากที่จะเปลี่ยนแปลงสิ่งต่าง ๆ โดยไม่ต้องเสียเวลาและการแก้ไขข้อผิดพลาดได้ง่ายในโครงสร้างปัจจุบัน

มันง่ายมากที่จะสร้างโฟลเดอร์ย่อยใน java และสร้างไฟล์ภายใน:

    File folder = new File(pathwithslashes);// like "images/23/29/50/192/232950192"
    folder.mkdirs();
    File imgFile = new File(folder, name);
    //Now get output stream etc

ในการรับตราประทับวันที่ในโฟลเดอร์ย่อย: SimpleDateFormat sdf = new SimpleDateFormat ("/ yyyy / MM / dd /"); pathwithslashes = pathwithslashes + sdf.format (ตอนนี้); // ตอนนี้เป็นโฟลเดอร์ไฟล์ util.Date = ไฟล์ใหม่ (pathwithslashes);

Dot net /programming/5482230/c-sharp-equivalent-of-javas-mkdirs


+1 สำหรับการแนะนำไดเรกทอรีที่ซ้อนกัน ฉันคิดว่านี่เป็นสิ่งสำคัญที่จะต้องพิจารณาเนื่องจากระบบไฟล์ที่แตกต่างกันสามารถพบปัญหาด้านประสิทธิภาพเมื่อโฟลเดอร์มีไฟล์ "มากเกินไป": stackoverflow.com/questions/197162/… , support.microsoft.com/kb/130694/en-usฯลฯ
deizel

1
ใช่ในระบบอื่นมีหนึ่งในเว็บเซิร์ฟเวอร์แฮงค์เมื่อเราพยายาม rmdir บน aa dir ที่มีมากกว่า 400,000 ไฟล์ เรามีโฟลเดอร์เพิ่มขึ้นเช่นนี้ ดังนั้นใช้โปรแกรมที่กำหนดเองที่เรียกว่า dir / p เพื่อรับไฟล์สองสามไฟล์ในเวลาเดียวกัน ใช้เวลาไม่กี่ชั่วโมง แต่ไม่มีเวลาลง :)
tgkprog

1

ฉันแนะนำให้ใช้แค่ md5 หรืออะไรก็ตามที่เทียบเท่ากับแนวคิด โดยการเปลี่ยนชื่อไฟล์โดยแยกย่อยเนื้อหาคุณไม่เพียง แต่ให้ความเป็นเอกลักษณ์ (เสมอแคชภาพให้นานที่สุดเท่าที่จะทำได้และด้วยการเปลี่ยนชื่อเนื้อหาตามดีด้วยที่เหมาะสมคุณสามารถแคชภาพจริงตลอดกาล)

นอกจากนี้ไม่ใช่เรื่องใหญ่ แต่อย่างไรก็ตามมันไม่ใช่กรณีสมมุติที่บริสุทธิ์เมื่อผู้ใช้ที่แตกต่างกันอัปโหลดภาพเดียวกันทั้งหมด คุณจะได้รับการเพิ่มประสิทธิภาพการจัดเก็บข้อมูลขนาดเล็กนอกกรอบ

สำหรับสิ่งอื่น ๆ ที่เสนอ: สำหรับฉันฉันเป็นคู่ต่อสู้ที่แข็งแกร่งในการเก็บข้อมูลเสริมทุกชนิดในชื่อไฟล์ เมื่อฉันอายุน้อยกว่ามาก (และผอมกว่าเล็กน้อย :) ฉันเป็นผู้พัฒนา Perl และมีนิสัยที่น่าสงสัยในการจัดเก็บข้อมูลเสริมมากมายในชื่อไฟล์ตามสามัญสำนึกที่อนุญาตให้ฉันเนื่องจากคุณสมบัติรูปแบบสตริงของ Perl นั้นยอดเยี่ยมมาก และฉันก็สรุปได้ว่าเมื่อพูดถึงการพัฒนาเว็บไซต์เป็นทางเลือกที่ดีกว่าเสมอในการเก็บข้อมูลที่เกี่ยวข้องกับไฟล์แยกจากชื่อไฟล์

โปรดทราบว่าทุกวันนี้เมื่ออินเทอร์เฟซมือถือมีอิทธิพลเหนือชื่อไฟล์จริงเป็นสิ่งที่สำคัญน้อยกว่าเมื่อ 5, 10 ปีที่แล้ว แต่แม้ว่าสิ่งนี้จะมีความสำคัญในบริบทของแอปพลิเคชันของคุณคุณก็สามารถมีส่วนร่วมกับเวทมนต์ของโรงเรียนเก่าด้วยการมีContent-Disposition: attachment; filename="pretty_file_name.jpg"ส่วนหัว HTTP ที่เกี่ยวข้องสร้างชื่อไฟล์ที่เกี่ยวข้องที่คุณต้องการ นอกจากนี้เบราว์เซอร์ที่ทันสมัยปูทางแอตทริบิวต์ HTML5 ใหม่ดาวน์โหลด ฉันไม่เชื่อว่าการเห็นชื่อภาพ "อ่านง่าย" จริง ๆ แล้วเป็นสิ่งที่คุณควรคิดถึงในกรณีส่วนใหญ่

UPD: การแก้ไขสามารถทำได้เพื่อไม่ให้มีไฟล์มากเกินไปในไดเรกทอรีเดียว - ใช้ตัวอักษร 3 ตัวแรกและสร้าง dir


1
md5 นั้นมีความโดดเด่นจริง ๆ หรือไม่?
I.devries

@ I.devries ฉันไม่ใช่ผู้เชี่ยวชาญ แต่เท่าที่ฉันรู้มันดีพอสำหรับวัตถุประสงค์นี้ โดยเฉพาะอย่างยิ่งหากคุณจะตรวจสอบขนาดของไฟล์เพิ่มเติมเนื่องจากอัลกอริทึมการแฮชที่ดีจริง ๆ แล้วอนุญาตให้เอนทิตีขนาดเดียวกันอาจมีการชนกันน้อยลง - stackoverflow.com/questions/2442632/…
shabunc

-1

โอกาสของการชนกับสิ่งอื่นเช่น sha4 นั้นเล็กมาก หากคุณรวมแฮชกับหมายเลขผู้ใช้หรือแม้กระทั่งวันที่เรียบง่าย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.