Il modo migliore per modellare un singleton in un database relazionale

11

Quando si progetta uno schema di database relazionale per applicazioni web, trovo spesso un caso in cui finisco per creare una tabella solo per contenere una riga e solo una riga. Sembra che sia il modo sbagliato di progettarlo, ma non riesco a trovare nulla di significativamente migliore, o ovviamente "il modo giusto per farlo".

Un esempio recente è un sito che consente agli utenti di controllare manualmente il contenuto sulla home page. Bene, c'è solo una pagina iniziale. Ho creato una tabella con tutti i campi necessari per creare la home page, ad esempio un campo di testo per un'area che conteneva testo descrittivo. Un campo per memorizzare il nome di un grande file immagine. Alcune chiavi esterne che rimandano agli articoli presenti nella home page, ecc. Funziona, ma è sbagliato avere una tabella con una sola riga.

In passato ho provato molti altri progetti, come ad esempio consentire più righe nella tabella della home page e selezionarne una a caso. Ho provato ad aggiungere un campo booleano denominato "attivo" e selezionare una delle home page attive a caso. Ho provato a forzare solo una riga ad essere attiva in qualsiasi momento nella logica dell'applicazione. Non ho nemmeno provato a creare una tabella della home page e ad avere tutti gli altri elementi, come gli articoli, per avere campi booleani con nomi come featured_on_homepage.

Nella maggior parte dei casi potrei creare la homepage con un gruppo di costanti in un file di impostazioni. Il problema principale con il file delle impostazioni è che è sotto il controllo dello sviluppatore. Perché qualcosa come il contenuto della homepage è qualcosa che deve essere modificato dall'utente, deve andare nel database.

Su molti siti, non ho questo problema perché posso costruire cose come la homepage con una query come selezionare i cinque articoli più recenti. Ma quando ho pagine che sono curate manualmente con requisiti rigorosi, diventa complicato modellarla nel database. Ma immagina di avere un tavolo fotografico e un tavolo di articoli. Il requisito è che nella home page vengano visualizzate esattamente cinque foto, esattamente tre articoli e due blocchi di testo arbitrario controllati manualmente dall'utente. Come si modella quello nel database nel modo giusto?

Inoltre, ho questo problema di modellazione in molti altri casi oltre alle home page. È solo l'esempio più facile e generalmente applicabile che potrei trovare.

    
posta Apreche 17.12.2010 - 14:15
fonte

8 risposte

10

