Sto utilizzando SQL UDF per incapsulare la logica di reporting / incassi semplice. Devo evitare questo?

StackOverflow https://stackoverflow.com/questions/2158361

Domanda

Sto costruendo un nuovo database in SQL Server 2008 per qualche segnalazione, e ci sono molte regole comuni di business relative a questi dati che vanno in diversi tipi di rapporti. Attualmente queste regole sono per lo più combinati in programmi procedurali più grandi, in una lingua legacy, che sto cercando di spostare verso SQL. Sto girando per la flessibilità nel reporting attuazione da questi dati, come una segnalazione in SAS, alcuni in C #, ecc.

Il mio approccio al momento è quello di rompere queste regole comuni (di solito molto semplice logica) e di incapsulare in singoli UDF SQL. Le prestazioni non è un problema, voglio solo utilizzare queste regole per compilare i campi statici in una sorta di segnalazione "snapshot", che possono poi essere utilizzati per segnalare da in qualsiasi modo si desidera.

Mi piace questo approccio modulare per quanto capire ciò che ogni regola sta facendo (e mantenere le regole stesse), ma sto anche iniziando a diventare un po 'paura che la manutenzione può anche diventare un incubo. Alcune regole dipendono da altri, ma non può davvero uscire da quella - queste cose costruiscono a vicenda ... che è quello che voglio ... penso? ;)

Ci sono alcuni approcci migliori per questo approccio modulare in un database? Sono sulla strada giusta, o sto pensando di questo in troppo di una mentalità applicazioni di sviluppo?

È stato utile?

Soluzione

SQL è impostato in base, ed esegue intrinsecamente male quando si applica un approccio modulare.
Funzioni, stored procedure e / o Vista - tutti astratto la logica sottostante. Il problema di prestazioni entra in gioco quando si utilizzano due (o più) funzioni / etc che utilizzano la stessa tabella (s). Ciò significa che due interrogazioni sono fatte la stessa tabella (s) in cui si poteva sono stati utilizzati.

L'uso di molteplici funzioni mi dice che il modello di dati è stato fatto per essere molto "flessibile". Per me, questo significa discutibile digitazione dei dati e la definizione complessiva della colonna / tavolo. C'è la necessità di funzioni / etc perché il database consentirà di tutto per essere conservato, il che significa la possibilità di cattivo dati è molto alto. Preferisco mettere lo sforzo in avere sempre dati buoni / validi, piuttosto che lavorare dopo il fatto per combattere i dati cattivi esistente.

La banca dati è il luogo per contenere questa logica. E 'più veloce di codice dell'applicazione, e soprattutto -. Centralizzata per ridurre al minimo maintainence

Altri suggerimenti

A un certo punto, ampio uso di UDF inizierà a causare problemi di prestazioni in quanto vengono eseguiti per ogni riga nel vostro gruppo di risultati e la logica oscura dal ottimizzatore, il che rende difficile utilizzare gli indici (cioè io non capisco come le prestazioni non può essere un problema, ma si sa le vostre esigenze migliori). Per alcune funzionalità sono grandi; ma usarli con parsimonia.

logica Keeping sul lato database è quasi sempre una cosa giusta da fare.

Come lei ha ricordato nella sua interrogazione, la maggior parte delle regole di business coinvolgono logica molto semplice ma di solito si occupa di enormi volumi di dati.

Il motore di database è la cosa giusta per implementare questa logica perché, in primo luogo, mantiene I/O dati al minimo, e, dall'altro, di database esegue trasformazioni mosts dati in modo più efficiente.

Qualche tempo fa ho scritto un post molto soggettivo su questo argomento:

Una nota a margine: a. UDF non è lo stesso di una stored procedure

Un UDF è una funzione creazione di richiamabile all'interno di un'interrogazione, in modo che possa fare solo un sottoinsieme molto limitato di possibili operazioni.

Si può fare molto di più è una stored procedure.

Aggiornamento:

Nel esempio che ha dato, come cambiare la logica che calcola un "campo derivato", il UDF che calcola il campo è OK.

Ma (nel caso) quando le prestazioni sarà un problema (e credetemi, questo sarà molto prima che si possa pensare), trasformando i dati con operazioni di set-based può essere molto più efficiente rispetto all'utilizzo UDFs.

In questo caso, si consiglia di creare una vista, una stored procedure o una funzione a valori tavolo restituire un gruppo di risultati che conterrà un più efficiente di query piuttosto che da soli limitandosi ad aggiornare i UDFs (che sono basata sui record).

Un esempio: la ricerca ha qualcosa come "punteggio user", che si sente di essere soggetti a modifiche e avvolgerlo in un UDF

SELECT  user_id, fn_getUserScore(user_id)
FROM    users

Inizialmente, questo è solo un campo di pianura in tabella:

CREATE FUNCTION fn_getUserScore(@user_id INT) RETURNS INT
AS
BEGIN
        DECLARE @ret INT
        SELECT  user_score
        INTO    @ret
        FROM    users
        WHERE   user_id = @user_id
        RETURN @ret
END

, allora si decide che calcolarlo utilizzando i dati provenienti da altra tabella:

CREATE FUNCTION fn_getUserScore(@user_id INT) RETURNS INT
AS
BEGIN
        DECLARE @ret INT
        SELECT  SUM(vote)
        INTO    @ret
        FROM    user_votes
        WHERE   user_id = @user_id
        RETURN @ret
END

Questa condannerà il motore per utilizzando l'algoritmo NESTED LOOPS meno efficiente in entrambi i casi.

Ma se si è creato una vista e riscritto la query sottostanti in questo modo:

SELECT  user_id, user_score
FROM    users

SELECT  user_id, SUM(vote) AS user_score
FROM    users u
LEFT JOIN
        user_votes uv
ON uv.user_id = u.user_id

, questo darebbe il motore spazio molto più ampio per l'ottimizzazione, pur mantenendo la struttura di risultati e separare la logica dalla presentazione.

Direi che siete sulla strada giusta -. Procedure SQL possono rapidamente sfuggire di mano come diventano sempre più complessi e incapsulare condivise, ripetuti pezzi di logica in UDF è una soluzione del tutto appropriata per affrontare questo

vado spesso per quanto incapsulare la logica di una procedura SQL che viene utilizzato solo in quella procedura in un pozzo di nome UDF per migliorare la leggibilità.

Dai un'occhiata alla questo articolo MSDN su UDF - forse che vi darà qualche idea in più circa i loro usi?

Ci sono varie considerazioni sulle prestazioni che sarà necessario essere consapevoli di se avete intenzione di utilizzare UDF pesantemente -. Le cose come le prestazioni di scalare vs UDF da tavolo e gli eventuali benefici di CLR UDF

Se il vostro interesse nella costruzione di un data warehouse per la segnalazione si dovrebbe provare a mettere come gran parte di questo nella parte Trasforma del vostro ETL possibile in modo SQL segnalazione è composto da semplici dichiarazioni che gli strumenti e gli utenti allo stesso modo sono in grado di generare.

SSIS è strumento di ETL molto capace che viene fornito con SQL Server per questo genere di cose.

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