Consiglio per Databse di Grande dimensione

di il
10 risposte

Consiglio per Databse di Grande dimensione

Ciao a tutti.
Vi chiedo questo consiglio in quanto non ho mai realizzato progetti di grandi dimensioni.

Stò realizzando un progetto per un mio amico scritto nel linguaggio PHP con database Mysql.

Questo progetto, che dovrà essere pubblicato online, è un portale dove ogni utente ha la sua area di gestione con le proprie
funzioni, gestire eventi, offerte, ecc..

In previsioni future, questo portare dovrà contenere sui 5000/6000 clienti e speriamo anche di più.
Per come ho realizzato il sistema, ogni gestione crea una tabella nel DB per ogni cliente che la utilizza.
Ho creato questa struttura in modo che il sistema non abbia una sola tabella di grande dimensioni, ma tante tabelle di piccole dimensioni.
Quindi (prendiamo per esempio la gestione eventi) per il cliente 1 ci sarà la tabella 1_eventi, per il cliente 2 ci sarà la tabella 2_eventi ecc..

Per come si stà evolvendo il progetto, sono già a circa 30 tabelle per utente, quindi nell'ottica di avere 5000 cliente si avrà un DB con 150000 tabelle.
Questa cosa mi preoccupa un po, in quando non so se Mysql può reggere un tale carico.

Ho pensato a diverse soluzioni, tra cui :
1) creare un DB per ogni utente (non so se risolvo il problema, avere 5000 DB ?? )
2) creare una sola tabella per ogni gestione e metterci il'id del proprietario (in questo caso secondo me si avrebbe una tabella con tanti record e con l'andare del tempo leggere e scrivere diventerebbe sempre più lento)
3) creare una soluzione intermedia fra DB e Tabelle, ovvero creare più DB che contengano 100/200 clienti (forse la più sensata).

Voi cosa mi consigliate di fare?
Grazie

