Come posso eseguire iterazioni su due cicli di dimensioni non corrispondenti, mantenendoli sincronizzati?

0

Ho una tabella di database in cui ogni riga è un film (con campi come "titolo", "direttore" e "autore") e una tabella correlata in cui ogni riga è uno screenshot di un film (con i campi " movie_id 'e' jpeg_data '). Ogni film ha 2-8 screenshot.

Voglio produrre dati nell'ordine

  • Film 1
    • Schermata 1
    • Screenshot 2
  • Film 2
    • Schermata 1
    • Screenshot 2
    • Schermata 3
    • Schermata 4

Ora la soluzione più semplice che ho trovato è quella di fare (uno pseudocodice approssimativo):

for movie in database.select id,title,director from movies
    print movie.title, movie.director
    for screenshots in database.select screenshots where movie_id = id
        print screenshots.screenshot

Questo funziona - ma è un ciclo annidato in cui il ciclo interno sta effettuando una chiamata al database. Ciò renderebbe ~ 2.800 chiamate al database con il mio set di dati attuale, che sembra terribilmente lento e inefficiente.

Ci deve essere una soluzione migliore, ma non posso davvero pensarne una. Mi piacerebbe selezionare tutti i film e selezionare tutti gli screenshot, quindi trovare un modo per iterare attraverso i due array mantenendoli sincronizzati tra loro, se questa è la parola giusta.

Qual è la cosa giusta / ottimale da fare in questo caso?

    
posta GreenTriangle 04.12.2014 - 00:08
fonte

1 risposta

4

Dopo alcuni commenti e la lettura della domanda di nuovo sono arrivato a una realizzazione di base - hai un problema XY:

and a related table where each row is one screenshot from a movie (with the fields 'movie_id' and 'jpeg_data')

I do see a performance hit, yeah; even with only 12 images on my locally-hosted webpage I'm seeing a 5-second loadtime as it fetches the images.

Il browser web è progettato per andare a recuperare tutti i dati il più velocemente possibile. Quando si esegue il rendering della pagina, spesso (non sempre) preferisce eseguire molti piccoli recuperi di dati statici (come le immagini) piuttosto che un unico grande recupero. L'unico grande recupero: deve attendere un po 'fino a quando non può avviare il rendering.

Questo è probabilmente il problema principale. Non è l'iterazione sui loop, ma piuttosto che devi iterare sul loop per ottenere i dati jpeg.

Non memorizzare l'immagine nel database. Archivia l'immagine come file statico a cui il server Web può accedere come file statico. Memorizza il nome del file o il percorso del file nel database.

Cercare di estrarre dal database un oggetto binario di grandi dimensioni (non di dimensioni consistenti) non è quello per cui è stato progettato o valido - questo è il modo in cui i filesystem sono buoni.

Related:

Mettendo da parte questo, hai due set di risultati. Puoi:

  • Usa il database (se lo supporta) per memorizzare le informazioni concatenate (nome del file) in una colonna.

    select M.id, M.moviename, group_concat(S.filename)
    from movie M
    join screenshots S on (S.movieid = M.id)
    group by M.id
    
  • Recupera tutti i dati come una struttura unita (perché ottenere due set di risultati in primo luogo?)

    select M.id, M.moviename, S.filename
    from movie M
    join screenshots S on (S.movieid = M.id)
    
  • Recupera tutti i dati e inseriscili in una bella struttura del tuo programma e esegui un'iterazione.

    public class Movie {
        int id;
        String name;
        List<String> files;
    }
    
  • Iterate sul set di risultati e quando arrivate al film successivo, backup.

    for movie in moviesCursor
        print movie.title, movie.director
        for screenshots in screenShotCursor
            if screenshot.movieId != movie.id 
                screenShotCursor.previous
                break
            print "<img src=\"screenshots.fileName\">"
    

Alcuni di questi potrebbero essere limitati dalla scelta della lingua e del database.

    
risposta data 04.12.2014 - 01:00
fonte

Leggi altre domande sui tag