Sostituzione di SQL dinamico con una pipeline di filtri?

7

Come parte di un incarico di lavoro ho a lungo affrontato una procedura memorizzata gigante e dinamica per la creazione di SQL che viene utilizzata per recuperare un gruppo di articoli di inventario. Questa stored procedure accetta una tonnellata di parametri (forse come 20+) che, a sua volta, attiva e disattiva l'SQL dinamico generato.

Alla fine eseguiamo tutto questo SQL e generiamo un risultato.

Lo spazio pubblicitario, ovviamente, ha regole speciali su chi può e non può vedere determinati oggetti e quanti oggetti possono ordinare, quel genere di cose. Di conseguenza, gran parte di questa logica viene impostata nella stored procedure.

Come puoi immaginare, con le sue risme di SQL dinamico i programmatori della mia squadra non hanno mai avuto la necessità di cambiare questa dannata cosa.

Dato che consideriamo già la procedura memorizzata come un 'endpoint' (lasciamo che la stored procedure gestisca tutto in modo che non ci sia incoerenza, permettendo ad un utente di vedere gli elementi che non dovrebbero, per esempio), penso che questo sarebbe un ottimo candidato per essere trasformato in un vero e proprio servizio indipendente.

Nella mia mente mi immagino di eliminare la procedura memorizzata e utilizzare invece una selezione diretta in una sorta di lista immutabile sul lato dell'applicazione. Dovremmo quindi generare una serie di filtri che preformeranno lo stesso tipo, filtrando i vari bit dell'SQL dinamico che stanno facendo ora e ottenendo un risultato dall'altra parte.

Ciò che mi dà una pausa, tuttavia sono i seguenti:

  • Credo di essere solo ingenuo sul modo migliore per creare una "catena di filtri" come questa. Siamo prevalentemente un negozio di Java, quindi mi sono certamente occupato dell'applicazione di un Predicate a una raccolta e tutto, ma in genere l'ho fatto con pochi filtri. Esiste un buon esempio del modo migliore per impostare una "pipeline di filtraggio", in cui inizi con un elenco di grandi dimensioni e progressivamente lo abbassi o si tratta solo di avere una lista di filtri gigantesca?

  • Quando penso a quanto sopra, mi sembra che stia semplicemente ricreando SQL in un ambiente non SQL e che sembra male. La nostra piattaforma è SQL Server / TSQL e sembra che la creazione di stored procedure / funzioni che accettano tabelle come input sia, se non disapprovata, non ampiamente praticata.

Fare cose interamente in SQL le rende anche molto difficili da testare, dalla mia esperienza.

Come accennato, siamo prevalentemente un negozio di Java, ma sono aperto a suggerimenti da qualsiasi lingua. SQL Server è un po 'meno malleabile, come puoi immaginare.

Ad ogni modo, questo problema mi ha fatto girare la testa per un anno o più e mi piacerebbe sentire i tuoi pensieri!

    
posta benjamin 11.08.2016 - 22:59
fonte

1 risposta

1

Penso che ci siano due problemi al lavoro qui. Il primo problema è la ricerca e il filtraggio, che in questo caso è probabilmente meglio risolto usando SQL. Il secondo problema è il fatto che avete una complessa logica di business nella stored procedure, che in realtà non vi appartiene.

Si potrebbe iniziare identificando quali parti della procedura memorizzata appartengono al lato SQL e quali parti sono in realtà la logica aziendale. Il filtraggio degli elementi che iniziano con 'sheep' è SQL, non restituendo più elementi di quelli che possono essere ordinati da una vedova scorrevole è la logica di business. (Diamine, non riesco nemmeno a pensare a come potresti avere i due in una singola query SQL e farlo funzionare correttamente ...) Crea una lista di tutte le cose che sono logiche di business e poi sceglierne una su cui lavorare.

Quindi, scrivi un test. Suppongo che tu abbia un codice che a un certo punto restituisce l'elenco degli elementi richiesti e che internamente richiama la stored procedure. Stai per espandere quel codice inserendo un nuovo livello che si prende cura della tua logica aziendale. Probabilmente il tuo test dovrebbe essere sul codice che si trova appena "sopra" dove introdurrai la tua pipeline di filtraggio. Scrivi il tuo test in cima a quel codice. Fai in modo che il test (o i test se ne hai bisogno di più) si occupino dell'unica specifica logica di business che hai scelto.

Successivamente, refactoring. Estrarre il codice SQL dalla stored procedure e scrivere Java per sostituirlo. Un buon modo per farlo sarebbe quello di creare una singola classe per adattarsi alla logica di business su cui si sta lavorando (ad esempio, 'MaximumOrdersPerSlidingWindowLimiter'). Unittest quella classe e fare affidamento sul test scritto sopra per assicurarsi di non rompere nulla. La classe dovrebbe prendere un elenco di elementi e restituire un elenco di elementi. Fai in modo che questa classe estenda un'interfaccia comune a tutte queste piccole classi che creerai. Qualcosa come questo potrebbe essere adatto a te.

Continua a distruggere la procedura memorizzata fino a quando tutta la tua logica di business è Java e tutto ciò che rimane è il vero codice di interrogazione SQL.

    
risposta data 13.08.2016 - 20:05
fonte

Leggi altre domande sui tag