Il salvataggio dello spazio su disco è un motivo valido per rinunciare alla migrazione a un formato di testo standard (ad es. JSON)?

5

Qualche tempo fa ho chiesto una domanda sui formati di dati di testo personalizzati , invece di utilizzare strumenti esistenti come XML, JSON, YAML, ecc. Ora, a favore della conversione del nostro formato personalizzato in un database relazionale e alcuni segmenti di JSON (in un campo JSON ), Mi imbatto nel problema dei "dati gonfiati". Con questo intendo che ci sarà un lotto di aumento della duplicazione per il JSON (di cui c'è un bel po ', perché gran parte del sistema deve essere flessibile in diversi ambienti). Ad esempio, la parte del formato di testo personalizzato:

Data data data [#tag, #tag, ...]: some more data

Field: [id] description of data; [id] description

potrebbe essere convertito in:

{
    "data": "...",
    tags: ["tag", "tag", ...],
    "more_data": "some more data",
    "fields": [
        {
            "id": 123
            "description": "description of data"
        },
        {
            "id": 456
            "description": "description"
        }
    ]
}

Molti di questi nomi di proprietà JSON ora sono extra, ad es. more_data , id , description , che sono duplicati su milioni di voci JSON; saremo più che quadruplicare i nostri requisiti di archiviazione dei dati. Tuttavia, questo finisce con circa 100 MB rispetto ai precedenti 25 MB, per una maggiore flessibilità e sanità mentale. Certo, questa è un'app mobile, quindi 75 MB potrebbero scioccare alcuni utenti una volta in transizione - "perché questa app occupa ora lo spazio di 4x senza funzionalità aggiuntive?". Il formato personalizzato mantiene le cose belle e compatte, ma ovviamente i parser devono essere mantenuti, ei dati non possono essere interrogati in modo efficiente su qualcosa di diverso da alcuni campi primari (che sono tutti indicizzati manualmente ... tra l'altro).

Modifica : per chiarire alcuni commenti e una risposta: i dati che ho sono altamente relazionali, ad eccezione di alcune informazioni "tag" che variano per riga del database; vale a dire, il 90% del nostro formato personalizzato può essere convertito in una struttura relazionale, ma l'altro 10% è il 'tag', che non è strutturato e può variare in base al record. Questi "tag" contengono informazioni semantiche rilevanti per gli utenti, ma mai non possono essere interrogate. E poiché non è strutturato, JSON sembra la soluzione migliore. Dovrei anche notare che i tag possono essere (teoricamente) infinitamente variabili nella loro struttura, sebbene esistano ancora elementi comuni tra i tag (ad esempio id e description sono generalmente comuni a tutti). Tuttavia, non sarebbe fattibile disporre di una tabella di join XXXTag esplicitamente strutturata per ogni variazione del JSON ; Inizialmente pensavo che sarebbe stata una buona idea, per alleviare il problema nella domanda che sto chiedendo in questo momento, ma il numero di tabelle di join è teoricamente infinito, il che mi fa pensare che JSON sia appropriato per il problema. Il JSON sarebbe solo una singola colonna in una tabella relazionale, che è una piccola parte dei dati nel suo insieme. Mi dispiace per essere stato così vago con questo, ma non riesco a rendere la mia domanda abbastanza specifica da identificare il progetto reale su cui sto lavorando.

Quando ha senso gonfiare i requisiti di archiviazione per semplificare la programmazione e la manutenzione?

    
posta Chris Cirefice 20.12.2016 - 05:51
fonte

5 risposte

4

In primo luogo non dovresti memorizzare il testo JSON in un database relazionale, specialmente se non sei preoccupato dello spazio di archiviazione. Archiviare i dati in tabelle regolari e quindi costruire il JSON quando ne avete bisogno per la comunicazione. Ciò sarà molto più efficiente rispetto all'archiviazione di JSON o del tuo formato dati personalizzato.

