Domanda

Ho un'applicazione con molte relazioni di database che dipendono l'una dall'altra per far funzionare correttamente l'applicazione. Il cardine nell'applicazione è un modello chiamato Schedule, ma il programma attirerà Blocks, un Employee, un JobTitle e un Assignment (in aggiunta a ciò, ogni Block estrarrà un compito dal database insieme a esso) per assemblare un programma dei dipendenti durante il giorno.

Quando ho creato l'app, ho posto molta enfasi sulle convalide che avrebbero assicurato che tutti i pezzi dovevano essere a posto prima che tutto fosse salvato nel database. Finora ha funzionato in modo fantastico e l'app è stata live e martellata per quasi 6 mesi, servendo circa 150.000 richieste al mese senza singhiozzi o errori. Fino alla settimana scorsa.

La settimana scorsa, mentre qualcuno stava modificando una pianificazione, sembra che il database sia errato e una Pianificazione è stata salvata nel database con l'assegnazione mancante. Poiché l'associazione viene richiamata in ogni vista, ogni volta che questa pianificazione veniva richiamata dal database, l'applicazione generava un errore NoMethod per la chiamata su zero.

Durante la progettazione di un'applicazione secondo le mie indicazioni, ti proteggi da un possibile errore da parte del database / delle convalide? E se sì, come si difende programmaticamente da esso? Controlli ogni relazione per accertarti che non sia nulla prima di inviarlo alla vista?

So che questa domanda è generale in generale, e se posso essere più specifico in ciò che intendo, per favore fatemi sapere nei commenti.

È stato utile?

Soluzione

Consiglierei di aggiungere rinforzato con database vincoli di chiave esterna e che avvolge importanti gruppi di operazioni in transazioni .

Se esiste una chiave esterna tra Pianificazione e Assegnazione da qualche parte, un vincolo di chiave esterna imposto dal database avrebbe impedito l'inserimento errato. Inoltre, se si avvolge la particolare azione in una transazione, si può essere certi che l'intero flusso di inserimenti / aggiornamenti / eliminazioni si verifichi o fallisca, ripristinando uno stato pulito.

Altri suggerimenti

Oltre alle convalide e all'aggiunta di alcuni vincoli del database, come indicato in altre risposte, è anche possibile eseguire un processo in background che spazza periodicamente il database alla ricerca di orfani.

Quando ne trova uno, lo pulisce (se possibile), o lo elimina, o semplicemente lo contrassegna come inattivo e ti invia e-mail in modo da poterlo guardare in seguito. A seconda della quantità e della natura dei tuoi dati, una volta al minuto, una volta all'ora, una volta al giorno ...

In questo modo, se arrivano dati errati nonostante le protezioni che hai messo in atto, lo saprai prima piuttosto che dopo.

Sosterrò la saggezza non convenzionale su questo. I vincoli che descrivi non appartengono al database, appartengono al tuo codice OO. E non è vero che "il database ha errato", è senza dubbio vero che l'applicazione è ciò che ha inserito dati validati in modo errato.

Quando inizi ad aspettarti che il database porti l'onere di questi controlli, stai inserendo le regole di business nello schema. Come minimo, questo rende molto più difficile scrivere test unitari (che è dove probabilmente dovresti averlo preso in primo luogo; ma ora hai la possibilità di aggiungere un altro test.)

Idealmente, dovresti essere in grado di sostituire RDBMS con qualche altro archivio di dati generico e avere comunque tutta la logica funzionale correttamente attiva e invariata negli altri posti appropriati. L'interfaccia utente non dovrebbe parlare con il DAL e tanto meno gestire direttamente le eccezioni del database.

Se lo si desidera, è possibile aggiungere ulteriori vincoli al database, ma dovrebbe essere rigorosamente un backup. Come puoi vedere, gestire gli errori strutturali del database con garbo (specialmente se è coinvolta l'interfaccia utente) è molto più difficile.

Se è qualcosa che deve essere vero per far funzionare l'app, è proprio quello a cui servono assert () . Ho appena usato Ruby, ma immagino che debba avere quel concetto. Usali per applicare le precondizioni in vari punti del codice. Ciò combinato con la sanificazione e la convalida degli input esterni (utente) dovrebbe essere sufficiente per proteggerti. Penso che se qualcosa va storto dopo tale quantità di controllo, la tua app può essere arrestata correttamente (in modo controllato, ovviamente).

Dubito che il problema riscontrato sia un errore nel database. Più probabilmente c'è un caso limite nelle tue convalide che hai trascurato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top