2010-08-21 11 views
6

Ich habe einen Datensatz von Büchern und Autoren, mit einer Viele-zu-viele-Beziehung.Viele-zu-viele Datenstruktur in Python

Es gibt ungefähr 10^6 Bücher und 10^5 Autoren, mit einem Durchschnitt von 10 Autoren pro Buch.

Ich muss eine Reihe von Operationen auf dem Datensatz ausführen, z. B. die Anzahl der Bücher von jedem Autor zählen oder alle Bücher von einem bestimmten Autor aus dem Satz löschen.

Was wäre eine gute Datenstruktur sein, die schnelle Handhabung ermöglicht?

Ich hoffe auf einige fertige Modul, das Verfahren nach dem Vorbild der zur Verfügung stellen kann:

obj.books.add(book1) 

# linking 
obj.books[n].author = author1 
obj.authors[m].author = book1 

# deleting 
obj.remove(author1) # should automatically remove all links to the books by author1, but not the linked books 
ich klarstellen sollte, dass ich es vorziehen, nicht eine Datenbank für diese zu verwenden, aber alles in Erinnerung zu tun .

Dank

+2

die Informationen in eine Datenbank einfügen? – obelix

+1

Fügen Sie es in eine Datenbank ein, die sich im Speicher statt auf der Festplatte befindet. – carl

Antwort

16

sqlite3 (oder jede andere gute relationale DB, aber sqlite kommt mit Python und ist handlicher für eine solche einigermaßen kleine Menge von Daten) scheint den richtigen Ansatz für Ihre Aufgabe. Wenn Sie SQL lieber nicht lernen möchten, ist ein beliebter "Wrapper" über relationale DBs, so dass Sie mit ihnen auf verschiedenen Abstraktionsebenen Ihrer Wahl arbeiten können.

Und "alles im Speicher zu tun" ist überhaupt kein Problem (es ist dumme, wohlgemerkt, da Sie unnötigerweise den Overhead des Einlesens in allen Daten von irgendwo mehr hartnäckig auf jedem Durchlauf von bezahlen Ihr Programm, während Sie die Datenbank auf einer Festplattendatei aufbewahren, würde Ihnen diesen Overhead sparen - aber das ist ein anderes Problem ;-). Öffnen Sie einfach Ihre SQLite-Datenbank als ':memory:' und da sind Sie ja - eine frische, neue relationale DB leben vollständig im Speicher (für die Dauer des Prozesses nur), keine Scheibe an dem Verfahren beteiligt bei allen. Also, warum nicht? -)

Persönlich würde ich SQL direkt für diese Aufgabe verwenden - es gibt mir ausgezeichnete Kontrolle über genau, was vor sich geht, und lässt mich leicht Indizes hinzufügen oder entfernen, um Leistung, etc. zu optimieren verwende drei Tabellen: eine Books Tabelle (Primärschlüssel-ID, andere Felder wie Titel & c), eine Authors Tabelle (Primärschlüssel-ID, andere Felder wie Name & c) und eine "Viele-zu-Viele-Beziehungstabelle ", sagen BookAuthors, mit nur zwei Felder, BookID und AuthorID, und ein Datensatz pro Autor-Buch-Verbindung.

Die beiden Felder der Tabelle BookAuthors sind sogenannte "Fremdschlüssel", die sich auf die ID-Felder von Büchern und Autoren beziehen, und Sie können sie mit einem ON DELETE CASCADE definieren, sodass Datensätze auf ein Buch oder einen Autor verweisen gelöscht werden automatisch gelöscht - ein Beispiel für die hohe semantische Ebene, auf der sogar "bare" SQL Sie arbeiten lässt, die keine andere existierende Datenstruktur annähernd erreichen kann.

+2

Ich glaube, sqlite hat sogar eine Option, um die Datenbank im Speicher zu erstellen. – Omnifarious

+1

Um Speicher wie in den Kommentaren zum OP zu verwenden: "Sie können auch den speziellen Namen': memory: 'angeben, um eine Datenbank im RAM zu erstellen." –

+0

Darüber hinaus kann sqlite nur im Speicher verwendet werden - siehe http://www.sqlite.org/inmemorydb.html – Brendan

2

Ich hoffe auf einige fertige Modul, das Verfahren nach dem Vorbild der zur Verfügung stellen kann: tatsächlich, dass

Da funktioniert, was will man mehr?

Sie haben ein Buch und eine Autor Klassendefinition. Sie haben auch eine Book-Author-Zuordnung für die Beziehungen. Die erforderlichen Methoden zum Verwalten von Hinzufügen/Ändern/Löschen sind nur ein paar Zeilen Code.

Erstellen Sie große alte Wörterbücher von Autoren-, Bücher- und Author-Book-Assoziationsobjekten.

Verwenden Sie shelve, um alles zu speichern.

Fertig.