Mesa Django con Millones de filas

Tengo un proyecto con 2 aplicaciones (libros y lector).

La aplicación de libros tiene una tabla con 4 millones de filas con estos campos:

book_title = models.CharField(max_length=40) book_description = models.CharField(max_length=400) 

Para evitar consultar la base de datos con 4 millones de filas, estoy pensando dividirla por tema (20 modelos con 20 tablas con 200.000 filas (book_horror, book_drammatic, ecc).

En la aplicación “lector”, estoy pensando en insertar estos campos:

 reader_name = models.CharField(max_length=20, blank=True) book_subject = models.IntegerField() book_id = models.IntegerField() 

Así que en lugar de ForeignKey, estoy pensando en utilizar un entero “book_subject” (que permite acceder a la tabla apropiada) y “book_id” (que permite acceder al libro en la tabla especificada en “book_subject”).

¿Es una buena solución para evitar consultar una tabla con 4 millones de filas?

¿Hay alguna solución alternativa?

Gracias ^ __ ^

Como muchos han dicho, es un poco prematuro dividir la mesa en tablas más pequeñas (partición horizontal o incluso fragmentación). Las bases de datos están diseñadas para manejar tablas de este tamaño, por lo que su problema de rendimiento probablemente se encuentre en otra parte.

Los índices son el primer paso, aunque parece que has hecho esto. 4 millones de filas deberían estar bien para que la db maneje con un índice.

En segundo lugar, compruebe el número de consultas que está ejecutando. Puede hacer esto con algo como la barra de herramientas de depuración de django, y a menudo se sorprenderá de cuántas consultas innecesarias se están realizando.

El almacenamiento en caché es el siguiente paso, use memcached para páginas o partes de páginas que no han cambiado para la mayoría de los usuarios. Aquí es donde verá su mayor aumento de rendimiento por el poco esfuerzo requerido.

Si realmente necesita dividir las tablas, la última versión de django (1.2 alpha) puede manejar el fragmentado (por ejemplo, multi-db), y debería poder escribir a mano una solución de partición horizontal (postgres ofrece un in-db manera de hacer esto). Por favor, no use el género para dividir las tablas! elige algo que nunca cambiarás y que siempre sabrás cuando hagas una consulta. Como autor y dividir por primera letra del apellido o algo así. Esto es un gran esfuerzo y tiene una serie de inconvenientes para una base de datos que no es particularmente grande. ¡Es por eso que la mayoría de las personas aquí están aconsejando no hacerlo!

[editar]

Dejé fuera la desnormalización! Coloque recuentos comunes, sums, etc. en la tabla de autor, por ejemplo, para evitar uniones en consultas comunes. El inconveniente es que debe mantenerlo usted mismo (hasta que django agregue un campo Denormalized). Me gustaría ver esto durante el desarrollo para casos claros y directos, o después de que el almacenamiento en caché le haya fallado — pero mucho antes de la fragmentación o la partición horizontal.

ForeignKey se implementa como IntegerField en la base de datos, por lo que ahorrará poco o nada a costa de paralizar su modelo.

Edición: Y, por el bien de Pete, manténgalo en una tabla y use los índices según corresponda.

¿Tienes problemas de rendimiento? Si es así, es posible que necesite agregar algunos índices .

Una forma de tener una idea de dónde podría ayudar un índice es mirar el registro de consultas de su servidor db (las instrucciones aquí están en MySQL).

Si no estás teniendo problemas de rendimiento, entonces sigue adelante. Las bases de datos están hechas para manejar millones de registros, y django es bastante bueno para generar consultas sensatas.

Un enfoque común a este tipo de problema es Sharding . Desafortunadamente, depende principalmente del ORM implementarlo (Hibernate lo hace maravillosamente) y Django no lo admite. Sin embargo, no estoy seguro de que 4 millones de filas sea realmente tan malo. Sus consultas deben ser completamente manejables.

Quizás deberías buscar en el caché con algo como memcached . Django soporta esto bastante bien.

No has mencionado qué base de datos estás usando. Algunas bases de datos, como MySQL y PostgreSQL, tienen configuraciones extremadamente conservadoras listas para usar, que son básicamente inutilizables para cualquier cosa, excepto bases de datos pequeñas en servidores pequeños.

Si nos dice qué base de datos está utilizando y en qué hardware se está ejecutando, y si ese hardware se comparte con otras aplicaciones (también está sirviendo a la aplicación web, por ejemplo), entonces podremos brindarle algunos ajustes específicos. Consejo.

Por ejemplo, con MySQL, probablemente necesitará ajustar la configuración de InnoDB; para PostgreSQL, deberá modificar shared_buffers y una serie de otras configuraciones.

No estoy familiarizado con Django, pero tengo una comprensión general de DB.

Cuando tienes bases de datos grandes, es bastante normal indexar tu base de datos . De esa manera, recuperar datos, debería ser bastante rápido.

Cuando se trata de asociar un libro con un lector, debe crear otra tabla que vincule al lector con los libros.

No es una mala idea dividir los libros en temas. Pero no estoy seguro de lo que quieres decir con tener 20 aplicaciones.