การจัดเก็บหนึ่งล้านภาพในระบบไฟล์


79

ฉันมีโครงการที่จะสร้างภาพจำนวนมาก ประมาณ 1,000,000 สำหรับการเริ่มต้น พวกมันไม่ใช่ภาพขนาดใหญ่ดังนั้นฉันจะเก็บมันไว้ในเครื่องเดียวตอนเริ่มต้น

คุณแนะนำให้เก็บภาพเหล่านี้อย่างมีประสิทธิภาพได้อย่างไร (ปัจจุบันระบบไฟล์ NTFS)

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

สิ่งที่จะเป็นรูปแบบการตั้งชื่อที่ดีกว่า:

a / b / c / 0 ... z / z / z / 999

หรือ

a / b / c / 000 ... z / z / z / 999

ความคิดใด ๆ เกี่ยวกับเรื่องนี้?


1
พวกเขาเชื่อมโยงกับผู้ใช้ที่เฉพาะเจาะจงหรือเพียงแค่ทั่วไป? พวกเขาถูกจัดกลุ่มในรูปแบบใด ๆ ?

ทั่วไปเท่านั้น รูปภาพจำนวนมากที่สร้างขึ้นโดยอุปกรณ์ทางเทคนิคบางอย่าง ฉันตั้งชื่อพวกเขาที่เพิ่มขึ้นจาก 1 ขึ้นไปเพียงแค่มีความคิดของการ refence เวลา
s.mihai

พวกเขาจะใช้ / เข้าถึงอย่างไร ผ่านแอพ bespoke หรืออะไร
นกพิราบ

16
นี่คุณหรือเปล่า i46.tinypic.com/1z55k7q.jpg

1
:)) ใช่แล้ว ... 1 ล้าน ภาพโป๊ :))
s.mihai

คำตอบ:


73

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

อย่าเก็บเส้นทางที่แท้จริงไปยังฐานข้อมูล ดีกว่าที่จะเก็บหมายเลขลำดับของภาพไปยังฐานข้อมูลและมีฟังก์ชั่นที่สามารถสร้างเส้นทางจากหมายเลขลำดับ เช่น:

 File path = generatePathFromSequenceNumber(sequenceNumber);

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

ฉันจะใช้อัลกอริทึมชนิดนี้เพื่อสร้างโครงสร้างไดเรกทอรี:

  1. แผ่นแรกคุณหมายเลขลำดับที่มีเลขศูนย์นำจนกว่าคุณจะมีอย่างน้อย 12 หลักสตริง นี่คือชื่อไฟล์ของคุณ คุณอาจต้องการเพิ่มคำต่อท้าย:
    • 12345 -> 000000012345.jpg
  2. จากนั้นแบ่งสตริงเป็น 2 หรือ 3 ตัวอักขระบล็อกที่แต่ละบล็อกหมายถึงระดับไดเรกทอรี มีระดับไดเรกทอรีคงที่ (ตัวอย่าง 3):
    • 000000012345 -> 000/000/012
  3. จัดเก็บไฟล์ภายใต้ไดเรกทอรีที่สร้าง:
    • ดังนั้นพา ธ เต็มและชื่อไฟล์ไฟล์สำหรับไฟล์ที่มีรหัสลำดับ123คือ 000/000/012/00000000012345.jpg
    • สำหรับไฟล์ที่มีรหัสลำดับ12345678901234เส้นทางจะเป็น123/456/789/12345678901234.jpg