10 Risposte

  • Re: Consiglio per Databse di Grande dimensione

    morriluca ha scritto:


    Ciao a tutti.
    ...Per come ho realizzato il sistema, ogni gestione crea una tabella nel DB per ogni cliente che la utilizza.
    Ho pensato a diverse soluzioni, tra cui :
    1) creare un DB per ogni utente (non so se risolvo il problema, avere 5000 DB ?? )
    2) creare una sola tabella per ogni gestione e metterci il'id del proprietario (in questo caso secondo me si avrebbe una tabella con tanti record e con l'andare del tempo leggere e scrivere diventerebbe sempre più lento)
    3) creare una soluzione intermedia fra DB e Tabelle, ovvero creare più DB che contengano 100/200 clienti (forse la più sensata).

    Voi cosa mi consigliate di fare?
    Grazie
    0) hai sbagliato il progetto
    1) un solo DB
    2) no e ti spiego perchè
    3) lascia perdere

    Cominciamo col dire che dipende dal carico e dal tipo di lavoro.
    Ho siti con 800.000 utenti, senza nessun problema.
    Inoltre è il mix (letture-scritture-concorrenza) che determina cosa ti serve; per i casi estremi c'è sempre lo sharding, ovvero la suddivisione
    automatica in più file dei dati, operati mediante tipicamente un partizionamento della chiave.
    In sostanza puoi fare quello che chiedi direttamente dal db (meglio mariadb invece di mysql).
    Aumentando o diminuendo la selettività dello sharding puoi avere un controllo abbastanza buono sulla granularità dello scattering.
  • Re: Consiglio per Databse di Grande dimensione

    Architettura sbagliata:

    un DBMS Relazionale (QUALUNQUE DMBS relazionale, da MySQL a Oracle) NON E' PROGETTATTO per gestire decine/centinaia di migliaia di tabelle, almeno non nel modo in cui lo hai descritto tu.

    E non e' progettato NEMMENO per gestire decine/centinaia di migliaia di database distinti.

    Pero' e' progettato per gestire MILIONI o MILIARDI di record in ogni tabella.

    In questo contesto (poche tabelle, tanti record), 5000/100.000 utenti, o anche 1.000.000 NON SONO minimamente un problema.

    Il tuo approccio, quindi, e' sbagliato concettualmente: stai evitando di utilizzare una delle caratteristiche FONDAMENTALI del DBMS.

    Riproggetta il tutto, e studia teoria relazionale dei dati

    perche' le alternative 1) e 3) che hai indicato sono altrettanto sbagliate, basandosi su ipotesi sbagliate.

    Quella corretta, OVVIAMENTE, e' la 2)!

    I problemi di performace del DBMS sono problemi legati all'ERRATA creazione di opportuni indici (in altri termini, all'errata progettazione), NON alla dimensione della tabella.

    Tanto per darti qualche numero:

    - se cercare UNA RIGA in una tabella con UN RECORD stai 1 millisecondo,
    - cercare UNA RIGA in una tabella con 1.000.000 di RECORD potresti stare, ad esempio, tra i 6 millisecondi ed i 20 millisecondi! NON UN MILIONE DI VOLTE in piu'!

    Architetture piu' complesse (DBMS in cluster, DMBS federati, DBMS distribuiti, sharding, ...) hanno senso solo quando inizi ad avere CENTINAIA DI MIGLIAIA/MILIONI o piu' utenti, distribuiti nel mondo.

    Se diventi il nuovo Zuckerberg, potresti avere di questi problemi
  • Re: Consiglio per Databse di Grande dimensione

    Bhè diciamo che sono, o non sono, un problema (le righe) a seconda dell'utilizzabilità degli indici, della selettività degli stessi, della shardabilità orizzontale, e magari pure verticale, dei dati, e come già detto dal mix letture-scritture-concorrenza.
    5.000 righe possono essere tantissime, al limite della gestibilità pratica odierna, o niente del tutto.

    Riguardo al non creare migliaia di tabelle e di db sono perfettamente d'accordo, anche perchè le tabelle che a loro volta mantengono le informazioni sono gestite dal db, e per mysql spesso con mysam (mariadb è migrata ad aria sotto questo profilo).

    Quindi, paradossalmente, anche solo sapere se un certo DB esiste implica una vera e propria query sulla tabella... degli schema
  • Re: Consiglio per Databse di Grande dimensione

    Aggiunta: se vuoi renderti la vita più semplice puoi sempre usare viste per suddividere logicamente le tabelle per i vari clienti, oppure più banalmente (e mooolto meglio dal punto di vista delle performances) gestire da applicazione la selezione.
    In sostanza che ne so puoi decidere (se la circostanza è pertinente al tuo caso) che i clienti col codice fiscale che inizia per A vanno nel db database_a; quelli che iniziano per B nel database_b e così via.
    Perdi però la possibilità di fare interrogazioni (facili) di tipo raggruppato, e devi sempre avere la chiave (ad esempio il codice fiscale).

    TRADUZIONE: se cerchi il cliente "pippo" non sai in quale DB sia, ti tocca cercarlo in tutti (il che è male)

    In certi casi (molto particolari, a me è successo una sola volta) si adottano strategie (sempre da applicazione) multilivello, cioè operando ad esempio con le prime cifre dell'hash della chiave (per ridurre il problema della "polverizzazione")


    Ed aggiungo un dettaglio: se devi arrivare ad un partizionamento sul database (cioè uno shard orizzontale tipicamente per RANGE di una tabella), o ad uno fisico (cioè uno spider-shard), allora hai così tanti clienti da poter pagare un professionista per fare un lavoro come si deve
  • Re: Consiglio per Databse di Grande dimensione

    migliorabile ha scritto:


    I problemi di performace del DBMS sono problemi legati all'ERRATA creazione di opportuni indici (in altri termini, all'errata progettazione), NON alla dimensione della tabella.
    Ahem... no, o meglio non solo
    - se cercare UNA RIGA in una tabella con UN RECORD stai 1 millisecondo,
    - cercare UNA RIGA in una tabella con 1.000.000 di RECORD potresti stare, ad esempio, tra i 6 millisecondi ed i 20 millisecondi! NON UN MILIONE DI VOLTE in piu'!
    Ahem... no, o meglio dipende.
    Questo è il classico errore (perdonami) del dilettante, cioè quello che non opera effettivamente con db grandi (e magari sarebbe interessante dire cos'è "grande", ma lasciamo stare).

    Supponiamo di avere 1.000.000 di record composto da 500.000 femmine e 500.000 maschi, con un campo "genere" (M o F).
    Se voglio cercare un maschio, mi serve a qualcosa un indice sul campo genere?

    Questo è un esempio banale di come la selettività dell'indice è un elemento chiave, uno dei tanti da tenere in considerazione (quasi mai viene spiegato nei corsi, insieme a tutti gli altri elementi che fanno la differenza tra i progetti didattico-scolastici-bimbominkieski e quelli veri-professionali)

    EDIT:
    Riproggetta il tutto, e studia teoria relazionale dei dati
    Bhè io studierei TUTTA la teoria dei DB, perchè quella relazionale è nata negli anni '60 per gestire certi problemi, che oggi, quasi 60 anni dopo, non ci sono più.

    Non è che se ti insegnano ad usare un martello tutti i problemi sono chiodi.
    Devi saper usare anche cacciaviti, lime e così via.

    POI scegli l' "attrezzo" più adatto per il problema.
  • Re: Consiglio per Databse di Grande dimensione

    Grazie dei vostri consigli,

    Ri-progetto il tutto creando per ogni tabella l'id di appartenenza dell'utente.

    Magari quando avrò (Se mai ci saranno) decine di miglia di cliente si vedrà se magari implementare lo sharding o altre tecniche.

    Grazie a tutti per il consigli
  • Re: Consiglio per Databse di Grande dimensione

    Cosa sarebbe per te "l'id di appartenenza dell'utente" ?
    Perchè a me non è così chiaro, a dir la verità.
    Mica vorrai fare una tabella utenti separata, così da pagare un join ad ogni singola interrogazione?
    Conviene di gran lunga denormalizzare, se hai il "problema esistenziale" di alte prestazioni.
  • Re: Consiglio per Databse di Grande dimensione

    No no,non sono matto, metto un campo in più nelle tabelle in comune id_utente che identifica l'appartenenza di quel record al cliente specifico.
  • Re: Consiglio per Databse di Grande dimensione

    morriluca ha scritto:


    No no,non sono matto, metto un campo in più nelle tabelle in comune id_utente che identifica l'appartenenza di quel record al cliente specifico.
    E poi come fai a cercare l'utente pippo (non l'utente id_utente=27) ?
    Così, tanto per dire.
  • Re: Consiglio per Databse di Grande dimensione

    +m+ ha scritto:


    E poi come fai a cercare l'utente pippo (non l'utente id_utente=27) ?
    Così, tanto per dire.
    Riparto dall'inizio.
    Questo software che stò facendo è un backoffice centralizzato.
    La dinamica è questa. Ipotizziamo che il software gestisca solo gli eventi.
    Ogni utente, con il proprio username e Password, accede a questa gestione e si gestisce i propri e eventi (tablella con campi id_evento, nome_evento,data_evento, ec...).
    Gli eventi fra i vari utenti devono essere scollegati, ovvero un utente può vedere, modifica, eliminare, ecc.. solo i suoi di eventi, e non deve in alcun modo poter vedere quelli degli altri utenti.
    Quindi in principio avevo scollegato gli eventi mettendoli fisicamente in tabelle differenti (l'utente 1 aveva la tabella eventi_1, l'utente 2 aveva la tabella eventi_2 ecc...).In questo caso ho la completa certezza che ogni utente agisce sulle proprie tabelle.

    Con il vostro consiglio invece vado a creare una sola tabella, chiamata eventi. Per sapere chi è il proprietario dell'evento, metto l'id dell'utente che è loggato al sistema. Questo implica che cosi ogni select, update, delete, ecc.. che vado ha fare avrà ci dovrà essere sarà sempre user_id = "utente loggato".

    Forse ora è un po più chiaro? credo in principio di aver fatto un po di confusione
Devi accedere o registrarti per scrivere nel forum
10 risposte