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 Wwwoffle và polipo ; 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/UM0pPbpRufiErf4DLFcWlhw
chứa URL.