2009-06-14 3 views
0

BerkeleyDB ist das Datenbankäquivalent einer Ruby-Hashtabelle oder eines Python-Wörterbuchs, außer dass Sie mehrere Werte für einen einzelnen Schlüssel speichern können.Wie würden Sie eine relationale Entität als einzelne Einheit abrufbarer Daten in BerkeleyDB darstellen?

Meine Frage ist: Wenn Sie einen komplexen Datentyp in einer Speicherstruktur wie diesem speichern möchten, wie können Sie darüber gehen?

In einer normalen relationalen Tabelle, wenn Sie eine Person darstellen mögen, erstellen Sie eine Tabelle mit Spalten von bestimmten Datentypen:

Person 
-id:integer 
-name:string 
-age:integer 
-gender:string 

Wenn es so geschrieben ist, können Sie, wie eine Person sehen könnte als eine Reihe von Schlüssel/Wert-Paare zu verstehen:

id=1 
name="john"; 
age=18; 
gender="male"; 

Zersetzen der Person in einzelne Schlüssel/Wert-Paaren (name = „John“) ist einfach.

Um jedoch das BerkeleyDB-Format zur Darstellung einer Person zu verwenden, benötigen Sie eine Möglichkeit, die Person aus den zugehörigen Schlüssel/Wert-Paaren zusammenzusetzen.

Dafür müssten Sie eine künstliche Einkapselungsstruktur aufstellen, um eine Person als Einheit zusammenzuhalten.

Gibt es eine Möglichkeit, dies zu tun?

BEARBEITEN: Wie Robert Harvey's Antwort zeigt, gibt es eine Entity Persistenz-Funktion in der Java edition von BerkeleyDB. Leider, weil ich eine Verbindung zu BerkeleyDB von einer Ruby-Anwendung unter Verwendung Moneta herstellen werde, werde ich die standard edition verwenden, die ich glaube, erfordert, dass ich eine benutzerdefinierte Lösung in Ermangelung dieser Unterstützung erstellen.

Antwort

3

Sie immer (so genannte Rangierung in Ruby), um die Daten als String und speichert, die stattdessen serialisiert werden kann. Die Serialisierung kann auf verschiedene Arten erfolgen.

Mit YAML (Vorteile: Menschen lesbare, mehrere Implementierung in verschiedenen Sprachen):

require 'yaml'; str = person.to_yaml 

Mit Rangierung (Rubin nur, auch Ruby-Version spezifisch):

Marshal.dump(person) 

Dies funktioniert nur, Wenn die Klasse einer Person eine Entität ist, die sich nicht auf andere Objekte bezieht, die nicht enthalten sein sollen. Zum Beispiel müssten Verweise auf andere Personen anders behandelt werden.

2

Wenn der Datenspeicher ist in der Lage, dies zu tun (und BerkeleyDB tut AFAICT) Ich würde nur eine Darstellung der Objektattribute speichern Keyed mit der Objekt-ID, ohne die Objektattribute in verschiedenen Schlüsseln zu teilen.

z. gegeben:

Person 
-id:1 
-name:"john" 
-age:18 
-gender:"male" 

ich die yaml Darstellung in BerkleyDB mit dem Schlüssel person_1 speichern würde:

--- !ruby/object:Person 
attributes: 
    id: 1 
    name: john 
    age: 18 
    gender: male 

Stattdessen, wenn Sie jedes Attribut als Schlüssel im Datenspeicher (warum?) speichern, müssen Sie sollten Stellen Sie sicher, dass der Schlüssel für den Personendatensatz mit seinem Identifizierungsattribut verbunden ist, das ist die ID für einen ActiveRecord.

In diesem Fall würden Sie diese Schlüssel in BerkleyDB speichern:

person_1_name="john"; 
person_1_age=18; 
person_1_gender="male"; 
+0

Das ist knapp zur richtigen Strategie. Seien Sie vorsichtig beim Umgang mit Objekten, die andere Objekte "has_a" haben. Sie möchten die meiste Zeit einen Verweis auf das andere Objekt speichern. Ich habe etwas googeln, und es sieht nicht so aus, als hätte Ruby eine echte Objektdatenbank, was schade ist. Sieh dir Perls KiokuDB oder CLs Elephant an, um zu sehen, wie man so etwas richtig macht. – jrockway

+0

Ja, richtig. Wenn BerkleyDB keine strenge Anforderung wäre, würde ich auch Redis: http://code.google.com/p/redis/ betrachten, da es dem Entwickler viel mehr Vokabular von Datenstrukturen (Listen, Sets) mit einem wohldefinierte Rechenkomplexität (zB kennen Sie die Big-O-Komplexität der verschiedenen Operationen) – LucaM

Verwandte Themen