Aiuto con DB Structure, sito vOD

1

Ho un sito in stile video on demand che ospita serie di video in diversi moduli . Tuttavia, con il modo in cui ho progettato il database, si sta dimostrando molto lento. Ho già fatto questa domanda e qualcuno ha suggerito l'indicizzazione, ma non riesco a capirlo. Ma vorrei che qualcuno aiutasse con la struttura del database qui per vedere se può essere migliorato. La tabella principale è Video:

ID       bigint(20) (primary key, auto-increment)
pID      text   
airdate  text   
title    text   
subject  mediumtext
url      mediumtext
mID      int(11)
vID      int(11)    
sID      int(11)

pID è una stringa di 5 cifre unica per ogni video che è un identificatore stenografico. Airdate è il TS, (memorizzato in formato testo, proprio lì forse dovrei cambiarlo in TIMESTAMP AUTO UPDATE), il titolo è auto esplicativo, il soggetto è autoesplicativo, url è l'hard link sul sito al video, il mID è unito a un'altra tabella per il titolo del modulo, vID è unito a un'altra tabella per la lingua del video, (inglese, russo, ecc.) e sID è il riepilogo del modulo, un paragrafo memorizzato in un database esterno.

La parte più lenta del sito Web è la parte relativa alla registrazione. Conservo i dati in un'altra tabella chiamata 'Hits':

id      mediumint(10)   (primary key, auto-increment)
progID  text
ts      int(10)

Di nuovo, qui (questo è stato fatto un po 'di tempo fa) ma il mio Timestamp (ts) è un INT invece di ON UPDATE CURRENT TIMESTAMP, che suppongo dovrebbe essere. Tuttavia questa tabella ora ha una lunghezza di 47.492 righe e lo script che ho scritto per elaborarlo è molto lento, quindi lento nel tempo. Una riga viene aggiunta a questa tabella ogni volta che un utente fa clic su "Riproduci" sul sito Web e quindi il progID è uguale al pID e registra la data / ora di php time () in ts .

Fondamentalmente carico l'intero database di 'Hits' in un array e conto i colpi in ogni giorno usando la colonna TS. Sto indovinando (sono abbastanza lento a tutto questo, ma non avevo idea che questo sarebbe accaduto quando ho costruito la cosa) che questo è probabilmente il modo peggiore per farlo.

Quindi le mie domande sono le seguenti:

  1. C'è un modo migliore per strutturare la tabella "Video", è così, cosa suggerisci?
  2. Esiste un modo migliore per strutturare gli "hit", in tal caso, per favore aiutami / dimmi!

O è il fatto che le mie tabelle stiano bene e la codifica PHP sia schifosa?

    
posta Chud37 21.08.2012 - 12:05
fonte

3 risposte

1

Basically I load the entire database of 'Hits' into an array and count the hits in each day using the TS column.

Vuoi velocità, De-normalizza. Questa è una di quelle rare occasioni in cui la de-normalizzazione è OK. per rallentare il tuo sito anche un po 'per qualcosa di minore come hit counter è pazzesco.

Quindi crea una tabella come tale:

Video bigint(20) 
Date (Date Only)
HitCounter int

Ogni volta che ottieni un successo Aggiorna questa tabella, aggiungendo uno alla HitCounter . (Inserisci un nuovo record con il primo colpo del giorno). Ora puoi sempre ottenere i tuoi conteggi in un istante.

Nota importante: ogni volta che decodifichi in questo modo, assicurati di avere una routine in grado di riparare i dati nella tabella di riepilogo. Questa routine dovrebbe essere eseguita regolarmente.

Come altri hanno sottolineato, poiché hai così pochi dati, sono d'accordo con loro nel dubitare che il contatore sia la causa del tuo problema di prestazioni. La soluzione sopra è molto probabilmente simile a ciò che YouTube sta facendo per i conteggi.

    
risposta data 21.08.2012 - 14:14
fonte
0
  1. Perché hai un pID stringa quando hai già un identificativo intero univoco in ID? La colonna ID, dichiarata come chiave primaria, è probabilmente già indicizzata e i confronti tra numeri interi sono molto più veloci di quelli a stringa. Perché non puoi semplicemente usare ID invece di pID ovunque e rilasciare la colonna pID?

  2. Penso che il numero 1 sopra sia un errore minore. Hai programmato la tua domanda per dimostrare a te stesso esattamente dove è la lentezza? A meno che tu non sia assolutamente certo di cosa sia lento, stai sprecando il tuo tempo cercando di accelerare le cose sbagliate.

In Java, io uso:

long startMs = System.currentTimeMs();
logger.info("Time before doing first thing: " + System.currentTimeMs() - startMs);
// do first thing.
logger.info("Time before doing second thing: " + System.currentTimeMs() - startMs);
// do second thing.
logger.info("Time after doing second thing: " + System.currentTimeMs() - startMs);
// etc.
logger.info("Total time: " + System.currentTimeMs() - startMs);

Esegui la parte lenta del tuo programma almeno 5 volte, forse 10 volte per essere sicuro che il tuo sistema di test non sia impegnato a fare qualcos'altro e ad abbandonare i tuoi orari. Annota i tuoi tempi, in particolare cosa è lento, esattamente quanto lento, e il tempo totale. Non vuoi accelerare una parte rallentando un'altra parte così tanto da rendere l'intera operazione più lenta.

    
risposta data 21.08.2012 - 16:01
fonte
0

Posso vedere un paio di cose che dovresti guardare.

A cosa serve il pID? Se è solo per collegare le 2 tabelle un int sarà molto più veloce e semplificare la tabella dei video.

Hai ragione, AirDate dovrebbe essere archiviato come un timestamp / datetime field, quando possibile, vuoi mantenere i campi di testo al minimo richiesto. Prenderò in considerazione la possibilità di spostare titolo, oggetto (e un nuovo campo di descrizione) in una tabella separata (questo mantiene la tabella dei video principale più piccola e veloce possibile):

ID bigint (same as videos.ID field)
title mediumtext
subject mediumtext
description mediumtext

Per la tabella degli hit, farei esattamente come suggerito da @Morons, possibilmente con una tabella aggiuntiva per registrare separatamente ciascuna riproduzione (se questo è importante):

ID bigint (same as videos.ID field)
playedat timestamp/datetime
playedby int (if userid is known) / text (IP address if videos can be played anonymously)

@Morons suggerisce comunque di aumentare la velocità. Come regola di base, quando possibile, spingere la maggior parte della logica dei dati sul server DB, è ciò per cui sono progettati e sono molto buoni (veloci), minimizza anche il numero di volte che si raggiunge il DB e la quantità delle informazioni che stai trasferendo sulla rete.

    
risposta data 29.09.2012 - 23:41
fonte

Leggi altre domande sui tag