Creare una funzione nel database centrale o ripetere in ciascun database?


8

Uno dei miei sviluppatori ha scritto una funzione SQL che funziona come la funzione VB.Net (LastIndexOf) e vuole pubblicarla. La mia domanda è: quale sarebbe il motivo per inserirlo in un database centrale anziché inserirlo in ciascun database utente?

Lo sviluppatore stava cercando di inserirlo nello schema sys sul suo db master in modo da non dover qualificare le chiamate dai database degli utenti ... sigh

Ma non ero sicuro di quale fosse la scusa valida per centralizzarlo (ovviamente non il database principale) rispetto a ciascun database utente?


1
Penso che l'idea alla base possa essere qualcosa del tipo 'Cosa faresti nel caso di un ipotetico bugfix? Vai su ogni singolo database e aggiusta ogni singola copia separatamente? '
dezso

1
Il sovraccarico amministrativo è irrilevante qui perché posso aggiornare tutti i database con la stessa facilità di un singolo database
David George

E il tuo sviluppatore lo sa? :) E probabilmente lui / lei sente che implementa una funzionalità di base tale che deve essere al centro.
dezso

Sì. Questa è la mia domanda: qualcosa che potrebbe essere considerato core dovrebbe far parte del database utente o essere condiviso tra tutti i database da un unico database comune?
David George,

Sì, ho provato a presentare due argomenti più o meno validi a favore della centralizzazione. Penso che possa essere piuttosto una questione di politica o di gusti personali: dalla formulazione emerge chiaramente che non ti piace l'idea.
dezso

Risposte:


12

Il modo in cui preferisco fare questo: inserire la funzione in un database di utilità e creare un sinonimo in ciascun database normale. In questo modo ottieni il meglio da entrambi i mondi:

  1. c'è solo una copia dell'oggetto da mantenere
  2. lo sviluppatore non deve fornire nomi in tre o quattro parti

per esempio

USE UtilityDB;
GO
CREATE FUNCTION dbo.LastIndexOf(...) ...
GO
USE otherDB;
GO
CREATE SYNONYM dbo.LastIndexOf FOR UtilityDB.dbo.LastIndexOf;
GO

Ciò è particolarmente potente per le funzioni CLR, poiché vi è un sovraccarico amministrativo aggiuntivo per la modifica / distribuzione di tali.

Ed è preferibile utilizzare master (e contrassegnare come oggetto di sistema, che non è garantito per essere trasferibile in avanti). Mi piacerebbe sapere come il tuo sviluppatore si aspetta di creare la sua funzione nello sysschema, però.

Comprendo che mantenere più copie di una funzione in 500 database non è più difficile del mantenere una singola copia, ma avere più copie è davvero un vantaggio solo quando si hanno eccezioni (ad esempio il client A vuole che la sua funzione gestisca NULL in modo diverso, o qualcosa). Nel qual caso lascerei il sinonimo in tutti gli altri database e introdurrei una versione speciale della funzione solo in quel database.

(Ciò presuppone che la funzione non si basi su alcun accesso ai dati all'interno del database di un client, ovviamente - il che può certamente complicare le cose.)


5

Non dovrò essere d'accordo con Aaron (e la risposta accettata).

L'approccio di Aaron è il modo in cui mi piace gestire "cose ​​DBA", ad esempio gli script di manutenzione. Non vorrei mai farlo con una funzione di libreria che verrebbe chiamata da un database utente.

Perché? Ti dirigerai verso l'equivalente del database di DLL Hell .

Versioni incompatibili

... Prima di Windows 2000, Windows era vulnerabile a questo perché la tabella delle classi COM era condivisa da tutti gli utenti e tutti i processi. Solo un oggetto COM, in una DLL / EXE, può essere dichiarato come avere un ID di classe COM globale specifico su un sistema. Se un programma aveva bisogno di creare un'istanza di quella classe, otteneva qualunque fosse l'attuale implementazione registrata centralmente. Di conseguenza, un'installazione di un programma che installa una nuova versione di un oggetto comune potrebbe interrompere inavvertitamente altri programmi precedentemente installati.

Installa .net 4.5 su un server che esegue un'applicazione .net 2.0 e cosa succede? Niente, l'applicazione continua a utilizzare il framework 2.0. Aggiorna la tua funzione LastIndexOf su un server che ospita 3 database di applicazioni (come parte di un aggiornamento a uno di essi) e cosa succede? Tutti e tre ora stanno utilizzando l'ultima versione.

L'alternativa è l'approccio adottato da SQL # . Questo è installato su uno schema in ogni database utente, quindi puoi aggiornare in sicurezza il database per Application-X senza rischiare la stabilità di Application-Y.

Se lavori in un ambiente di gestione delle modifiche strettamente controllato, non avrai scelta, non puoi aggiornare un componente condiviso senza testare tutti i consumatori del componente. Se lavori da qualche parte un po 'più "veloce e lento", sei libero di correre il rischio di rompere involontariamente qualcosa con una patch / aggiornamento.


Lascia che ti fornisca una confutazione, dato che sembra che tu ne voglia uno e ora ho qualche momento libero che non avevo prima. :-) (1) Ho ipotizzato che l'insieme di database in questione fosse tutto correlato e non facesse parte di applicazioni completamente diverse. (2) In questo caso non sospetto che ci sia molto pericolo per una funzione chiamata LastIndexOfa cambiare, tanto meno in un modo che rompe solo alcune delle app / dei database. Direi che è un problema più grande per CLR o funzioni veramente centrali / complesse che servono più app. (3) La mia attuale preferenza sarebbe quella di non usare affatto una funzione per compiti semplici.
Aaron Bertrand

1
Accogli sempre i tuoi pensieri ovviamente :)
Mark Storey-Smith,

Ehilà. Come creatore di SQL # apprezzo la menzione positiva :-). Tuttavia, dovrei chiarire che il principale punto di decisione per l'utilizzo di uno schema separato per tutti gli oggetti SQL # era quello di creare uno spazio dei nomi in modo che non vi fossero conflitti di denominazione, indipendentemente da dove fosse installato SQL #. Tuttavia, fai apparire un punto che deve essere considerato per quanto riguarda il controllo delle versioni, a seconda di come è strutturata l'app. Personalmente, mi piace avere un UtilityDB per le cose comunemente chiamate librerie, ma aumenta leggermente il rischio e richiede test approfonditi.
Solomon Rutzky,

0

La risposta a questa domanda dipende dal fatto che stiamo parlando di oggetti T-SQL o oggetti SQLCLR. Ci sono diversi (e più) fattori da considerare quando si tratta di oggetti SQLCLR.

In termini di oggetti T-SQL, entrambe le risposte qui riportano punti validi. Come descritto nella risposta di @ Aaron , il DB centrale può essere abbastanza utile, e Sinonimi può essere usato per rendere semplice avere alcuni DB che puntano alla risorsa condivisa e alcuni usano una risorsa locale. Ma il punto sollevato nella risposta di Mark riguardo all'aumento del rischio dovuto alla maggiore dipendenza non può essere ignorato.

Tuttavia, se hai a che fare con oggetti SQLCLR, devi prima considerare tutti i punti che ho sollevato nella seguente risposta:

Come utilizzare al meglio la funzione CLR dal punto di vista delle prestazioni (ripetere all'interno di ciascun DB o avere una funzione generale)?

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.