Je connais le bibliothèques clé / valeur pour unix ( berkeleydb , gdbm , redis ...). Mais avant de commencer à coder, je me demande s'il existe un outil standard pour unix qui me permettrait d'effectuer les opérations suivantes:
$ 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...
Merci
Si votre base de données est suffisamment petite, vous pouvez utiliser le système de fichiers. L'avantage de cette approche est qu'elle est très low-tech et fonctionnera partout avec très peu de code. Si les clés sont composées de caractères imprimables et ne contiennent pas
/
, vous pouvez les utiliser comme noms de fichiers:Pour prendre en charge des clés arbitraires, utilisez une somme de contrôle de la clé comme nom de fichier et stockez éventuellement une copie de la clé (sauf si vous n'êtes pas satisfait de ne pas pouvoir répertorier les clés ou dire quelle est la clé pour une entrée donnée).
Notez que les implémentations de jouets ci-dessus ne sont pas toute l'histoire: elles n'ont aucune utilité propriété transactionnelle comme l'atomicité. Les opérations de base du système de fichiers telles que la création et le renommage de fichiers sont atomiques cependant, et il est possible de construire des versions atomiques des fonctions ci-dessus.
Ces implémentations du système de fichiers direct ne conviennent aux systèmes de fichiers typiques que pour les petites bases de données, jusqu'à quelques milliers de fichiers. Au-delà de ce point, la plupart des systèmes de fichiers ont du mal à gérer de gros répertoires. Vous pouvez adapter le schéma à des bases de données plus importantes en utilisant une disposition en couches. Par exemple, au lieu de stocker tous les fichiers dans un seul répertoire, stockez-les dans des sous-répertoires distincts en fonction des premiers caractères de leurs noms. C'est ce que fait git , par exemple: ses objets, indexés par les hachages SHA-1, sont stockés dans des fichiers appelés
.git/objects/01/2345679abcdef0123456789abcdef01234567
. D'autres exemples de programmes qui utilisent une couche sémantique sont les proxies de mise en cache Web Wwwoffle et polipo ; les deux stockent la copie en cache d'une page trouvée à une URL dans un fichier appeléwww.example.com/HASH
où HASH est un encodage d'un hachage de l'URL.¹Une autre source d'inefficacité est que la plupart des systèmes de fichiers gaspillent beaucoup d'espace lors du stockage de petits fichiers - il y a un gaspillage allant jusqu'à 2 Ko par fichier sur les systèmes de fichiers typiques, indépendamment de la taille du fichier.
Si vous choisissez d'utiliser une vraie base de données, vous n'avez pas besoin de renoncer à la commodité d'un accès transparent au système de fichiers. Il existe plusieurs systèmes de fichiers FUSE pour accéder aux bases de données, notamment Berkeley DB (avec les dbfs de Jeff Garzik ), Oracle (avec Oracle DBFS ), MySQL (avec mysqlfs ), etc.
¹ Pour une URL comme
http://unix.stackexchange.com/questions/21943/standard-key-value-datastore-for-unix
, Polipo utilise le fichierunix.stackexchange.com/M0pPbpRufiErf4DLFcWlhw==
, avec un en-tête ajouté à l'intérieur du fichier indiquant l'URL réelle en texte clair; le nom du fichier est l'encodage base64 du hachage MD5 (en binaire) de l'URL. Wwwoffle utilise le fichierhttp/unix.stackexchange.com/DM0pPbpRufiErf4DLFcWlhw
; le nom du fichier est un encodage local du hachage MD5, et un fichier compagnonhttp/unix.stackexchange.com/UM0pPbpRufiErf4DLFcWlhw
contient l'URL.la source
dbmutil
pourrait vous obtenir ce que vous voulez. Il a des utilitaires shell pour les opérations que vous décrivez dans la question. Je ne dirais pas que c'est exactement standard, mais il a les installations que vous voulez.la source
Depuis que vous l'avez nommé, le client redis standard dispose d'une interface de ligne de commande
redis-cli
. Quelques exemples deredis-cli -h
:(Et si vous souhaitez accéder à la base de données via le système de fichiers, vous pouvez utiliser des sockets avec
-s
. Un outil qui lirait l'index de la base de données directement à chaque appel serait très inefficace.)la source