2010-08-21 16 views
6

Tengo un conjunto de datos de libros y autores, con una relación muchos a muchos.Estructura de datos de muchos a muchos en Python

Hay alrededor de 10^6 libros y 10^5 autores, con un promedio de 10 autores por libro.

Necesito realizar una serie de operaciones en el conjunto de datos, como contar el número de libros de cada autor o eliminar todos los libros de un determinado autor del conjunto.

¿Cuál sería una buena estructura de datos que permitirá un manejo rápido?

que estoy esperando algún módulo ya hecha que puede proporcionar métodos a lo largo de las líneas de:

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 

Debo aclarar que yo no prefiero usar una base de datos para esto, pero para hacerlo todo en la memoria .

Gracias

+2

poner la información en una base de datos? – obelix

+1

Ponlo en una base de datos que reside en la memoria en lugar del disco. – carl

Respuesta

16

sqlite3 (o cualquier otro bien relacional DB, pero sqlite viene con Python y es más práctico para un razonablemente pequeño conjunto de datos tales) parece el enfoque adecuado para su tarea. Si prefiere no aprender SQL, SQLAlchemy es un popular "envoltorio" sobre los DB relacionales, por así decirlo, que le permite tratar con ellos en cualquiera de los diferentes niveles de abstracción de su elección.

Y "hacerlo todo en la memoria" no es ningún problema (es tonto, tenga en cuenta, ya que usted pagará innecesariamente la sobrecarga de leer todos los datos de un lugar más persistente en cada carrera de su programa, mientras mantiene el DB en un archivo de disco le ahorraría esa sobrecarga, pero ese es un problema diferente ;-). Simplemente abra su base de datos sqlite como ':memory:' y allí estará: una nueva base de datos relacional totalmente viva en la memoria (solo durante el proceso), ningún disco involucrado en el procedimiento en total. Entonces, ¿por qué no? -)

Personalmente, usaría SQL directamente para esta tarea - me da un control excelente de exactamente lo que está sucediendo, y me permite agregar o quitar fácilmente índices para ajustar el rendimiento, etc. Usaría tres tablas: una tabla Books (ID de clave principal, otros campos como Title & c), una tabla Authors (ID de clave principal, otros campos como Name & c) y una tabla de relaciones "muchos a muchos" ", diga BookAuthors, con solo dos campos, BookID y AuthorID, y un registro por conexión de libro de autor.

Los dos campos de la tabla BookAuthors son lo que se conoce como "claves externas", que se refieren respectivamente a los campos ID de Libros y autores, y los puede definir con un ON DELETE CASCADE para que los registros se refieran a un libro o autor Los borrados se eliminan automáticamente, un ejemplo del alto nivel semántico en el que incluso el SQL "simple" le permite trabajar, que ninguna otra estructura de datos existente puede igualar.

+2

Creo que sqlite incluso tiene una opción para crear la base de datos en la memoria. – Omnifarious

+1

Además, para usar la memoria según los comentarios en el OP: "También puede proporcionar el nombre especial': memory: 'para crear una base de datos en la RAM". –

+0

Además, sqlite solo se puede utilizar en memoria: consulte http://www.sqlite.org/inmemorydb.html – Brendan

2

que estoy esperando algún módulo ya hecha que puede proporcionar métodos a lo largo de las líneas de:

Desde que realmente funciona, ¿qué más necesitas?

Tiene una definición de clase Libro y Autor. También tienes una asociación Libro-Autor para las relaciones. Los métodos necesarios para administrar agregar/cambiar/eliminar son solo unas pocas líneas de código.

Crea grandes diccionarios antiguos de autores, libros y objetos de asociación autor-libro.

Use shelve para almacenarlo todo.

Listo.

Cuestiones relacionadas