Approccio per la memorizzazione di molti dati di tipo sconosciuto nel database

3

Ho un'app Web a cui è possibile collegare applicazioni esterne per inviare i propri dati. Questo è per scopi di telemetria.
L'app Web non controlla il tipo di dati di telemetria che gli viene inviato: può essere qualsiasi cosa in una forma di Dictionary<string, object> .

Intendo memorizzare ogni chiave di questa coppia di valori chiave come una riga separata nella tabella "TelemetryDetails".

La tabella conterrà Id (int), Key (stringa) - e valori - tuttavia, non sono sicuro in quale formato.

Ci sono due considerazioni:

  • Probabilmente il tavolo diventerà di dimensioni enormi, quindi mi piacerebbe mantenerlo il più "leggero" possibile. Suppongo che meno colonne siano "migliori" per il database?
  • Voglio consentire la semplice & interrogazione veloce di questi dati

Mi chiedo se è meglio mantenere qualsiasi valore come stringa (avendo così solo tre colonne in questa tabella), o creare una colonna separata (e quindi una proprietà sulla mia entità EF) per ciascuno dei tipi di dati primitivi, ad esempio:

public class MyEntity
{
    public int Id { get; set; }

    [MaxLength(50)]
    public string Key { get; set; }

    public string ValueTypeName { get; set; } //maybe also have the type stored...

    public string ValueString { get; set; }

    public bool? ValueBoolean { get; set; }

    public decimal? ValueDecimal { get; set; }

    public int? ValueInt { get; set; }

    public DateTime? ValueDateTime { get; set; }
}

In questo modo la tabella ottiene più colonne, di cui la maggior parte è nullo, il valore effettivo è memorizzato solo in una di esse - questo potrebbe consentire alle query più veloci / più leggere di ottenere dati "user-chart-friendly", con calcoli come SUM, AVG, MAX ecc. - che non è possibile sulle stringhe.

Inoltre, se vai avanti con questo approccio, forse avrebbe anche senso avere diverse colonne per ValueString con una lunghezza diversa - ad es. non mantenere le stringhe corte nella colonna NVARCHAR (MAX)?

Non sono sicuro che tutto ciò non sia pseudo-ottimizzazione senza senso e / o cattiva progettazione.

    
posta Bartosz 09.12.2018 - 11:36
fonte

2 risposte

1

Ottimizzazione prematura

Sebbene possa essere doloroso migrare a schemi specifici in seguito, senza ulteriori informazioni sulla forma sia nello spazio che nel tempo dei tuoi dati, il meglio che puoi fare è una riga per valore.

Dicendo ciò, non stringere i dati perché vuoi una sola tabella. Crea una tabella per tipo di dati noto. Ciò avrà un payoff sia nell'uso dello spazio (non c'è bisogno di un campo di tipo) sia nella velocità (non c'è bisogno di controllare / convertire algoritmicamente i tipi).

Se sei a conoscenza degli schemi specifici che verranno ricevuti, puoi ottimizzare lo spazio rappresentando ciascuno schema come una tabella. Sfortunatamente questo è un compromesso con la complessità dato che ciascuno di questi schemi specializzati renderà le query e l'aggregazione per ogni chiave / evento / valore più difficile e potrebbe infatti essere più lento, rendendo più veloci le query specifiche dello schema.

Un modo per osservare la struttura:

Event Table := Event ID | Received | Other meta-data

Value Table[Type] := Event ID | Key | Value[Type]

Una volta che i dati fluiscono attraverso il sistema, puoi ottenere statistiche e formulare un giudizio informato su come ottimizzare le tabelle, il codice o l'hardware.

    
risposta data 10.12.2018 - 06:21
fonte
1

Con questo tipo di dati non definiti, "massività" e modello di dati banali, prenderei in considerazione la possibilità di scrivere il proprio servizio e utilizzare un normale file system come back store con ogni blob come file. In questo modo ottieni

  • Scalabilità Aggiungi volumi o anche macchine / NAS / server in base alle esigenze.

  • Accoppiamento lento Non sei legato a nessun RDBMS e sarà facile convertirlo in qualsiasi altro momento successivo.

Sarà aperto, robusto e facile da eseguire il backup in modo incrementale. È possibile supportare diversi front-end, da un eseguibile locale a un browser Web.

    
risposta data 10.12.2018 - 07:38
fonte