Ho optato nuovamente per le liste concatenate.Puoi usare una Union, dove inserire tutti i tipi di dato a cui sei interessato, ovvio poi hai bisogno di un ulteriore membro che definisce che tipo di dato da usare per quel particolare valore. È quello che si fa anche in C++, un sacco di istruzioni “switch” tutte le volte che si accede ai valori (ma almeno in C++ sono incapsulati dentro a una classe.)
struct interolista{
int valore;
int nonusata;
struct interolista *successivo;
};
struct varcharfissolista{
char valore[100];
int nonusata;
struct varcharfissolista *successivo;
};
struct doppiolista{
double valore;
int nonusata;
struct doppiolista *successivo;
};
struct record{
int indiceriga;
char numerocolonne;
struct interolista *il;
struct varcharfissolista *vfl;
struct doppiolista *dl;
};
Guarda che non è sbagliato del tutto secondo me. E' vero che non è questo il modo di implementare un db ma con cio che dici non sono d'accordo. grazie del supporto @Andretti60. Perchè 6 campi nelle liste non mi sembra uno spreco di memoria ma giustamente le liste collegate si usano per altri scopi ;)Scusa quello che stai facendo non ha alcun senso
c'è un motivo:Senza dubbio non si è sentito mai parlare di database che usassero liste concatenate per descrivere campi generici.
Tutto chiaro. Infatti probabilmente occorre pensare al design del db in termini di chunk di file per pagina. Salvare i dati nel file assieme alla loro struttura e leggere i file non in forma di tabella ma di Btree. Conosco i Btree e cosa sono da un esame di algoritmi e strutture dati.Non importa quanto tu possa essere bravo a programmare o iperesperto in C, alla fine ti scontri con l'inefficienza intrinseca di una struttura dati completamente lineare.
Non ci sono database che usano liste perché esse non sono le strutture dati giuste con cui implementare i database:
servono strutture molto più complicate, chiamate B*Tree, molto più sofisticate ma immensamente più efficienti nella gestione di grandi quantità di dati. La loro struttura non è lineare ma bilanciata e consentono di fare praticamente tutte le operazioni in tempo logaritmico.
enum data_type {no_type, int_type, double_type, char_type};
union data {
double double_value;
int int_value;
char char_value[100];
};
struct {
union data value;
enum data_type type;
};
Certo che non puoi, ma è così che funzionano i database di tipo relazionale, i recordset sono “cablati” quando le tabelle vengono create, mediante appunto lo schema. Se in futuro si vogliono aggiungere o togliere colonne, sono dolori, in quanto occorre riscrivere tutto il database (buona fortuna...) per cui si usano tabelle aggiuntive che si accedono medianti opportune chiavi. Ma è anche quello che rende il database efficiente e veloce. Se vuoi tabelle dinamiche il solo modo è quello di usare un Database noSQL (tipo appunto chiave-valore, come per esempio il Registry di Windows), che usa tutto un altro approccio per renderlo efficiente. Lo puoi fare anche con un database di tipo relazionale, ma le query diventano complicatissime e la velocità fa schifo (ci sono passato di mezzo, lo so)è difficile da spiegare. E' senza dubbio uno spreco di spazio. Ma con il linguaggio C
non posso "inniettare" un membro in piu in una struct.
esatto, qualcosa di simile:Aggiungo solo che rispetto al codice che ho visto li sopra, puoi fare come suggerito da Andretti. Sono due righe "buttate li", ma credo che anche lui si riferisse a qualcosa di analogo:
...
struct Membro {
char key[100]; // l'dentificatore di questo membro, per esemio "autore" (puo anche essere una enumerazione)
union data value; // il valore di questo membro
enum data_type type; // il tipo di dato
struct Membro *next; // il valore successivo
};