2010-11-10 62 views
7

Una base de datos (simplificada) de marcadores de Internet. Pensé que tenga sentido para organizar las mesas lógicamente, así:Forma óptima de unir tres tablas en SQLite

Bookmarks (id, title, url; basically external data) 
+------+------------+-----+ 
| suid | Title | ... | 
+------+------------+-----+ 

User (user-specific data: favorites, ratings, etc) 
+------+------------+-----+ 
| suid | IsFavorite | ... | 
+  + (0 or 1) +  + 
+------+------------+-----+ 

History (last used, use count etc) 
+------+------------+-----+ 
| suid | LastUsed | ... | 
+  +(TDateTime) +  + 
+------+------------+-----+ 

('suid' es único ID, clave entera primaria)

de favoritos marcado como favorito necesito seleccionar N utilizado más recientemente (para llenar un menú en tiempo de ejecución como una conveniencia).

SELECT Bookmarks.suid, Title from Bookmarks 
    INNER JOIN User USING (suid) 
    INNER JOIN History USING (suid) 
    WHERE IsFavorite = 1 
    ORDER BY LastUsed DESC 
    LIMIT 15; 

La declaración funciona, y parece lo suficientemente legible, pero ¿es óptima? La tabla Marcadores está destinada a contener entre 20 y 50 k registros en promedio (es decir, no el administrador de marcadores del navegador estándar :-) La aplicación ejecutará 3 o 4 declaraciones similares al inicio para completar los controles. Todos los campos utilizados en el ejemplo están indexados.

Me estoy enseñando a mí mismo SQL y se me ocurrió el código anterior, pero ¿tal vez estoy pasando por alto una sintaxis o un modismo que podría mejorarlo?

+0

Si el indicador de favoritos está almacenado en la tabla de usuarios, inferiría que todos los marcadores asociados al usuario son favoritos, debe estar en el nivel de marcador o no entiendo bien el propósito. –

+0

Tengo una tendencia a sobreexplicar en mis preguntas, así que he inventado un simple ejemplo básico para evitar eso. La tabla de marcadores principal se actualizará periódicamente. Durante la actualización, no quiero tocar ningún dato que los usuarios ingresaron, como calificar, marcar como favoritos, etc. Parecía más claro separar los dos. Del mismo modo, es posible que algunos usuarios no deseen mantener el historial, en cuyo caso la aplicación puede borrar o eliminar toda la tabla de historial. (O, tal vez, el nombre "Usuarios" es engañoso. No es una tabla para los datos de la cuenta de usuario, sino para los puntos de datos ingresados ​​por los usuarios. Es una aplicación de escritorio de un solo usuario). –

Respuesta

4

Es imposible (o al menos muy, muy difícil) adivinar desde SQL sin procesar exactamente cómo el motor de la base de datos realizará satisfactoriamente la consulta. Por esa razón, necesita usar EXPLAIN para descubrir cómo SQLite realmente obtendrá los datos. Y tenga en cuenta que el plan de ejecución que genere será diferente según la cantidad de datos que haya en cada tabla y el aspecto que tengan los datos (en términos de cantidad de valores diferentes que se encuentran en las columnas indexadas). Así que asegúrese de preparar su base de datos de prueba con datos reales.

Una vez que pruebe EXPLAIN, creo que hay una posibilidad de que encuentre que SQLite une las tablas antes de tomar las 15 mejores coincidencias, lo que no sería óptimo si fuera cierto. Si esto resulta ser el caso, puede intentar algo como:

SELECT Bookmarks.suid, Title from Bookmarks 
    INNER JOIN User USING (suid) 
    WHERE IsFavorite = 1 
    AND suid IN (SELECT suid FROM History ORDER BY LastUsed DESC LIMIT 15); 

Pero, de nuevo, no trate de que hasta que he visto de explicar que SQLite está recibiendo los datos de una manera no óptima .

0

Me parece bien. Puede que ya lo sepa pero puede investigar su consulta utilizando la palabra clave de explicación (http://www.sqlite.org/lang_explain.html) si desea sintonizarla más.

¡Salud!

0

Puede usar la palabra clave EXPLAIN como ya se dijo, pero hay otras formas de mejorarla. Hay un sitio web con algo de información ... échale un vistazo haciendo clic en here para obtener más información al respecto ... ¡buena suerte!

Cuestiones relacionadas