DOMANDA Programma gestionale di una biblioteca: come realizzarlo?

Pubblicità
La velocità è relativa, non è tutto. Innanzitutto sono gli algoritmi da ottimizzare.
Poi, per dire, immagina di avere il software in rete: se le query sono ottimizzate ma le immagini delle copertine dei libri pesano 3MB l'una, puoi usare Python o C++, ma non avrai differenze, in quanto il problema è dettato da altro.
Certo, ma uno dei vantaggi di avere tutto in locale è proprio quello della velocità. In caso lo mettessi in rete in futuro di può fare in modo che le immagini delle copertine non vengano caricate tutte insieme per non sovraccaricare la cache, ma richiamane una solo quando si apre la scheda del libro in questione.

Tra un software desktop e uno via web (quindi su un server) ti consiglierei la seconda. Al di là di ottimizzazioni, facilità di distribuzione etc avresti un problema non trascurabile, a mio avviso: il fatto che potrà essere crackato.
Ma se io inserissi nel software desktop la richiesta di una chiave di licenza, che il software confronta con quelle memorizzate in un database in rete sarebbe più difficile il crack, almeno credo.

Per risponderti nel merito di MySQL: la cosa corretta è avere una tabella dei prestiti, dove associ il libro e la persona a cui l'hai prestato; quindi avrai quelle che si chiamano chiavi esterne. Saranno due colonne tipo id_utente e id_libro.
Ovviamente dovrai considerare anche il numero di libri che hai a disposizione, nel senso che puoi prestare a due persone diverse il medesimo libro (insomma, se ci sono 10 copie, in teoria puoi prestarne 10, MA ad esempio solo a persone diverse).
Quindi ricapitolando ho bisogno di tre database:
  1. Quello per la lista dei libri che la biblioteca possiede con Titolo, Autore, Genere, Id, Ultimo prestito da collegare ad un’altra tabella (anche se non sono arrivato ancora a quel punto con SQL, quindi al momento lo inserisco come valore normale) e Numero di copie.
  2. Quello per i vari prestiti con Nome e cognome di chi ha preso il libro che saranno due valori distinti in una tabella con la lista dei registrati, che unirò in uno solo in questa tabella (se si può fare), Data di presa in prestito, data di restituzione, Titolo del libro sempre da collegare alla tabella della lista dei libri. Però forse è meglio mettere l’ID dell’utente e del libro al posto che nome è titolo. Quale mi consigliate?
  3. Quella con i vari utenti che sono registrati alla biblioteca con Nome, Cognome, Data di registrazione, Ultimo libro preso in prestito e Id

È tutto corretto o devo cambiare qualcosa nello schema?
 
Certo, ma uno dei vantaggi di avere tutto in locale è proprio quello della velocità. In caso lo mettessi in rete in futuro di può fare in modo che le immagini delle copertine non vengano caricate tutte insieme per non sovraccaricare la cache, ma richiamane una solo quando si apre la scheda del libro in questione.

In locale le immagini le dovrai caricare comunque, avranno comunque un peso.
In merito alla rete però no, non dovresti fare così: l'approccio corretto sarebbe innanzitutto comprimerle. Ma era solo un esempio, potrei anche fartene un altro: se hai un algoritmo che fa 2 cicli innestati, è comunque "non efficiente", al di là che tu lo scriva in C++ o in altro.
Posto che sul Web chiaramente potresti usare altri linguaggi, come Go ad esempio. Ma sarà un problema che ti porrai a tempo debito. ?

Ma se io inserissi nel software desktop la richiesta di una chiave di licenza, che il software confronta con quelle memorizzate in un database in rete sarebbe più difficile il crack, almeno credo.
Quindi lo limiteresti al solo utilizzo online? Si, puoi anche farlo.
Considera però che dipende come lato codice vai a fare il controllo. Ipotizzando che utilizzi un linguaggio nativo, potresti ritrovarti con tutta la procedura che recupera il seriale e poi fregarti con un controllo stile:

Codice:
; EDX = risposta dal server -> true | false
CMP     EDX, 0
JE        _seriale_errato
; seriale corretto

_seriale_errato:

e ci vorrebbero 2 minuti a bypassarla, una volta individuata. ?
Inoltre dovresti valutare come generare le key, per non averne una unica (metti che qualcuno lo compra e diffonde la chiave... saresti fregato).