บางสิ่งที่ควรพิจารณาเกี่ยวกับโครงสร้างไดเรกทอรีและที่เก็บไฟล์:

  • อัลกอริทึมด้านบนจะให้ระบบที่ทุก ๆ leaf directory มีไฟล์ได้สูงสุด 1,000 ไฟล์ (ถ้าคุณมีจำนวนน้อยกว่า 1,000 000 000 000 ไฟล์)
  • อาจมีการ จำกัด จำนวนไฟล์และไดเร็กทอรีย่อยที่ไดเร็กทอรีสามารถมีได้ตัวอย่างเช่นระบบไฟล์ ext3 บน Linuxมีขีด จำกัด ของไดเร็กทอรีย่อย 31998 ต่อหนึ่งไดเร็กทอรี
  • เครื่องมือปกติ (WinZip, Windows Explorer, บรรทัดคำสั่ง, bash shell, ฯลฯ ) อาจทำงานได้ไม่ดีนักหากคุณมีไฟล์จำนวนมากต่อไดเรกทอรี (> 1,000)
  • โครงสร้างไดเรกทอรีเองจะใช้พื้นที่ดิสก์บางส่วนดังนั้นคุณจะไม่ต้องการไดเรกทอรีมากเกินไป
  • ด้วยโครงสร้างด้านบนคุณสามารถค้นหาเส้นทางที่ถูกต้องสำหรับไฟล์ภาพได้โดยเพียงแค่ดูที่ชื่อไฟล์หากคุณเกิดความสับสนในโครงสร้างไดเรกทอรีของคุณ
  • หากคุณต้องการเข้าถึงไฟล์จากหลาย ๆ เครื่องให้พิจารณาแชร์ไฟล์ผ่านระบบไฟล์เครือข่าย
  • โครงสร้างไดเรกทอรีด้านบนจะไม่ทำงานหากคุณลบไฟล์จำนวนมาก มันปล่อยให้ "หลุม" ในโครงสร้างไดเรกทอรี แต่เนื่องจากคุณไม่ได้ลบไฟล์ใด ๆ มันก็น่าจะพอใช้ได้

1
น่าสนใจมาก! แยกชื่อไฟล์ ... ฉันไม่คิดอย่างนั้น ฉันคิดว่านี่เป็นวิธีที่ยอดเยี่ยมในการทำ: -
s.mihai

37
การใช้แฮช (เช่น MD5) เป็นชื่อของไฟล์รวมถึงการแจกจ่ายไดเรกทอรีจะใช้งานได้ ความสมบูรณ์ของไฟล์ไม่เพียง แต่จะเป็นประโยชน์ต่อการตั้งชื่อรูปแบบ (ตรวจสอบได้ง่าย) แต่คุณจะมีการกระจายที่สมเหตุสมผลแม้ในลำดับชั้นของไดเรกทอรี ดังนั้นหากคุณมีไฟล์ชื่อ "f6a5b1236dbba1647257cc4646308326.jpg" คุณจะเก็บไว้ใน "/ f / 6" (หรือลึกตามที่คุณต้องการ) 2 ระดับความลึกให้ 256 ไดเรกทอรีหรือต่ำกว่า 4000 ไฟล์ต่อไดเรกทอรีสำหรับไฟล์ 1m เริ่มต้น นอกจากนี้ยังเป็นเรื่องง่ายมากที่จะกระจายการแจกจ่ายให้เป็นแบบอัตโนมัติ

+1 ฉันเพิ่งสังเกตเห็นคำตอบนี้คล้ายกับที่ฉันเพิ่งโพสต์
3dinfluence

1
ฉันเห็นด้วยอย่างแน่นอนเกี่ยวกับการใช้ระบบไฟล์และการสร้างตัวบ่งชี้ artficial เพื่อ "แบ่ง" ขึ้นเป็นชื่อโฟลเดอร์ แต่คุณควรลองรับการกระจายตัวระบุแบบสุ่มเช่นอย่าใช้หมายเลขลำดับ ซึ่งจะช่วยให้คุณมีแผนผังโฟลเดอร์ที่สมดุลมากขึ้น นอกจากนี้ด้วยการกระจายแบบสุ่มคุณสามารถแบ่งแผนภูมิต้นไม้ข้ามระบบไฟล์หลาย ๆ ระบบได้ง่ายขึ้น ฉันยังใช้ SAN ที่ใช้ ZFS ด้วยการเปิดใช้งานการขจัดความซ้ำซ้อนและไดรฟ์ข้อมูลแบบกระจายสำหรับระบบไฟล์แต่ละระบบ คุณยังสามารถใช้ NTFS ได้โดยใช้ iSCSI เพื่อเข้าถึง SAN
Michael Dillon

