Memorizzazione di un dizionario C # di tipo datetime, enum [chiuso]

0

Come dice il titolo, sto cercando un modo per memorizzare molti dizionari (uno per utente) di tipo Dictionary<DateTime,enum> in un database (sql server 2012).

Ogni dizionario contiene 366 elementi e rappresenta un calendario in cui ogni giorno ha un determinato "stato" e preferibilmente non voglio memorizzare ogni elemento come un record separato nel DB. Idee?

Aggiorna :

Con il suggerimento @AndyBursh & @Konrad Morawski ha fatto, ho anche trovato un'altra ottimizzazione. Anziché creare un nuovo calendario (rappresentato come Dictionary ) per ogni elemento aggiunto dall'utente, sceglierne uno predefinito da un menu a discesa e, se questo non funziona, creare un calendario separato. Con la possibilità di riutilizzare un calendario e non memorizzare valori predefiniti, avrei a che fare con molti meno dati a lungo termine.

    
posta Aviatrix 10.04.2014 - 12:51
fonte

3 risposte

3

Sebbene un database sia ideale per archiviare un numero enorme di tuple (utente, datetime, enum), esiste un altro approccio che potrebbe essere adottato.

Supponiamo che la maggior parte dei valori datetime abbia un valore enum predefinito DEFAULT . Invece di memorizzare tutti i record (#users)*366 , è possibile memorizzare solo quei record che hanno un valore enum che non è DEFAULT . Gestire questo codice sarebbe semplice come inizializzare l'intero intervallo di valori datetime con il valore enum DEFAULT , quindi recuperare i record dal database e sostituire i valori enum dei dati recuperati.

Dictionary<DateTime, MyEnum> GetDictionary(int UserId)
{
    DateTime startDate = new DateTime();
    Dictionary<DateTime, MyEnum> calendar = 
        (from i in Enumerable.Range(0, 365)
        let dt = startDate.AddDays(i);
        select { date = dt, enumVal = MyEnum.DEFAULT})
        .ToDictionary(k => k.date, v => v.enumVal);

    var rows = this.FetchRows(UserId);
    foreach(SomeRow R in rows)
    {
        calendar[R.datetime] = R.enumValue;
    }
    return calendar;
}
    
risposta data 10.04.2014 - 13:07
fonte
2

Lo schiacciamento dell'intero dizionario in una riga non ha davvero ragione, uno dei principi fondamentali della progettazione di database è l'atomicità.

Dovresti serializzarlo in qualche modo (ad esempio in Json o anche in un blob), ma questa non è una soluzione raccomandabile e non sarai in grado di interrogare i dati convenientemente.

Non vedo alcun beneficio del tuo approccio che stai tentando di adottare.

my only reason is because i will always need to get the whole list of items and not each record separately, also each user can have up to thousand of those dictionaries, and a thousand users * ~5 dictionareis * 366 records each = 1 830 000 records in no time

Ok, ma allora? L'enorme mole di dati rimarrà la stessa, PIÙ il sovraccarico della deserializzazione ("spacchettamento" dei tuoi dictonari) o l'inconveniente di dover gestire un design insolito della tabella (come 366 colonne).

Se stai cercando di ridurre la quantità di dati, considera altre opzioni, ad es. è un valore enum predefinito / più prevalente rispetto agli altri? In tal caso, memorizzerei solo i valori "insoliti" nel database e l'assenza di una voce verrebbe considerata come valore predefinito per l'utente e il giorno specificati. Ma bisognerebbe dare più contesto.

    
risposta data 10.04.2014 - 13:03
fonte
2

Seriamente, il modo migliore è 4 colonne:

UserID (Guid or int)
CalendarNumber (smallint)
DayNumber (smallint)
Status (tinyint)

Non renderlo più complicato di quanto debba essere. Se hai fatto qualcosa come creare una tabella con 366 colonne, ti concederai un calcio in un secondo momento quando decidi che vuoi effettivamente archiviare una cosa in più per ogni giorno, oppure vuoi che Status sia un tipo di dati diverso. Cerca di non progettare te stesso in nessun angolo.

    
risposta data 10.04.2014 - 13:05
fonte

Leggi altre domande sui tag