Ma venendo a quanto chedi...
Quindi ricapitolando ho bisogno di tre database:
  1. Quello per la lista dei libri che la biblioteca possiede con Titolo, Autore, Genere, Id, Ultimo prestito da collegare ad un’altra tabella (anche se non sono arrivato ancora a quel punto con SQL, quindi al momento lo inserisco come valore normale) e Numero di copie.
  2. Quello per i vari prestiti con Nome e cognome di chi ha preso il libro che saranno due valori distinti in una tabella con la lista dei registrati, che unirò in uno solo in questa tabella (se si può fare), Data di presa in prestito, data di restituzione, Titolo del libro sempre da collegare alla tabella della lista dei libri. Però forse è meglio mettere l’ID dell’utente e del libro al posto che nome è titolo. Quale mi consigliate?
  3. Quella con i vari utenti che sono registrati alla biblioteca con Nome, Cognome, Data di registrazione, Ultimo libro preso in prestito e Id

È tutto corretto o devo cambiare qualcosa nello schema?

Hai bisogno di 1 solo database, innanzitutto. Quello a cui fai riferimento tu sono tabelle. A cosa ti serve il campo "Ultimo prestito"? Puoi già ricavarlo dalla tabella dei prestiti. Ti basterebbe fare una query usando un ORDER BY ASC usando come WHERE l'id della persona e l'id del libro, e prendere il primo record, ad esempio.

No, la tabella 2 non mi sembra giusta: ricorda che il db deve essere normalizzato. Non devi ripetere i dati che ti puoi evitare (anche perchè in caso di modifica impazzisci), oltre ad occupare spazio inutilmente.
La 2 secondo me potrebbe avere questa struttura:

Codice:
// Prestiti
| ID | id_utente | id_libro | data_prestito | data_restituzione |

Questa tabella va ad associare un utente (id_utente) e un libro (id_libro) con il prestito. In questo modo non avrai ripetizioni, e risulterà anche semplice effettuare ricerche, cancellazioni etc etc.
Al tuo posto andrei ad aggiungere anche un'altra colonna, un flag, che indichi se il libro è stato restituito. Ti agevolerà molto le ricerche.

La 3 va quasi bene, toglierei solo "ultimo libro presto in prestito", perchè tanto lo recuperi sempre in maniera analoga dalla tabella dei prestiti.

Di solito per queste operazioni si utilizzano le JOIN. Diciamo che hai il libro con ID = 1 e vuoi vedere a quante persone è stato prestato. Puoi fare una cosa come questa:

Codice:
SELECT * FROM tabella_prestiti
LEFT JOIN tabella_libri ON tabella_libri.id = id_libro
WHERE tabella_libri.id = 1 AND restituito = 0;

Qui ottieni tutti i record di tabella_prestiti che hanno come ID libro 1 e che non sono stati restituiti (restituito = 0). Puoi anche complicare la ricerca in base a quello che ti serve poi; tipo aggiungere un filtro per estrarre solo quelli in prestito a un determinato utente.

In questo modo oltre ad avere delle tabelle più ottimizzate anche le ricerche saranno più veloci (cercare su un numero è più rapido che cercare su una stringa).
Queste colonne come id_libro e id_utente saranno poi degli indici (delle chiavi esterne, ma puoi trascurare questo fatto attualmente, tutto funzionerebbe comunque).

EDIT: aggiungo una precisazione: se non vuoi la colonna 'restituito' un modo veloce per vedere se è stato restituito o no è verificare che la data di restituzione sia ad esempio NULL o diversa da NULL (a seconda che cerchi quelli restituiti o non restituiti).
 
Ultima modifica:
È tutto corretto o devo cambiare qualcosa nello schema?
il database deve essere uno solo, non 3
1 database con varie tabelle eventualmente collegate tra loro...
cioè hai 1 databse con (per ora) 3 tabelle (quelle dei punti 1-2-3 del tuo precedente post)
 
il database deve essere uno solo, non 3
1 database con varie tabelle eventualmente collegate tra loro...
cioè hai 1 databse con (per ora) 3 tabelle (quelle dei punti 1-2-3 del tuo precedente post)
si scusa, molto spesso faccio confusione tra i due
--- i due messaggi sono stati uniti ---
In locale le immagini le dovrai caricare comunque, avranno comunque un peso.
In merito alla rete però no, non dovresti fare così: l'approccio corretto sarebbe innanzitutto comprimerle. Ma era solo un esempio, potrei anche fartene un altro: se hai un algoritmo che fa 2 cicli innestati, è comunque "non efficiente", al di là che tu lo scriva in C++ o in altro.
Posto che sul Web chiaramente potresti usare altri linguaggi, come Go ad esempio. Ma sarà un problema che ti porrai a tempo debito. ?
ah, mi sa che devo ripassare da questo punto allora.

Quindi lo limiteresti al solo utilizzo online? Si, puoi anche farlo.
Considera però che dipende come lato codice vai a fare il controllo. Ipotizzando che utilizzi un linguaggio nativo, potresti ritrovarti con tutta la procedura che recupera il seriale e poi fregarti con un controllo stile:

Codice:
; EDX = risposta dal server -> true | false
CMP     EDX, 0
JE        _seriale_errato
; seriale corretto