Un approccio semplice sarebbe quello di salvare le proprietà della Home Page in una tabella Proprietà (o chiamarla qualcos'altro) che è composta da Nome & Colonne di valore.

HomePageProperty1 - UserValue1

HomePageProperty2 - UserValue2

Potrebbe non essere una soluzione ideale, ma è semplice e flessibile. Elimina anche la tabella con uno scenario di fila.

    
risposta data 17.12.2010 - 14:28
fonte
3

Non mi è chiaro che tu abbia un problema che devi risolvere.

Una tabella a riga singola non è in alcun modo un problema per il database stesso e consente di applicare tipi di dati e vincoli ai dati.

Non sono sicuro che tu stia cercando di risolvere un problema reale, per essere onesti.

    
risposta data 01.06.2017 - 19:08
fonte
2

Non c'è assolutamente niente di sbagliato in una tabella con una riga.

Se questo fa parte del tuo progetto, dovresti applicarlo. Assegna alla tabella una colonna Identity, assegna un vincolo di univocità, quindi aggiungi un vincolo di colonna per consentire solo un singolo valore. Questo assicurerà che nessuno sarà in grado di aggiungere una seconda riga, il che potrebbe essere catastrofico se le istruzioni SQL che leggono la tabella (comprensibilmente) non hanno una clausola where.

Se inizi a ricevere un numero elevato di colonne, potresti essere tentato di restringere la tabella e invece avere una riga per elemento di configurazione. Questa non è l'idea migliore perché perdi la sicurezza e la convalida del tipo. Inoltre, potresti perdere la compatibilità con multi-tenancy , che potrebbe essere importante per te. Una soluzione migliore sarebbe quella di ripensare ciò che sono realmente le entità e disporre di tabelle a riga singola separate per entità diverse.

Sì, non sto solo dicendo che una tabella a riga singola è OK, ma sto suggerendo che potresti volerne più di una.

    
risposta data 01.06.2017 - 21:24
fonte
1

Potresti creare una tabella chiamata STATIC_CONTENT e avere colonne per una chiave così come il contenuto, tracker attivi / inattivi, ecc. Quindi, creare una riga con una chiave di "HomePage" e nella tua homepage, caricare il contenuto statico per quella chiave e visualizzarla. In questo modo, quando hai altri contenuti statici (sulla pagina, sulla pagina di contatto e così via), puoi aggiungere righe a quella tabella.

    
risposta data 17.12.2010 - 14:38
fonte
1

Mi sembra che tu stia utilizzando un database per qualcosa che dovrebbe essere effettivamente archiviato come un file.

La tua descrizione mi ricorda un sacco di pagine Wiki, dove gli utenti possono modificare il contenuto. In Wiki, o almeno nelle implementazioni che ho visto, le pagine sono mantenute come file.

Questo ti aiuta con altri dettagli web come consentire agli utenti di memorizzare nella cache la tua home page, che viene praticamente gratis se si archiviano le pagine come file, ma si dovrebbe implementare manualmente la logica per l'invalidazione della cache se si ' ri costruire la pagina su ogni richiesta in base al contenuto memorizzato nel database.

In ogni caso, voglio solo chiarire che anche se la maggior parte dei dati persistenti di un'applicazione è archiviata in un database, ciò non significa che dobbiamo memorizzare tutto lì. I database sono solo uno degli strumenti del nostro commercio. Dobbiamo imparare a fare buon uso del maggior numero di strumenti diversi che possiamo.

    
risposta data 01.06.2017 - 05:05
fonte
1

Non c'è nulla di sbagliato di per sé nell'avere una tabella con una sola riga. Se hai sempre una sola istanza di una certa entità, allora potrebbe essere il modo più naturale per rappresentarla.

Ma selezionare una riga in modo casuale è sbagliato e sbagliato. Se la tua logica di dominio si aspetta solo una singola riga, è ovvio che si tratta di un errore nei dati se ce ne sono effettivamente di più. Quindi dovresti capire chi o cosa sta scrivendo dati non validi nel database e impedirgli di farlo! A seconda del database, potresti probabilmente aggiungere un vincolo alla tabella per evitare che ciò accada in primo luogo, ad es. consentendo solo un valore particolare come chiave primaria.

    
risposta data 01.06.2017 - 20:09
fonte
0

Solo per aggiungere a Walter ..

La struttura della tabella delle proprietà dovrebbe consentire più tipi di dati.

Fileds:
PropertyName
PropertyTextValue
PropertyDateValue
PropertyNumericValue
PropertyBoolValue
    
risposta data 17.12.2010 - 14:35
fonte
0

Mi sembra che tu abbia potuto astrarre un livello in più. Alla fine una "HomePage" è una "Pagina". Puoi avere diversi tipi di pagine con le proprietà di cui hai bisogno. Se avessi sezioni nel tuo sito, probabilmente avresti bisogno di una "SectionHomePage", che può benissimo funzionare come una "Home Page".

The requirement is that the homepage will display exactly five photos, exactly three articles, and two blocks of arbitrary text manually controlled by the user. How do you model that in the database the right way?

Proviamo in questo modo. Sto aggiungendo una tabella ArticlePage in modo da vedere come è possibile separare le proprietà di conseguenza.

PAGES
Id
Title
Description

HOMEPAGES
PageId (FK)
PhotoListLimit
ArticleListLimit
TextBlockListLimit

ARTICLEPAGE
PageId (FK)
ArticleMainQuote
ArticleMainBody
ArticlePhoto1
ArticlePhoto2

Funzionerebbe bene per me, funzionerebbe egregiamente per un grande sito.

    
risposta data 31.05.2017 - 23:41
fonte

Leggi altre domande sui tag