หากคุณไปจากขวาไปซ้ายในขั้นตอนที่ 2 ไฟล์จะถูกกระจายอย่างเท่าเทียมกัน นอกจากนี้คุณไม่ต้องกังวลว่าคุณจะไม่ได้เติมเต็มจำนวนศูนย์เท่าที่คุณสามารถทำได้ไม่ จำกัด จำนวนไฟล์
ropo

31

ฉันจะใส่ค่า 2 เซ็นต์ไว้ในคำแนะนำเชิงลบ: อย่าไปกับฐานข้อมูล

ฉันทำงานกับฐานข้อมูลที่เก็บรูปภาพมานานหลายปีแล้ว: ไฟล์ขนาดใหญ่ (1 meg-> 1 กิ๊ก) ซึ่งมักจะมีการเปลี่ยนแปลงไฟล์หลายเวอร์ชันเข้าถึงได้บ่อยครั้งพอสมควร ปัญหาฐานข้อมูลที่คุณพบกับไฟล์ขนาดใหญ่ที่ถูกจัดเก็บนั้นน่าเบื่ออย่างยิ่งในการจัดการปัญหาการเขียนและการทำธุรกรรมนั้นยากที่จะแก้ไขและคุณพบปัญหาในการล็อค ฉันมีการปฏิบัติมากขึ้นในการเขียนสคริปต์ DBCC และการเรียกคืนจากการสำรองข้อมูลตารางกว่าคนปกติใด ๆ ควรที่เคยมี

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


ใช่. จดบันทึกแล้ว!
s.mihai

5
คุณได้ดูชนิดข้อมูล FILESTREAM ของ SQL 2008 แล้วหรือยัง มันข้ามระหว่างการจัดเก็บฐานข้อมูลและระบบไฟล์
NotMe

+1 เมื่อผสานกับไฟล์เซิร์ฟเวอร์แทนที่จะเป็นฐานข้อมูลในขณะที่คุณกำลังดำเนินการ IO ที่รวดเร็วและไม่บ่อยนัก

ถ้าคุณเพียงแค่จัดเก็บเอกสารหรือภาพจำนวนไม่กี่ร้อยต่อฐานข้อมูล - ข้อเสียใด ๆ ในการใช้ฐานข้อมูลสำหรับการจัดเก็บ?
ปี๊บปี๊บ

1
+1 ... ระบบไฟล์เป็น "ฐานข้อมูล" อยู่แล้ว (แน่นอนว่า ntfs) ดังนั้นทำไมมันซับซ้อนเกินไป
akira

12

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

สมมติว่าคุณมีแฮชของไฟล์ที่เป็นแบบนี้515d7eab9c29349e0cde90381ee8f810
คุณสามารถเก็บสิ่งนี้ไว้ในตำแหน่งต่อไปนี้และคุณสามารถใช้ระดับความลึกที่คุณต้องการให้มีจำนวนไฟล์ในแต่ละโฟลเดอร์ที่ต่ำ
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

ฉันเคยเห็นวิธีการนี้ใช้เวลาหลายครั้ง คุณยังต้องการฐานข้อมูลเพื่อแมปไฟล์เหล่านี้กับชื่อที่มนุษย์สามารถอ่านได้และข้อมูลเมตาอื่น ๆ ที่คุณต้องการเก็บไว้ แต่วิธีการนี้ปรับขนาดได้ค่อนข้าง b / c คุณสามารถเริ่มกระจายพื้นที่ที่อยู่แฮชระหว่างคอมพิวเตอร์หลายเครื่องและหรือพูลหน่วยเก็บข้อมูลเป็นต้น


2
Git ใช้วิธีการที่คล้ายกัน: git-scm.com/book/en/v2/Git-Internals-Git-Objects (เพื่อสำรองคำตอบนี้)
aexl

11

เป็นการดีที่คุณควรทำการทดสอบบางอย่างในเวลาเข้าถึงแบบสุ่มสำหรับโครงสร้างต่างๆเช่นการตั้งค่าฮาร์ดไดรฟ์แคชหน่วยความจำที่มีอยู่ ฯลฯ สามารถเปลี่ยนผลลัพธ์เหล่านี้ได้

