Come memorizzare raccolte di oggetti Testo collegati nel database

1

Sto scrivendo un programma Java che funziona come presentazione di un documento scritto, che deve essere archiviato in un database (sto usando MySQL, ma sono aperto a suggerimenti di altri tipi di DB).

La classe Essay è una raccolta di oggetti della classe Paragraph (più specificamente Essay extends LinkedList<Paragraph> , costituita principalmente da int ID e String content . L'oggetto Essay è memorizzato come propria tabella nel DB, che è abbastanza semplice (con colonne int paragraphId e Blob text ), e faccio una semplice query che crea un nuovo oggetto Paragraph per ogni riga nella tabella quando il programma viene inizializzato.

All'interno di ciascun paragrafo, alcune parole con collegamenti ipertestuali si collegano ad altri oggetti Essay, che devono anche essere memorizzati nel database. La mia domanda è il modo migliore per salvarli: le opzioni che sto considerando sono:

  • Creazione di una singola tabella DB aggiuntiva in cui ogni testo è archiviato su una riga, con i paragrafi memorizzati in un singolo oggetto di testo separati da un delimitatore e il programma li separa in un oggetto Paragrafo separato mentre li estrae dal DB. (Questo è abbastanza gestibile perché questi saggi collegati sono molto più brevi del saggio principale).
  • Crea una singola tabella aggiuntiva, con un numero elevato di colonne di contenuto, memorizzando ogni paragrafo in una colonna separata. Quindi, quando i dati vengono estratti dal database, crea un nuovo saggio per ogni riga e un nuovo paragrafo per ogni colonna in quella riga, finché non ne giunge uno che è nullo.
  • Crea dinamicamente una tabella DB separata per ciascun saggio collegato, impostandolo in modo identico a quello principale. Questo non sembra ideale perché finirebbe per essere un numero molto grande di tavoli, e molti di loro avrebbero solo due o tre paragrafi, facendo sembrare un nuovo tavolo dispendioso.
  • Esegui un arrangiamento diverso: disponi di una tabella di paragrafi, in cui sono memorizzati tutti i paragrafi di tutti i saggi e un'altra tabella denominata Essays, che utilizza un tipo di dati SET per memorizzare gli ID (chiavi esterne) dei paragrafi inclusi in ogni tema.

Ho modificato qui il mio caso di utilizzo effettivo per renderlo più semplice da spiegare. Sono nuovo nella programmazione di database e lo sto facendo principalmente come esercizio, quindi sono alla ricerca di suggerimenti generali sui pro / contro di questi approcci e su eventuali suggerimenti aggiuntivi.

    
posta drewmore4 12.12.2013 - 10:16
fonte

4 risposte

4

Ciò che descrivi non sembra adatto per un database SQL.

Fondamentalmente, quello che hai è un grafico di documenti, li memorizzerei in un database dei documenti (ad es. Cassandra , CouchDB , MongoDB , Redis ) o un database grafico (ad esempio Neo4J ), a seconda di come si desidera attraversare / interrogare i dati. (O forse anche entrambi: memorizza i documenti in un database di documenti e la struttura del grafico in un database grafico, in questo modo puoi attraversare il grafico nel database grafico, che è quello a cui sono abituati, e quindi recuperare il documento dal documento database, che è ciò che sono bravi a.)

Esistono anche database come ArangoDB che combinano un modello di archiviazione orientato al grafico, orientato al documento e basato su valori chiave in un singolo banca dati.

Questa idea di scegliere un modello di database che si adatta alla forma dei tuoi dati invece di cercare di adattare alla perfezione la forma dei tuoi dati in modo che corrisponda al modello di database (SQL) ha raccolto molta attenzione negli ultimi 10 anni circa ed è noto come NoSQL (non solo SQL) . Notare che NoSQL non significa che non si dovrebbe usare SQL. Significa che dovresti usare SQL quando è lo strumento giusto per il lavoro, cioè quando i tuoi dati sono in realtà a forma di tabella e relazionali.

    
risposta data 12.12.2013 - 11:16
fonte
1

Ci sono problemi con ciascuna delle prime tre opzioni.

La memorizzazione dell'intero testo in una colonna può funzionare, ma può diventare inefficiente a seconda di quanto sono grandi e quanti sono i tuoi paragrafi, se vuoi sempre recuperare tutti i paragrafi di un tema o forse solo alcuni di essi, ecc. Un distinto la tabella per i paragrafi collegati a saggi tramite chiavi esterne è spesso il modo migliore per andare.

L'inserimento di paragrafi successivi in colonne adiacenti di una tabella è una cattiva idea. Bisogna pronosticare quanti paragrafi possono esistere, quindi fornire molta memoria per ogni saggio , gran parte dei quali andranno sprecati, solo per scoprire che si è sottovalutato e si deve modificare lo schema nella produzione, o introdurre limiti indesiderati che sembrano totalmente arbitrari per gli utenti (perché lo sono). Inoltre, dovrai generare dinamicamente almeno parte delle query a seconda di quante di queste colonne ci sono, il che apre più lattine di worm meglio lasciati chiusi.

Creare una nuova tabella per ogni saggio collegato è ancora peggio. Qualsiasi soluzione che richieda di modificare non solo le definizioni della tabella ma l'insieme di tabelle esistenti nello schema solo perché un utente ha inserito nuovi dati è, nel migliore dei casi, un profondo fraintendimento di ciò che i database relazionali sono per. può lavorare con una piattaforma senza schema (solitamente chiamata "NoSQL", ma la differenza decisiva è la mancanza di uno schema relazionale, non la sintassi della query), ma non ho esperienza sufficiente qui per ti consigli su come e quando.

L'opzione 4 è ciò che farei, ma invece di mantenere un insieme di chiavi esterne, che introduce tutti i problemi di più colonne in miniatura, vorrei fare riferimento ai paragrafi che rimandano a saggi tramite una chiave esterna. Se il tuo database è troppo inefficiente per eseguire il JOIN necessario per ricostruire un intero saggio, allora probabilmente qualcos'altro è sbagliato oltre all'organizzazione dei tuoi dati - i database sono stati ottimizzati esattamente per questo compito per decenni, quindi sarebbe molto sorprendente se questo fosse davvero il fattore limitante.

    
risposta data 12.12.2013 - 11:16
fonte
0

Dovrebbe esserci una tabella per ogni tipo di entità: Saggio e Paragrafo. Suppongo che i saggi abbiano un identificatore esterno a cui fanno riferimento i collegamenti ipertestuali che chiamerò essay_name per questo esempio. Sembra che tu abbia bisogno anche di un attributo per indicare qual è il saggio "primario". In pseudo-DDL:

CREATE TABLE Essay (
    essay_id INT NOT NULL, 
    essay_name TEXT -- ...,
    is_primary BOOLEAN NOT NULL,
    PRIMARY KEY (essay_id)
)

Un paragrafo ha una relazione molti-a-uno con un saggio (tramite la colonna essay_id ). Deve anche avere un modo per rappresentare l'ordine dei paragrafi all'interno di un tema. Nell'esempio seguente viene utilizzato position per acquisire l'ordinamento dei paragrafi.

CREATE TABLE Paragraph (
    paragraph_id INT NOT NULL,
    essay_id INT NOT NULL,
    position INT NOT NULL,
    content TEXT,
    PRIMARY KEY (paragraph_id),
    FOREIGN KEY (essay_id) REFERENCES Essay (essay_id)
)
    
risposta data 16.12.2013 - 17:22
fonte
0

Nell'elaborazione semantica, vengono create annotazioni generate automaticamente che si riferiscono a un particolare blocco di testo. Le annotazioni darebbero sapore al contesto di singole parole o frasi all'interno del blocco di testo. Le frasi sono state contrassegnate con idee come "città" o "dipartimento governativo" o "campo medico". Anche se questo non è esattamente quello che stai facendo, l'idea è la stessa: come si relazionano le informazioni aggiuntive associate a un blocco di testo.

I blocchi di testo sono stati memorizzati in una singola tabella con un ID generato automaticamente per ogni riga. Le annotazioni sono state memorizzate in una tabella separata che ha fatto riferimento all'ID. I campi che aveva erano: major_type, minor_type, start, end e value. L'inizio e la fine erano numeri che indicavano i numeri di carattere all'interno del blocco di testo. "Il desktop era grande" annotava il desktop come un "oggetto fisico", "mobili", 4, 10, "desktop". Ha usato i valori dei caratteri per fare riferimento ai dettagli annotati. Anche se potrebbe non essere l'ideale, è un modo in cui un sistema reale ha fatto qualcosa di simile.

Se fossi in te, considererei strongmente un linguaggio di markup per modificare il testo per includere i collegamenti. Il riferimento al personaggio sembra facile da rompere. Dipende davvero dai tuoi dati, dalla frequenza con cui viene aggiornato o da quanto controllo hai su di esso.

Spero che questo sia stato di aiuto!

    
risposta data 16.12.2013 - 19:35
fonte

Leggi altre domande sui tag