Kho dữ liệu khóa / giá trị tiêu chuẩn cho unix


16

Tôi biết về các giá trị khóa / thư viện cho unix ( BerkeleyDB , GDBM , redis ...). Nhưng trước khi tôi bắt đầu viết mã, tôi tự hỏi liệu có một công cụ tiêu chuẩn nào cho unix cho phép tôi thực hiện các hoạt động sau:

$ 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...

Cảm ơn

Câu trả lời:


10

Tôi không nghĩ có một công cụ tiêu chuẩn cho việc đó. Ngoại trừ grep/ awk/ sedv.v. Nhưng sử dụng điều này, bạn sẽ cần quan tâm đến nhiều vấn đề khác như khóa, định dạng, ký tự đặc biệt, v.v.

Tôi đề nghị sử dụng sqlite. Xác định một bảng đơn giản và sau đó tạo tool_get()và các tool_put()hàm shell. sqlitelà hàng xách tay, nhanh chóng.

Bạn sẽ có thêm sự linh hoạt miễn phí. Bạn có thể xác định các ràng buộc, chỉ mục để điều chỉnh tập lệnh của mình hoặc sử dụng DB đó trong các ngôn ngữ khác một ngày nào đó.


Cảm ơn bạn . Tôi đã nhanh chóng viết một công cụ với API sqlite. Nó hoạt động tốt.
Pierre

9

Nếu cơ sở dữ liệu của bạn đủ nhỏ, thì bạn có thể sử dụng hệ thống tập tin. Ưu điểm của phương pháp này là công nghệ rất thấp và sẽ hoạt động ở mọi nơi với rất ít mã. Nếu các khóa bao gồm các ký tự có thể in và không chứa /, thì bạn có thể sử dụng chúng làm tên tệp:

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"; }

Để chứa các khóa tùy ý, hãy sử dụng tổng kiểm tra của khóa làm tên tệp và tùy ý lưu trữ một bản sao của khóa (trừ khi bạn không thể liệt kê các khóa hoặc cho biết khóa đó là gì cho một mục cụ thể).

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"
}

Lưu ý rằng việc triển khai đồ chơi ở trên không phải là toàn bộ câu chuyện: chúng không có bất kỳ tài sản giao dịch hữu ích nào như nguyên tử. Tuy nhiên, các hoạt động hệ thống tập tin cơ bản như tạo và đổi tên tệp là nguyên tử và có thể xây dựng các phiên bản nguyên tử của các chức năng trên.

Các triển khai hệ thống trực tiếp đến tệp này phù hợp với các hệ thống tệp điển hình chỉ dành cho cơ sở dữ liệu nhỏ, tối đa vài nghìn tệp. Ngoài thời điểm này, hầu hết các hệ thống tập tin có một thời gian khó đối phó với các thư mục lớn. Bạn có thể điều chỉnh lược đồ cho cơ sở dữ liệu lớn hơn bằng cách sử dụng bố cục lớp. Ví dụ, thay vì lưu trữ tất cả các tệp trong một thư mục, hãy lưu trữ chúng trong các thư mục con riêng biệt dựa trên một vài ký tự đầu tiên của tên của chúng. Đây là những gì git làm, ví dụ: các đối tượng của nó, được lập chỉ mục bằng băm SHA-1, được lưu trữ trong các tệp được gọi .git/objects/01/2345679abcdef0123456789abcdef01234567. Các ví dụ khác về các chương trình sử dụng phân lớp ngữ nghĩa là các proxy bộ đệm web Wwwofflepolipo ; cả hai lưu trữ bản sao được lưu trong bộ nhớ cache của một trang được tìm thấy tại một URL trong một tệp có tênwww.example.com/HASH trong đó HASH là một số mã hóa của một số hàm băm của URL.¹

Một nguồn không hiệu quả khác là hầu hết các hệ thống tệp đều lãng phí rất nhiều dung lượng khi lưu trữ các tệp nhỏ - có sự lãng phí lên tới 2kB mỗi tệp trên các hệ thống tệp thông thường, độc lập với kích thước của tệp.

Nếu bạn chọn sử dụng cơ sở dữ liệu thực, bạn không cần phải từ bỏ sự thuận tiện của việc truy cập hệ thống tệp trong suốt. Có một số hệ thống tập tin FUSE để truy cập cơ sở dữ liệu bao gồm Berkeley DB (với dbfs của Jeff Garzik ), Oracle (với Oracle DBFS ), MySQL (với mysqlfs ), v.v.

¹ Đối với một URL như http://unix.stackexchange.com/questions/21943/standard-key-value-datastore-for-unix, Polipo sử dụng các tập tin unix.stackexchange.com/M0pPbpRufiErf4DLFcWlhw==, với tiêu đề bổ sung bên trong tập tin chỉ URL thực tế trong văn bản rõ ràng; tên tệp là mã hóa base64 của hàm băm MD5 (ở dạng nhị phân) của URL. Wwwoffle sử dụng tệp http/unix.stackexchange.com/DM0pPbpRufiErf4DLFcWlhw; tên của tệp là mã hóa tự phát của hàm băm MD5 và tệp đồng hành http/unix.stackexchange.com/UM0pPbpRufiErf4DLFcWlhwchứa URL.


7

dbmutilcó thể giúp bạn có được những gì bạn muốn. Nó có các tiện ích shell cho các hoạt động bạn mô tả trong câu hỏi. Tôi sẽ không nói nó chính xác tiêu chuẩn, nhưng nó có các tiện nghi bạn muốn.


5

Vì bạn đã đặt tên cho nó, máy khách redis tiêu chuẩn có giao diện dòng lệnh thông qua redis-cli. Một số ví dụ từ redis-cli -h:

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

(Và nếu bạn muốn truy cập db thông qua hệ thống tệp, bạn có thể sử dụng các socket với -s. Một công cụ đọc chỉ mục db trực tiếp trên mỗi lệnh gọi sẽ rất kém hiệu quả.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.