DOMANDA Programma gestionale di una biblioteca: come realizzarlo?

Hero467

Utente Attivo
186
13
OS
Ubuntu 22.04 LTS
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?
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
1,558
1,201
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
30Mbps/3Mbps con Eolo
OS
Windows 10 64bit
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:
  • Mi piace
Reazioni: Andretti60

BAT

Moderatore
Staff Forum
Utente Èlite
11,915
5,327
CPU
Neurone solitario
Dissipatore
Ventaglio azionato a mano
Scheda Madre
Casalinga
RAM
Molto molto volatile
GPU
Binoculare integrata nel cranio
PSU
Pastasciutta, pollo e patatine al forno
Net
Segnali di fumo e/o tamburi
OS
Windows 10000 BUG
È 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)
 

Hero467

Utente Attivo
186
13
OS
Ubuntu 22.04 LTS
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
Post unito automaticamente:

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:

ilfe98

Moderatore
Staff Forum
Utente Èlite
2,760
1,102
CPU
Intel i7 7700K
Dissipatore
Bequiet Dark rock pro 4
Scheda Madre
Msi pc mate z270
HDD
Seagate barracuda 1tb, silicon power NVME 500gb
RAM
Patriot viper steel 3733Mhz
GPU
Inno 3d gtx 1080 herculez design
Monitor
Asus mg279q
PSU
Corsair HX750
Case
Itek lunar 23
Net
Tiscali ftth
OS
windows 10,mint,debian,Arch linux
Arrivo un po' tardi, ma in python potresti anche utilizzare un NOSQL, che ovvierebbe alle tue lacune.
 

Andretti60

Utente Èlite
5,792
4,384
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.
 

Hero467

Utente Attivo
186
13
OS
Ubuntu 22.04 LTS
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?
 

ilfe98

Moderatore
Staff Forum
Utente Èlite
2,760
1,102
CPU
Intel i7 7700K
Dissipatore
Bequiet Dark rock pro 4
Scheda Madre
Msi pc mate z270
HDD
Seagate barracuda 1tb, silicon power NVME 500gb
RAM
Patriot viper steel 3733Mhz
GPU
Inno 3d gtx 1080 herculez design
Monitor
Asus mg279q
PSU
Corsair HX750
Case
Itek lunar 23
Net
Tiscali ftth
OS
windows 10,mint,debian,Arch linux
Perché è necessario un NoSQL?
Non è assolutamente necessario in questo ambito, in altri contesti è fortemente consigliato, ovvero quelli in cui bisogna analizzare grandi flussi di dati( I Big Data Analysis)
 

Entra

oppure Accedi utilizzando