_seriale_errato:

e ci vorrebbero 2 minuti a bypassarla, una volta individuata. ?
Inoltre dovresti valutare come generare le key, per non averne una unica (metti che qualcuno lo compra e diffonde la chiave... saresti fregato).
mi sfugge l'istruzione JE...

Hai bisogno di 1 solo database, innanzitutto. Quello a cui fai riferimento tu sono tabelle. A cosa ti serve il campo "Ultimo prestito"? Puoi già ricavarlo dalla tabella dei prestiti. Ti basterebbe fare una query usando un ORDER BY ASC usando come WHERE l'id della persona e l'id del libro, e prendere il primo record, ad esempio.

No, la tabella 2 non mi sembra giusta: ricorda che il db deve essere normalizzato. Non devi ripetere i dati che ti puoi evitare (anche perchè in caso di modifica impazzisci), oltre ad occupare spazio inutilmente.
La 2 secondo me potrebbe avere questa struttura:

Codice:
// Prestiti
| ID | id_utente | id_libro | data_prestito | data_restituzione |

Questa tabella va ad associare un utente (id_utente) e un libro (id_libro) con il prestito. In questo modo non avrai ripetizioni, e risulterà anche semplice effettuare ricerche, cancellazioni etc etc.
Al tuo posto andrei ad aggiungere anche un'altra colonna, un flag, che indichi se il libro è stato restituito. Ti agevolerà molto le ricerche.

La 3 va quasi bene, toglierei solo "ultimo libro presto in prestito", perchè tanto lo recuperi sempre in maniera analoga dalla tabella dei prestiti.

Di solito per queste operazioni si utilizzano le JOIN. Diciamo che hai il libro con ID = 1 e vuoi vedere a quante persone è stato prestato. Puoi fare una cosa come questa:

Codice:
SELECT * FROM tabella_prestiti
LEFT JOIN tabella_libri ON tabella_libri.id = id_libro
WHERE tabella_libri.id = 1 AND restituito = 0;

Qui ottieni tutti i record di tabella_prestiti che hanno come ID libro 1 e che non sono stati restituiti (restituito = 0). Puoi anche complicare la ricerca in base a quello che ti serve poi; tipo aggiungere un filtro per estrarre solo quelli in prestito a un determinato utente.

In questo modo oltre ad avere delle tabelle più ottimizzate anche le ricerche saranno più veloci (cercare su un numero è più rapido che cercare su una stringa).
Queste colonne come id_libro e id_utente saranno poi degli indici (delle chiavi esterne, ma puoi trascurare questo fatto attualmente, tutto funzionerebbe comunque).

EDIT: aggiungo una precisazione: se non vuoi la colonna 'restituito' un modo veloce per vedere se è stato restituito o no è verificare che la data di restituzione sia ad esempio NULL o diversa da NULL (a seconda che cerchi quelli restituiti o non restituiti).
Perfetto, apporterò le modifiche subito, grazie mille
 
Ultima modifica:
Arrivo un po' tardi, ma in python potresti anche utilizzare un NOSQL, che ovvierebbe alle tue lacune.
Beh, per cominciare si potrebbe non usare affatto un database e memorizzare i dati in formato JSON, ci sono già librerie che li gestiscono, ma JSON non è nato come database.
Certo, si potrebbe usare un NoSQL come Mongo (che è gratuito), ma questi database sono nati per risolvere un altro tipo di problema, qui si può trovare una ottima spiegazione

In questo caso io andrei naturalmente con un database SQL, che ha anche il vantaggio di essere educativo, anche se occorrerà poi in futuro il dover usare un nosql, conoscere entrambi è indispensabile (solo così si potrà scegliere quale sia il migliore a seconda del caso). Tanto vale iniziare con SQLite, che come ripeto è compatto e non richiede installazione alcuna, perfetto per iniziare senza doversi sbattere con installazioni.
 
Beh, per cominciare si potrebbe non usare affatto un database e memorizzare i dati in formato JSON, ci sono già librerie che li gestiscono, ma JSON non è nato come database.
Certo, si potrebbe usare un NoSQL come Mongo (che è gratuito), ma questi database sono nati per risolvere un altro tipo di problema, qui si può trovare una ottima spiegazione

In questo caso io andrei naturalmente con un database SQL, che ha anche il vantaggio di essere educativo, anche se occorrerà poi in futuro il dover usare un nosql, conoscere entrambi è indispensabile (solo così si potrà scegliere quale sia il migliore a seconda del caso). Tanto vale iniziare con SQLite, che come ripeto è compatto e non richiede installazione alcuna, perfetto per iniziare senza doversi sbattere con installazioni.
Perché è necessario un NoSQL?
 
Pubblicità
Pubblicità
Indietro
Top