Il modo migliore per modellare un singleton in un database relazionale


12

Quando progetto 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 qualcosa di significativamente migliore, o che è ovviamente "il modo giusto di farlo".

Un esempio recente è un sito che consente agli utenti di controllare manualmente i contenuti sulla home page. Bene, c'è solo una home page. Ho creato una tabella che aveva tutti i campi necessari per costruire la homepage, come un campo di testo per un'area che conteneva testo descrittivo. Un campo per memorizzare il nome di un file immagine di grandi dimensioni. Alcune chiavi esterne che puntano ad articoli che saranno presenti sulla homepage, ecc. Funziona, ma sembra sbagliato avere una tabella con una sola riga.

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

Nella maggior parte dei casi ho potuto 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 creare 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 difficile modellarlo nel database. Ma immagina di avere un tavolo per le foto e un tavolo per gli articoli. Il requisito è che la homepage visualizzi esattamente cinque foto, esattamente tre articoli e due blocchi di testo arbitrario controllati manualmente dall'utente. Come modellarlo nel database nel modo giusto?

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


Non è affatto chiaro quale problema ti presenti la tabella a riga singola, a parte il fatto che in qualche modo rappresenta uno spreco di una tabella. Sei sicuro di provare a risolvere un problema di cui effettivamente soffri?
David Aldridge,

Risposte:


10

Un approccio semplice sarebbe quello di salvare le proprietà della Home Page in una tabella Proprietà (o chiamarla in altro modo) che è composta da colonne Nome e Valore.

HomePageProperty1 - UserValue1

HomePageProperty2 - UserValue2

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


1
Questo approccio funziona per molteplici scopi. Ad esempio, memorizzerò le informazioni sulla versione dello schema, i puntatori di rotazione per le cose che devono essere ciclicate quotidianamente, ecc. Le informazioni sulla versione dello schema sono importanti quando si diagnostica ciò che è andato storto. È un modo ragionevole per garantire l'applicazione di una patch per una correzione del solo database.
Berin Loritsch,

2
+1 - Questo è il layout esatto della tabella che il nostro Data Architect mi ha dato per uno scopo simile.
Ali,

3
Il problema con questo approccio è che è necessario rappresentare diversi tipi di variabili come colonne diverse e disporre di una logica che indichi quale colonna utilizzare e quali sono obbligatori. Non puoi definire che un valore booleano sia booleano o che una data sia una data o che un determinato attributo non possa essere nullo o debba rientrare in un determinato intervallo o soddisfare una condizione - tutte cose banalmente semplici con una tabella a riga singola.
David Aldridge,

3

Non mi è chiaro che hai un problema che devi risolvere.

Una tabella a riga singola non costituisce 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 vero problema, a essere sincero.


2

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

La tua descrizione mi ricorda molte pagine Wiki, in cui 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 è praticamente gratuita se memorizzi le pagine come file, ma dovresti implementare manualmente la logica per invalidare la cache se stai costruendo il pagina su ogni richiesta basata sul contenuto archiviato 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 archiviare tutto lì. I database sono solo uno degli strumenti del nostro commercio. Dobbiamo imparare a fare buon uso di quanti più strumenti possibili.


2

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

Se questo fa parte del tuo progetto, dovresti applicarlo. Assegna alla tabella una colonna di identità, assegnagli un vincolo di unicità, quindi aggiungi un vincolo di colonna per consentire un solo valore. Ciò garantirà che nessuno sarà in grado di aggiungere una seconda riga, il che potrebbe essere catastrofico se le istruzioni SQL che leggono la tabella (comprensibilmente) mancano di una clausola where.

Se inizi a ottenere un numero elevato di colonne, potresti essere tentato di restringere la tabella e avere invece una riga per elemento di configurazione. Questa non è la migliore idea perché perdi la sicurezza e la convalida del tipo. Inoltre, perderai la compatibilità diretta con la multi-tenancy , che potrebbe essere importante per te. Una soluzione migliore sarebbe quella di ripensare a cosa sono realmente le tue entità e di avere 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.


1

Puoi creare una tabella denominata STATIC_CONTENT e avere colonne per una chiave, nonché contenuto, tracker attivi / inattivi, ecc. Quindi, crea una riga con una chiave di "HomePage" e nella tua home page, carica il contenuto statico per quella chiave e visualizzalo. In questo modo, quando hai altri contenuti statici (su pagina, pagina di contatto, ecc.), Puoi aggiungere righe a quella tabella.


1

Di per sé non c'è nulla di sbagliato nell'avere una tabella con una sola riga. Se hai solo un'istanza di una determinata entità, allora potrebbe benissimo essere il modo più naturale di rappresentarla.

Ma selezionare una riga in modo casuale è sbagliato e negativo. Se la tua logica di dominio prevede solo una singola riga, è ovviamente 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 impedire loro di farlo! A seconda del database, è possibile probabilmente aggiungere un vincolo alla tabella per evitare che ciò accada in primo luogo, ad esempio consentendo solo un determinato valore come chiave primaria.


0

Solo per aggiungere a Walter ..

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

Fileds:
PropertyName
PropertyTextValue
PropertyDateValue
PropertyNumericValue
PropertyBoolValue

In questo modo, come si garantisce che sia impostato un solo valore di proprietà per riga? È abbastanza facile applicarlo nell'applicazione, ma cosa succede se qualcuno aggiorna manualmente il database e inserisce alcuni dati?
Apreche,

0

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

Il requisito è che la homepage visualizzi esattamente cinque foto, esattamente tre articoli e due blocchi di testo arbitrario controllati manualmente dall'utente. Come modellarlo nel database nel modo giusto?

Proviamo così. 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 anche benissimo per un grande sito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.