ที่เก็บคีย์ / ค่ามาตรฐานสำหรับยูนิกซ์


16

ฉันรู้เกี่ยวกับไลบรารีคีย์ / ค่าสำหรับ unix ( berkeleydb , gdbm , redis ... ) แต่ก่อนที่ฉันจะเริ่มเขียนโค้ดฉันสงสัยว่ามีเครื่องมือมาตรฐานสำหรับ unix ที่จะให้ฉันทำงานต่อไปนี้หรือไม่:

$ tool -f datastore.db put "KEY" "VALUE"
$ tool -f datastore.db put -f file_key_values.txt
$ tool -f datastore.db get "KEY"
$ tool -f datastore.db get -f file_keys.txt
$ tool -f datastore.db remove "KEY"
$ etc...

ขอบคุณ

คำตอบ:


10

ฉันไม่คิดว่าจะมีเครื่องมือมาตรฐานสำหรับสิ่งนั้น ยกเว้นgrep/ awk/ sedฯลฯ แต่การใช้สิ่งนี้คุณจะต้องใส่ใจกับปัญหาอื่น ๆ อีกมากมายเช่นการล็อครูปแบบตัวอักษรพิเศษ ฯลฯ

sqliteฉันขอแนะนำให้ใช้ กำหนดตารางอย่างง่ายจากนั้นสร้างtool_get()และtool_put()เชลล์ฟังก์ชัน sqliteเป็นแบบพกพารวดเร็ว

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


ขอขอบคุณ . ฉันเขียนเครื่องมือด้วย sqlite API อย่างรวดเร็ว มันใช้งานได้ดี
ปิแอร์

9

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

put () { key=$1; value=$2; printf %s "$value" >"datastore.db/$key"; }
get () { key=$1; cat "datastore.db/$key"; }
remove () { key=$1; rm "datastore.db/$key"; }

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

put () {
  key=$1; value=$2; set $(printf %s "$key" | sha1sum); sum=$1
  printf %s "$key" >"datastore.db/$sum.key"
  printf %s "$value" >"datastore.db/$sum.value"
}
get () {
  key=$1; set $(printf %s "$key" | sha1sum); sum=$1
  cat "datastore.db/$1.value"
}
remove () {
  key=$1; set $(printf %s "$key" | sha1sum); sum=$1
  rm "datastore.db/$1.key" "datastore.db/$1.value"
}

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

การใช้งานระบบไฟล์โดยตรงไปยังไฟล์เหล่านี้เหมาะสมกับระบบไฟล์ทั่วไปสำหรับฐานข้อมูลขนาดเล็กมากถึงสองพันไฟล์ นอกเหนือจากจุดนี้ระบบไฟล์ส่วนใหญ่มีปัญหาในการจัดการกับไดเรกทอรีขนาดใหญ่ คุณสามารถปรับโครงร่างเป็นฐานข้อมูลขนาดใหญ่โดยใช้เลย์เอาต์เลเยอร์ ตัวอย่างเช่นแทนที่จะเก็บไฟล์ทั้งหมดไว้ในไดเรกทอรีเดียวให้เก็บไว้ในไดเรกทอรีย่อยแยกกันโดยพิจารณาจากอักขระสองสามตัวแรกของชื่อ นี่คือสิ่งที่คอมไพล์ไม่ตัวอย่างเช่น: วัตถุของดัชนีโดย SHA-1 hashes .git/objects/01/2345679abcdef0123456789abcdef01234567จะถูกเก็บไว้ในไฟล์ที่เรียกว่า ตัวอย่างอื่น ๆ ของโปรแกรมที่ใช้ layering ความหมายคือพร็อกซี่แคชเว็บWwwoffleและpolipo ; ทั้งเก็บสำเนาแคชของหน้าเว็บที่พบใน URL ในไฟล์ที่เรียกว่าwww.example.com/HASH โดยที่ HASH เป็นการเข้ารหัสแฮชบางส่วนของ URL

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

หากคุณเลือกที่จะไปกับฐานข้อมูลจริงคุณไม่จำเป็นต้องสละความสะดวกสบายในการเข้าถึงระบบไฟล์แบบโปร่งใส มีระบบไฟล์FUSEหลายระบบในการเข้าถึงฐานข้อมูลรวมถึง Berkeley DB (กับdbfs ของ Jeff Garzik ), Oracle (กับOracle DBFS ), MySQL (พร้อมmysqlfs ) เป็นต้น

¹ สำหรับ URL อย่างhttp://unix.stackexchange.com/questions/21943/standard-key-value-datastore-for-unixPolipo ใช้ไฟล์unix.stackexchange.com/M0pPbpRufiErf4DLFcWlhw==โดยมีส่วนหัวเพิ่มเติมภายในไฟล์เพื่อระบุ URL จริงในข้อความที่ชัดเจน ชื่อไฟล์คือการเข้ารหัส base64 ของแฮช MD5 (ในไบนารี) ของ URL Wwwoffle ใช้ไฟล์http/unix.stackexchange.com/DM0pPbpRufiErf4DLFcWlhw; ชื่อของไฟล์คือการเข้ารหัสแฮช MD5 และโฮมไฟล์http/unix.stackexchange.com/UM0pPbpRufiErf4DLFcWlhwประกอบด้วย URL


7

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


5

เนื่องจากคุณตั้งชื่อมันไคลเอ็นต์ redis มาตรฐานจะมีอินเตอร์เฟสบรรทัดคำสั่งผ่าน redis-cliมาตรฐานมีอินเตอร์เฟซบรรทัดคำสั่งผ่าน ตัวอย่างบางส่วนจากredis-cli -h:

 cat /etc/passwd | redis-cli -x set mypasswd
 redis-cli get mypasswd
 redis-cli -r 100 lpush mylist x

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

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