สมมติว่าคุณสามารถควบคุมชื่อไฟล์ได้ฉันจะแบ่งพาร์ติชั่นที่ระดับ 1,000 ต่อไดเรกทอรี ยิ่งคุณเพิ่มระดับไดเรกทอรีมากเท่าใด inodes ที่คุณเผาไหม้ก็จะยิ่งเพิ่มมากขึ้นเท่านั้น

เช่น,

ราก / / [0-99] / [0-99] / ชื่อไฟล์

หมายเหตุhttp://technet.microsoft.com/en-us/library/cc781134(WS.10).aspxมีรายละเอียดเพิ่มเติมเกี่ยวกับการตั้งค่า NTFS โดยเฉพาะอย่างยิ่ง "ถ้าคุณใช้ไฟล์จำนวนมากในโฟลเดอร์ NTFS (300,000 หรือมากกว่า) ให้ปิดใช้งานการสร้างชื่อไฟล์แบบสั้นเพื่อประสิทธิภาพที่ดีขึ้นและโดยเฉพาะอย่างยิ่งถ้าอักขระหกตัวแรกของชื่อไฟล์แบบยาวมีความคล้ายคลึงกัน"

คุณควรปิดการใช้งานคุณสมบัติของระบบแฟ้มที่คุณไม่ต้องการ (เช่นเวลาเข้าถึงล่าสุด) http://www.pctools.com/guides/registry/detail/50/


3
+1 สำหรับการปิดใช้งานการสร้างชื่อไฟล์ 8.3 และเวลาเข้าถึงล่าสุด สิ่งเหล่านี้เป็นสิ่งแรกที่นึกถึงเมื่อฉันอ่าน "จำนวนมากของ [ไฟล์]" และ "NTFS" (Windows)
ปล้น

ลิงก์ลง ........................
Pacerier

7

ไม่ว่าคุณจะทำอะไรอย่าเก็บไว้ในไดเรกทอรีเดียว

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

ดังนั้น:

โฟลเดอร์img\a\b\c\d\e\f\g\จะมีรูปภาพที่ขึ้นต้นด้วย 'abcdefg' เป็นต้น

คุณสามารถแนะนำความลึกที่เหมาะสมของคุณเองที่จำเป็น

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


\ a \ b \ c \ d \ e \ f \ ฉันกำลังทำอยู่ตอนนี้ฉันคิดว่ามีวิธีที่ฉลาดในการทำเช่นนี้
s.mihai

1
นั่นเป็นวิธีการแก้ปัญหาที่ได้รับการยอมรับโดยทั่วไปเกี่ยวกับวิธีเก็บรักษาร่างกาย การสร้าง URL รูปภาพที่ชัดเจนนั้นเป็นสิ่งที่สามารถทำได้อย่างง่ายดายแบบไดนามิกตามชื่อไฟล์ภาพ คุณสามารถแนะนำโดเมนย่อย img-a, img-b บนเซิร์ฟเวอร์อิมเมจถ้าคุณต้องการเพื่อเพิ่มความเร็วในการโหลด

2
และ +1 สำหรับ "อย่าเก็บทั้งหมดไว้ในไดเรกทอรีเดียว" ฉันสนับสนุนระบบเดิมที่มีไฟล์มากกว่า 47,000 ไฟล์บนเซิร์ฟเวอร์ในโฟลเดอร์เดียวและใช้เวลาประมาณหนึ่งนาทีสำหรับ Explorer ในการเปิดโฟลเดอร์
Mark Ransom

5
การทำ \ b \ c \ d \ e \ f \ g ทำให้โครงสร้างไดเรกทอรีลึกมากและทุกไดเรกทอรีมีไฟล์เพียงไม่กี่ไฟล์ ควรใช้มากกว่านั้นหนึ่งตัวอักษรต่อระดับไดเรกทอรีเช่น ab \ cd \ ef \ หรือ abc \ def \ ไดเรกทอรียังใช้พื้นที่จากดิสก์ดังนั้นคุณจึงไม่ต้องการมากเกินไป
Juha Syrjälä