Ci sono alcuni casi d'uso in cui potrebbe essere una soluzione appropriata per memorizzare i dati in un formato di testo strutturato (xml, json, csv, qualunque cosa.) in una colonna del database. Ma se ti trovi in un luogo in cui ti preoccupi dei requisiti di archiviazione per vari formati basati su testo, dovresti semplicemente mordere il proiettile e salvare i dati in formato relazionale.

Per quanto riguarda la tua modifica: non esistono dati non strutturati. Se i tuoi dati possono essere espressi in JSON in modo significativo, allora ha una struttura. E se ha una struttura questa struttura può essere espressa in altri formati, inclusi i dati relazionali. JSON è solo un modo particolare per serializzare dati come testo.

    
risposta data 20.12.2016 - 08:29
fonte
3

Il mio principio preferito è "L'ottimizzazione prematura è la radice di problemi disordinati."

Allo stesso tempo, stai memorizzando i tuoi oggetti in json, senza alcun beneficio di flessibilità, taglierà l'architettura anti-pattern di 'resume-buildup before job'.

Nell'analisi pro-con considererò i seguenti punti:

Pro di archiviazione in Json

  • [a] Sviluppo più rapido (facoltativo)
  • [b] Consegna di funzionalità più rapida ai clienti (facoltativo)
  • [c] Debugging più semplice (facoltativo)

Contro di archiviazione in Json

  • [d] Aumento dell'impronta di memoria, che potrebbe scoraggiare alcuni clienti che non dispongono di spazio sufficiente (garantito, ma sarà per lo più una frazione di clienti).
  • [e] Impara / adotta la nuova tecnologia

Quindi ora hai un modo più semplice per determinare:

  1. Se non puoi monetizzare su a, b, c: è giusto decidere di NON usare Json.
  2. Se possibile, esegui alcune analisi su quale percentuale di clienti è probabile che non utilizzi un'applicazione a causa dell'impronta di memoria. Bonus se trovi ciò che i clienti saranno molto infastiditi a causa dell'impronta più elevata. Cerchiamo di quantificarlo come N%.
  3. Se stai eseguendo la tua app su tostapane / IoT e la maggior parte dei clienti se ne andrà se aumenti l'ingombro, allora NON sai di usare Json.
  4. Ora siamo su un terreno in cui N% è abbastanza piccolo. Ora hai un dibattito con il prodotto (o nella tua mente :)), vale la pena fornire più rapidamente le funzionalità o essere in grado di eseguire il debug dei problemi più velocemente?

Alla fine di questo viaggio dovresti avere la tua risposta.

    
risposta data 20.12.2016 - 06:37
fonte
1

Dovresti comunque passare a qualsiasi tipo di standard solo per poter accedere ai tuoi dati anche da altri client rispetto alla tua attuale applicazione principale! Pensa a una riscrittura, a una seconda app che esegue analisi utilizzando i dati o solo a qualcuno che desidera accedere direttamente al database per indagare su un bug.

Se memorizzi solo piccole parti dei tuoi dati che hanno una relazione con altre parti del modello relazionale, è valido archiviare questi documenti in qualche modo nello stesso database. Suppongo che tu usi una colonna VARCHAR, TEXT o BLOB / CLOB di grandi dimensioni (per la maggior parte dei database VARCHAR è più veloce di qualsiasi tipo di tipo LOB ma in genere limitato (a una lunghezza compresa tra 2000 e 65000 caratteri a seconda del fornitore) e anche LOB i tipi normalmente non supportano alcuna funzionalità di query).

Ecco alcune opzioni:

JSON semplice : leggibile, facile da migrare, mappatura diretta alla struttura dati esistente, supporto multi lingua, grande quantità di dati

JSON binario ( BSON ): come JSON semplice, ma più piccolo

Protobuf ( Google ): più piccolo di BSON ma meno supporto linguistico, è necessario possedere modello con mappatura a causa della proto specification (schema)

MessagePack : più piccolo di BSON (come Protobuf) ma più veloce e senza schema

JSON compresso (tramite zip): piccolo e facile da migrare ma prestazioni scadenti

