L'archiviazione di un elenco di stringhe nel campo di un singolo database non è una buona idea? Perché?

6

Recentemente, ho iniziato a lavorare su un sistema legacy. Le persone che lo hanno sviluppato, hanno avuto l'idea di memorizzare l'elenco delle stringhe in un singolo campo della tabella del database. Diciamo che è un identificatore per l'oggetto che non ha alcuna rappresentazione né dati nel database. L'intervallo di tali identificatori sarà relativamente piccolo nella produzione.

D'altra parte, le mie intuizioni e il mio "buon design" mi dicono che dovrebbe essere rappresentato in una tabella separata (simile a una tabella usata per rappresentare relazioni molti-a-molti).

Il loro approccio è davvero pessimo e sarebbe meglio iniziare un refactoring? Se sì, quali sono le cattive conseguenze che il design originale può causare in futuro? Ci sono dei principi di progettazione relazionale che spiegano questo approccio?

Modifica in risposta per i commenti:

Come suppongo, non hanno usato questo approccio per risolvere alcuni problemi specifici come la strutturazione gerarchica in un modo complicato. Lo scenario più probabile era che stavano semplicemente lavorando sotto la pressione del tempo e avevano bisogno di implementare nuove funzionalità il più rapidamente possibile.

Sono sicuro che in precedenza il campo rappresentava un singolo valore. Avrebbero implementato la funzione per archiviare più di un valore e cercato di evitare le migrazioni del database.

    
posta mpasko256 10.10.2017 - 18:35
fonte

4 risposte

13

La datamodel non è normalizzata; per essere così avrebbe bisogno di un tavolo separato come dici tu. A tale riguardo, non è particolarmente buona pratica di datamodelling.

Se è stato fatto per una buona ragione o no è difficile da determinare. È plausibile che la semplificazione o la performance della codifica siano state motivazioni. È probabile che il campo contenesse originariamente un identificatore, i requisiti siano cambiati e gli sviluppatori non avessero tempo o inclinazione a rifare il fattore.

Probabilmente più importante è se tu debba o meno refactoring te stesso. In circostanze simili, non rifarei preventivamente un caso come questo di default. Lo considererei se venisse applicata una delle seguenti:

  1. hai la prova che questo causa problemi ad es. dai log dei fascicoli precedenti
  2. sai per certo che realizzerai cambiamenti funzionali in quell'area
  3. il codice che gestisce i dati è particolarmente complesso e difficile da ragionare.

Che cosa farei, e TBH lo consiglierei ogni volta che acquisirai un'applicazione legacy, inizierò una wiki (o equivalente) e documenterò casi come questo. Ad esempio,

  • problemi che hai riscontrato come la ruga della codifica dei dati
  • modifiche che intendi implementare
  • modifiche che non pianifichi di implementare, ma lo farebbero se ci fosse tempo
  • aree di codice difficili da ragionare
  • aree di codice che hai trovato difficili da mantenere.

Ho scoperto che questo è un memorandum di aiuto utile per me mentre lavoro e / o ritorno a un codice base. Può anche essere molto utile per il tuo successore quando, a sua volta, ha bisogno di iniziare ad imparare il codice base.

    
risposta data 10.10.2017 - 19:29
fonte
7

Is storing a list of strings in single database field a bad idea?

Generalmente sarebbe considerata una violazione della normalizzazione.

Tuttavia, a volte viene utilizzata una soluzione a un problema, ad es. nella strutturazione gerarchica, dove una stringa di percorso di lunghezza variabile di qualche tipo rappresenta la struttura.

Tra i problemi con un elenco di elementi in una singola stringa può essere:

  • nella query, questo significa utilizzare le ricerche di stringhe invece del calcolo relazionale; indicizzare i dati può essere problematico.
  • c'è la domanda sul significato dell'ordine delle voci nella lista, e che più probabilmente non puoi imporre nulla sull'ordinazione come vincolo sul db.
  • c'è il problema del carattere separatore e il potenziale per il carattere che sfugge / non sfugge ai problemi con i singoli elementi.
  • esiste il potenziale per voci duplicate nella stessa lista; ancora una volta ciò deriva dal non essere in grado di forzare direttamente i vincoli (anche se forse una funzione di innesco può controllare i vincoli).
  • un singolo elemento da solo è ancora un elenco, ma potrebbe essere confuso poiché non possiamo dire (o chiedere) al database che il vero tipo è un elenco. Questo può essere problematico se la maggior parte delle righe ha un solo elemento nell'elenco, quando alcuni ne hanno più di uno: non c'è modo di far rispettare l'uso corretto della colonna come un elenco.
risposta data 10.10.2017 - 19:18
fonte
2

È un antipattern comune fare questo.

I tuoi requisiti cambiano e ora hai bisogno di più valori in un posto in cui ne hai solo bisogno. Come un libro ha un solo autore giusto? Chi avrebbe mai immaginato che un libro avesse più autori? Questo è un modo semplice per soddisfare questa modifica dei requisiti senza dover modificare lo schema del database.

Tuttavia ci sono alcuni aspetti negativi.

  • Le query diventano più difficili perché ora hai i dati di identificazione combinato in 1 campo.
  • Non puoi più usare "=" ma devi usare qualcosa come "mi piace". Quale ucciderà la prestazione.
  • Si perde il possibilità di unirsi in quel campo.
  • Prova conteggio / somma ecc., non funzionerà.
  • Aggiornamento, diventa imbarazzante.
  • Hai dei limiti artificiali perché tu scegli un varchar (10) per contenere la tua lista separata.
  • e altro ancora

Quindi in pratica, per favore non farlo.

Fondamentalmente stai eliminando il "relazionale" in "database relazionale".

    
risposta data 11.10.2017 - 14:01
fonte
0

Ci sono molti argomenti per il nostro essere già una cattiva idea. Penso che sarebbe giusto aggiungere alcune ragioni per cui sarebbe una buona idea, o almeno OK. Non sei sicuro di quanti di questi casi applichino specificamente intis, ma sembra che almeno le osservazioni sulle prestazioni fatte siano rilevanti:

  • se i numeri e la lunghezza delle stringhe sono strettamente limitati, la differenza di prestazioni dovrebbe essere trascurabile. Almeno per alcuni casi limite, le prestazioni saranno migliori, in quanto non è necessario il join.
  • a seconda dell'uso principale del campo, questo modulo potrebbe essere più facile da gestire.
  • se l'elenco è ordinato e i dati non richiedono chiavi esterne, i campi elenco sono di gran lunga superiori a qualsiasi database relazionale possa fornire a tale riguardo.
  • essere semplici salvadanai sul campo singolare esistente può essere una scelta prudente nei sistemi in cui la migrazione dello schema è costosa. È certamente un debito tecnico, ma potrebbe essere il tipo che vale la pena di prendere e non rimborsare mai, anche se è necessario che tu abbia un interesse di tanto in tanto.

Quando si tenta un refactoring, è sempre una buona idea prima capire la ragione dietro le scelte progettuali precedenti. Assicurati che le condizioni e i requisiti siano effettivamente cambiati abbastanza da giustificare costi e rischi.

    
risposta data 19.12.2018 - 17:36
fonte