2
ฉันต้องสนับสนุนแอปพลิเคชันที่มี 4 ล้านไฟล์ทั้งหมดในไดเรกทอรีเดียว มันใช้งานได้ดีอย่างน่าประหลาดใจ แต่คุณไม่สามารถเรียกใช้ explorer เพื่อเปิดโฟลเดอร์ได้ +1 สำหรับ NTFS สามารถจัดการได้โดยไม่ตาย
SqlACID

5

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

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


ภาพไม่ได้มีไว้สำหรับการเข้าถึงบ่อยครั้ง ดังนั้นจึงไม่มีปัญหากับสิ่งนี้ จำนวนของพวกเขาจะเติบโตอย่างรวดเร็ว ฉันคิดว่าจะมี 1mil ทำเครื่องหมายใน 1 เดือน
s.mihai

ฉันสนใจในมุมมองโปรแกรมเมอร์เพื่อที่ฉันจะไม่คิดมากเรื่องนี้มากเกินไป
s.mihai

ดังนั้นหากคุณไม่ต้องการการเข้าถึงที่รวดเร็ว Haystack อาจไม่เหมาะกับคุณ การใช้ไดเรคทอรี่สำหรับพาร์ติชั่นเป็นทางออกที่ง่ายที่สุดในมุมมองของฉัน
Lukasz

5

เรามีระบบจัดเก็บภาพที่มี 4 ล้านภาพ เราใช้ฐานข้อมูลสำหรับข้อมูลเมตาเท่านั้นและรูปภาพทั้งหมดจะถูกเก็บไว้ในระบบไฟล์โดยใช้ระบบการตั้งชื่อที่ถูกบุกรุกโดยที่ชื่อโฟลเดอร์จะถูกสร้างขึ้นจากตัวเลขหลักสุดท้ายของไฟล์สุดท้าย -1 และอื่น ๆ เช่น: 000001234.jpg ถูกเก็บไว้ในโครงสร้างไดเรกทอรีเช่น 4 \ 3 \ 2 \ 1 \ 000001234.jpg

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


4

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


: -? จุดด่วนที่ดี เพียงแค่ตอนนี้ฉันไม่มีอัลกอริทึมสำหรับสร้างเส้นทาง
s.mihai


4

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

นอกจากนี้คุณบอกว่าคุณจะได้รับ 1 ล้านภาพในเวลาหนึ่งเดือน แล้วหลังจากนั้นล่ะ รูปภาพเหล่านี้จะเติมระบบไฟล์ได้เร็วแค่ไหน? พวกเขาจะเริ่มต้นที่จุดหนึ่งและระดับที่ประมาณ 1 ล้านภาพ TOTAL หรือจะยังคงเติบโตและเติบโตทุกเดือน?

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

imgs\yyyy\mm\filename.ext

where: yyyy = 4 digit year
         mm = 2 digit month

example:  D:\imgs\2009\12\aaa0001.jpg
          D:\imgs\2009\12\aaa0002.jpg
          D:\imgs\2009\12\aaa0003.jpg
          D:\imgs\2009\12\aaa0004.jpg
                   |
          D:\imgs\2009\12\zzz9982.jpg
          D:\imgs\2010\01\aaa0001.jpg (this is why I ask about uniqueness)
          D:\imgs\2010\01\aab0001.jpg

เดือนปีหรือแม้แต่วันก็ดีสำหรับรูปภาพประเภทความปลอดภัย ไม่แน่ใจว่านี่คือสิ่งที่คุณกำลังทำ แต่ฉันทำอย่างนั้นกับกล้องรักษาความปลอดภัยในบ้านที่ถ่ายภาพทุก ๆ 10 วินาที ... วิธีนี้แอปพลิเคชันของคุณสามารถเจาะลงไปตามเวลาที่กำหนดหรือแม้แต่ช่วงที่คุณอาจคิดว่า . หรือแทนที่จะเป็นปีเดือน - มี "ความหมาย" อื่น ๆ ที่สามารถได้มาจากไฟล์ภาพเองหรือไม่? อธิบายอื่น ๆ นอกเหนือจากตัวอย่างวันที่ฉันให้?

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