Se si utilizza una colonna LOB, le prestazioni sono comunque fuori ambito e si può andare a JSON compresso. Se hai bisogno di interrogare (WHERE JSON LIKE '...') sei legato ad un formato di testo normale, ma non dovrebbe stampare bene. Se hai bisogno di un'integrazione perfetta ma di piccole dimensioni, vai su MessagePack.

    
risposta data 20.12.2016 - 16:24
fonte
0

Penso che ci siano due parti (molto correlate) a questa domanda:

  1. Devo memorizzare "oggetti di grandi dimensioni" nel database
  2. Quale formato dovrei memorizzare i dati in

La prima parte è primaria perché se la risposta è no, la seconda parte è irrilevante. Se mi avessi chiesto qualche anno fa, direi "certo, perché no?" Ma da allora le mie esperienze sono state che memorizzare dati di oggetti di grandi dimensioni in un database non è ottimale nella migliore delle ipotesi e può essere davvero problematico. Il motivo principale è che il modello concettuale alla base dei database non include realmente questo tipo di dati. Se vuoi inserire elementi in un RDBMS, idealmente, lo inserisci come dati relazionali. Questo è l'unico modo per ottenere il valore reale da RDMBS. Sì, ci sono fantastici tipi di dati che comprendono cose come XML e JSON ma, ancora una volta, questi sono al di fuori del modello relazionale concettuale e sono non standard.

Nel mondo reale, lo facciamo perché è facile e spesso il database è l'unica cosa che è lì che possiamo facilmente leggere e scrivere dati da e possiamo trovarlo usando la chiave relazionale. Ciò che non riesco a superare è che quando lo facciamo, lo usiamo come un hash glorificato. Il tuo database è probabilmente il componente più gravoso della tua architettura. È discutibile caricarlo con un lavoro per il quale non è specializzato. Ecco un pensiero: aggiungi un database o un sistema di archiviazione alla tua architettura progettata specificamente per contenere flussi di byte. Memorizza UUID per tali flussi nel tuo DB. Forse è eccessivo per le tue esigenze, ma vale la pena considerare.

Se decidi di inserire i dati JSON nel database, probabilmente dovresti usare GZIP. Ciò consentirà di risparmiare spazio e creare meno stress sul RDBMS e (un po 'in modo uni- forme) può migliorare le prestazioni. Il motivo per cui può essere più veloce è che comprimendo i dati, hai meno IO del disco. I risparmi sui tempi di I / O possono facilmente superare i tempi necessari per comprimere e decomprimere. È anche possibile eseguire lo streaming dei dati compressi direttamente al client poiché si tratta di un algoritmo di compressione quasi universalmente supportato.

Potresti guardare ad altre strutture ma probabilmente non diventerai molto più stretto di quanto lo comprimeresti e aggiungerà molta complessità. Se passerai a tutto ciò, potresti anche normalizzarlo.

    
risposta data 20.12.2016 - 17:57
fonte
0

Se hai una vasta gamma di dizionari con una struttura identica, puoi trasformarla in un dizionario di array. Prendi il tuo esempio

[
    {
        "id": 123
        "description": "description of data"
    },
    {
        "id": 456
        "description": "description"
    }
]

e trasformalo in

{
    "ids": [123,456],
    "descriptions": ["description of data","description"]
}

Un altro dizionario nell'originale si trasforma in valori giusti, con l'unico overhead costituito da una virgola come separatore. Se ci sono valori mancanti, puoi ovviamente aggiungere valori nulli.

Ora l'accesso ai tuoi dati tramite JSON (analizzato in dizionari, array, ecc.) è ovviamente privo di senso - in genere hai una serie di dizionari, ogni dizionario noto per rappresentare un'istanza di qualche classe e hai un costruttore che gira un dizionario in un'istanza (o in mancanza). Lo sostituiresti con un metodo di classe che trasforma un dizionario di array in una serie di istanze che di solito è ciò che vuoi comunque.

    
risposta data 21.12.2016 - 00:06
fonte

Leggi altre domande sui tag