คุณ / คนอื่นอาจจะพูดถึงความคิดเหล่านี้ในขณะที่ฉันตอบกลับ .. หวังว่านี่จะช่วยได้ ..


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

3

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

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

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

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

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


2

บางทีรูปแบบการตั้งชื่อตามวันที่สร้าง - รวมทั้งข้อมูลทั้งหมดในชื่อไฟล์หรือ (ดีกว่าสำหรับการเรียกดูในภายหลัง) แยกมันในไดเรกทอรี ฉันสามารถคิดถึงสิ่งต่อไปนี้ขึ้นอยู่กับว่าคุณสร้างภาพบ่อยแค่ไหน:

  • สร้างภาพหลายภาพในแต่ละวัน: Year/Month/Day/Hour_Minute_Second.png
  • สองสามเดือน: Year/Month/Day_Hour_Minute_Second.png

ฯลฯ คุณจะได้รับคะแนนของฉัน ... =)


มันไม่ได้ถูกสร้างอย่างต่อเนื่องเมื่อเวลาผ่านไปดังนั้นบางโฟลเดอร์จะกลายเป็นอ้วนและบางโฟลเดอร์ก็ยังคงอยู่ ... ผอมบาง :)
s.mihai

เห็นได้ชัดว่าคุณไม่จำเป็นต้องสร้างแต่ละโฟลเดอร์เพียงเพราะคุณทำตามรูปแบบนี้ คุณสามารถYear/Month/Day/Hour/Minuteกำหนดได้ว่าต้องการโฟลเดอร์กี่ระดับโดยขึ้นอยู่กับความถี่ของภาพที่สร้างขึ้นเมื่ออัตราสูงสุดและจากนั้นอย่าสร้างโฟลเดอร์ที่ว่างเปล่า
Tomas Aschan

2

ฉันอยากจะสร้างโครงสร้างโฟลเดอร์ตามวันที่เช่น \ year \ month \ day และใช้การประทับเวลาสำหรับชื่อไฟล์ หากจำเป็นการประทับเวลาสามารถมีองค์ประกอบตัวนับเพิ่มเติมหากจะสร้างภาพอย่างรวดเร็วจนอาจมีมากกว่าหนึ่งรายการภายในเสี้ยววินาที ด้วยการใช้ลำดับที่สำคัญที่สุดถึงสำคัญน้อยที่สุดสำหรับการจัดเรียงการตั้งชื่อการค้นหาและการบำรุงรักษาจึงเป็นเรื่องง่าย เช่น hhmmssmm [seq] .jpg


2

คุณกำลังพิจารณาการกู้คืนความเสียหายหรือไม่?

วิธีแก้ปัญหาที่เสนอบางส่วนจะจบลงด้วยการจัดการชื่อไฟล์ (เช่นหากไฟล์จริงถูกย้ายคุณจะสูญเสียการติดตามว่าเป็นไฟล์ใด) ฉันขอแนะนำให้คงชื่อฟิสิคัลไฟล์เฉพาะไว้เพื่อที่ว่าหากรายการหลักของตำแหน่งไฟล์เสียหายคุณสามารถสร้างมันขึ้นมาใหม่โดยใช้เชลล์ขนาดเล็กเอ้อ, PowerShell, script;)

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

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

คุณอาจพิจารณาใช้ GUID เป็นชื่อไฟล์จริงแทนที่จะเป็นตัวเลขที่เพิ่มขึ้นในกรณีที่ตัวนับจำนวนที่เพิ่มขึ้นของคุณ

หากเหมาะสมให้พิจารณาใช้ CDN เช่น Amazon S3


2

ในขณะที่ฉันไม่ได้แสดงภาพในระดับนั้นฉันเคยเขียนแอพแกลเลอรี่ขนาดเล็กสำหรับแสดงรูปภาพขนาด ~ 25k ด้วยเครื่อง 400MHz RAM 512 MB หรือมากกว่านั้น ประสบการณ์บางอย่าง;

  • หลีกเลี่ยงฐานข้อมูลเชิงสัมพันธ์ที่ค่าใช้จ่ายทั้งหมด; ในขณะที่ฐานข้อมูลไม่ต้องสงสัยเลยว่าฉลาดในการจัดการข้อมูล แต่ก็ไม่ได้ออกแบบมาสำหรับการใช้งานดังกล่าว (เรามีฐานข้อมูลคีย์ - ค่าเฉพาะแบบลำดับชั้นสำหรับที่เรียกว่าระบบไฟล์ ) ในขณะที่ฉันไม่มีอะไรมากไปกว่าลางสังหรณ์ฉันจะลองดูว่าแคช DB จะออกไปนอกหน้าต่างถ้าคุณขว้างก้อนใหญ่ ๆ ใส่เข้าไป ในขณะที่ฮาร์ดแวร์ที่มีอยู่ของฉันมีขนาดเล็ก แต่การไม่แตะฐานข้อมูลเลยแม้แต่น้อยในการค้นหารูปภาพทำให้คำสั่งความเร็วมีขนาดที่ดีขึ้น

  • วิจัยว่าระบบไฟล์ทำงานอย่างไร; ใน ext3 (หรือเป็น ext2 ในเวลา - จำไม่ได้) ขีด จำกัด ของความสามารถในการค้นหาไดเรกทอรีย่อยและไฟล์ได้อย่างมีประสิทธิภาพอยู่ที่ประมาณ 256 เครื่องหมาย; ดังนั้นมีไฟล์และโฟลเดอร์จำนวนมากในโฟลเดอร์ที่กำหนด อีกครั้งเร่งความเร็วที่เห็นได้ชัด ในขณะที่ฉันไม่รู้จัก NTFS แต่อย่าง XFS (ซึ่งใช้ B-trees เท่าที่ฉันจำได้) นั้นเร็วมากเพราะพวกมันสามารถทำการค้นหาได้อย่างรวดเร็ว

  • กระจายข้อมูลอย่างสม่ำเสมอ เมื่อฉันทดลองกับข้างต้นฉันพยายามกระจายข้อมูลอย่างสม่ำเสมอในทุกไดเรกทอรี (ฉันทำ MD5 ของ URL และใช้มันสำหรับไดเรกทอรี; /1a/2b/1a2b...f.jpg) วิธีนี้จะใช้เวลานานกว่าที่จะเข้าถึงขีด จำกัด ประสิทธิภาพการทำงานที่มีอยู่ (และแคชระบบไฟล์จะเป็นโมฆะในชุดข้อมูลขนาดใหญ่ดังกล่าว) (ตรงกันข้ามคุณอาจต้องการดูว่าขีด จำกัด นั้นอยู่ที่ไหนก่อนจากนั้นคุณต้องการทิ้งทุกอย่างในไดเรกทอรีแรกที่มี


2

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

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: การสร้างโครงสร้าง หวังว่านี่จะช่วยได้!


เราเก็บ 1.8 พันล้านรายการโดยใช้สิ่งที่คล้ายกัน มันใช้งานได้ดี ใช้แฮชที่รวดเร็วและมีอัตราการชนต่ำและคุณตั้งค่าไว้
CVVS


1

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

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


1

ฉันเพิ่งทดสอบ zfs เพราะฉันรัก zfs และฉันมีพาร์ทิชัน 500gig ที่ฉันมีการบีบอัด ฉันเขียนสคริปต์ที่สร้างไฟล์ 50-100k และวางไว้ในไดเรกทอรีที่ซ้อนกัน 1/2/3/4/5/6/7/8 (ลึก 5-8 ระดับ) และปล่อยให้มันทำงานได้ฉันคิดว่า 1 สัปดาห์ (มันไม่ใช่สคริปต์ที่ยอดเยี่ยม) มันเต็มดิสก์และจบลงด้วยการมีไฟล์ประมาณ 25 ล้านไฟล์ การเข้าถึงไฟล์ใดไฟล์หนึ่งด้วยพา ธ ที่รู้จักนั้นเป็นแบบทันที รายการไดเรกทอรีใด ๆ ที่มีเส้นทางที่รู้จักกันเป็นทันที

การนับจำนวนรายการไฟล์ (ผ่านการค้นหา) ใช้เวลา 68 ชั่วโมง

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


1

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

คุณอาจสนใจข้อมูลจำเพาะต่อไปนี้กล้องดิจิทัลส่วนใหญ่ติดตามเพื่อจัดการพื้นที่เก็บไฟล์: https://en.wikipedia.org/wiki/Camera_Image_File_Format

โดยพื้นฐานแล้วโฟลเดอร์จะถูกสร้างขึ้นเช่น000OLYMPUSและภาพถ่ายจะถูกเพิ่มลงในโฟลเดอร์นั้น (ตัวอย่างDSC0000.RAW) เมื่อนับถึงชื่อไฟล์DSC9999.RAWโฟลเดอร์ใหม่จะถูกสร้างขึ้น ( 001OLYMPUS) และภาพที่มีการเพิ่มอีกครั้งรีเซ็ตเคาน์เตอร์อาจจะมีคำนำหน้าแตกต่างกัน (เช่น: P_0000.RAW)

หรือคุณสามารถสร้างโฟลเดอร์ตามส่วนต่าง ๆ ของชื่อไฟล์ (ที่กล่าวถึงไปแล้วหลายครั้ง) ตัวอย่างเช่นถ้าคุณเป็นชื่อภาพเก็บไว้ที่IMG_A83743.JPG IMG_\A8\3\IMG_A83743.JPGมันซับซ้อนกว่าที่จะใช้ แต่จะทำให้ไฟล์ของคุณค้นหาง่ายขึ้น

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


0

คุณอาจต้องการดู ZFS (ระบบไฟล์ตัวจัดการโวลุ่มจาก Sun) ขอแสดงความนับถือ


0

วิธีที่สะอาดในการสร้างเส้นทางจากจำนวนมากคือการแปลงให้เป็นฐานสิบหกอย่างง่ายดายแล้วแยกมัน!

ตัวอย่างเช่น1099496034834> 0xFFFF1212>FF/FF/12/12

public string GeneratePath(long val)
{  
    string hex = val.ToString("X");
    hex=hex.PadLeft(10, '0');
    string path="";
    for(int i=0; i<hex.Length; i+=2 )
    {
        path += hex.Substring(i,2);
        if(i+2<hex.Length)
            path+="/";
    }
    return path;
}

จัดเก็บและโหลด:

public long Store(Stream doc)
{
   var newId = getNewId();
   var fullpath = GeneratePath(newId)
   // store into fullpath 
   return newId;
}

public Stream Load(long id)
{
   var fullpath = GeneratePath(newId)
   var stream = ... 
   return stream;
}

รหัสที่มาแบบเต็ม: https://github.com/acrobit/AcroFS


-1

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

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


-2

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

หากคุณคาดว่าจะขยายขนาดทำไมไม่ขยายขนาดตอนนี้ คุณจะประหยัดเวลาทั้งตอนนี้และภายหลัง IMO ใช้เลเยอร์ฐานข้อมูลหนึ่งครั้งซึ่งค่อนข้างง่ายในการเริ่มต้น หรือใช้งานบางอย่างกับโฟลเดอร์และชื่อไฟล์และ blah blah blah แล้วเปลี่ยนเป็นอย่างอื่นเมื่อคุณเริ่มเล่น MAX_PATH


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

1
และมีสาธารณูปโภคมากมายสำหรับจัดการกับไฟล์และระบบไฟล์มีจำนวนไม่น้อยที่จะจัดการกับไฟล์ภายในฐานข้อมูล
Mark Ransom

2
โอ้พระเจ้าไม่ได้โปรดอย่าใช้ฐานข้อมูลเป็นที่เก็บข้อมูล BLOB ขนาดใหญ่
Neil N

จี๊ด ไม่ทราบว่าฐานข้อมูล (ยัง) มีปัญหามากมายกับ BLOB

วิธีแก้ปัญหาที่ไม่ดีเช่นนี้ที่มีความคิดเห็นจำนวนมากยังคงมี +1 อยู่ได้อย่างไร ไม่มีความผิดที่จะ OP (ฉันเห็นมันมาจาก SO) แต่ปุ่ม downvote อยู่ที่นี่ด้วยเหตุผล!
Mark Henderson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.