Colonne di identità o UDF che generano esplicitamente un ID univoco?


11

Sono nel bel mezzo di un dibattito sul fatto che sia meglio ricavare una PRIMARY KEYcolonna d' identità , la nostra fuori da una UDF che genera esplicitamente un ID univoco.

  • Sto discutendo per la colonna di identità.
  • Il mio partner sta discutendo per la generazione manuale dei valori, afferma
    • inserendo l'UDF su un altro tavolo in cui possiamo avere un UDF
      • bloccare la risorsa
      • incrementare una tabella ID con un campo chiamato ID_Valueda1
      • usalo come identificatore univoco globale
    • Oppure fai fare una tabella id+1durante l'inserimento
    • È più semplice spostare i dati tra server e / o ambienti senza il vincolo identificativo; passare da un DB in cui sono presenti dati a un altro DB simile con dati di gestione temporanea o fittizi. Per i test in non produzione potremmo voler estrarre tutti i record da ieri alla messa in scena per i test.

Quale implementazione ha più senso?

Risposte:


21

Il tuo collega è un idiota.

La soluzione non sarà scalabile, l'UDF non è simultaneo ( stesso motivo di questo ). E come gestisci gli inserti multi-riga: ciò richiederebbe una chiamata UDF per riga

E la migrazione ad altri RDBMS non avviene spesso nella vita reale ... potresti non usare SQL Server ora e utilizzare sequenze su Oracle e sperare di non migrare via.

Modificare:

L'aggiornamento afferma che lo spostamento dei dati serve per l'aggiornamento di database non di produzione.

In tal caso, si ignorano le colonne dell'identità durante l'aggiornamento. Non comprometti l'implementazione per semplificare il caricamento senza produzioni. Oppure utilizza le tabelle temporanee per tenere traccia delle modifiche al valore dell'identità.

O utilizzare i processi: aggiorniamo il nostro sistema di test ogni notte dalla produzione, evitando completamente il problema. (E assicura che anche il nostro backup dei prodotti possa essere ripristinato)


11

Usa un valore di identità. Generare la propria tabella di sequenza e i valori di sequenza richiederà molto overhead e causerà molti blocchi e blocchi durante il tentativo di generare numeri.

L'identità esiste per una ragione, usala.

Quando uscirà SQL Denali supporterà sequenze che saranno più efficienti dell'identità, ma non puoi creare qualcosa di più efficiente da solo.

Per quanto riguarda lo spostamento dei record da un ambiente all'altro, attivare IDENTITY_INSERT su ON quando si esegue l'inserimento o selezionare la casella in SSIS.


Se si passa da "produzione" a "test" e si dispone di un campo identità, si corre il rischio di sovrascrivere o scontrarsi sui dati. Questo è tutto ciò che sto dicendo. Sì, non dovrebbe essere un problema in quella direzione, ma sto solo dicendo che potrebbe succedere.
jcolebrand

È vero, avrai lo stesso numero per valori di riga diversi in dev, test, qa, uat e production. E allora? Se questi valori sono importanti (come per una tabella di ricerca), allora codificali manualmente, il che non dovrebbe essere un problema in quanto non dovresti inserire valori in quelle tabelle molto spesso. Se è necessario controllare i valori di identità tra gli ambienti per evitare collisioni, ripristinare i valori di identità tra gli ambienti quando si esegue il ripristino dalla produzione.
mrdenny l'

5

La colonna identità suona bene per me. Non sono sicuro di seguire la logica del perché è difficile spostare i dati tra i server.

Se vuoi che ogni riga abbia un'identità univoca a livello globale, puoi usare un UUID, ma non lo farei a meno che tu non sia sicuro che l'unicità globale sia necessaria - di solito non lo è. L'uso degli UUID come ID riduce le prestazioni, aumenta i requisiti di spazio su disco e rende più difficile il debug: a causa della lunghezza è difficile ricordare un UUID, dirlo a qualcuno al telefono o scriverlo su carta senza errori.


4

Per semplici ID numerici, basta andare con identità e dimenticare tutti i problemi di generarli manualmente.

Puoi sempre creare una "super tabella" che utilizza un'identità come PK e abbia una colonna di tipo e qualsiasi altra informazione. Quando hai bisogno di un nuovo ID (supponendo che intendi ID univoci in diverse tabelle), inserisci semplicemente in questa tabella e prendi SCOPE_IDENTITY()e quindi inserisci nella tabella effettiva che ti serve.

Fondamentalmente si crea una tabella: MasterID con un PK di identità, quando è necessario inserire una riga nella tabella1, INSERT INTO MasterIDsottenere l'identità generata da quella riga utilizzando SCOPE_IDENTITY()e quindi inserire in tabella1 utilizzando quel valore come PK.

Table1 avrà un int PK non identitario. Faresti lo stesso processo per inserire in Table2, ecc. Consenti a SQL Server di gestire i valori di identità nella tabella MasterIDs , che puoi quindi utilizzare nelle altre tue tabelle. I MasterID potrebbero contenere altre tabelle, come il tipo (in modo da poter sapere quale tabella, Tabella1 o Tabella2, ecc., Utilizza quel valore di identità.


3

Finché stai usando correttamente i vincoli di chiave esterna (a cascata, aggiornando, ecc.) Allora starai bene usando un campo di identità. In questo caso non vedo davvero un vantaggio rispetto all'altra soluzione.


2

L'identità è stata creata per adattarsi al tuo scenario. Hai strumenti come la replica per lo scambio di dati server / ambienti che tengono tutto insieme.


1

Ho appena finito un lavoro in cui ho sostituito una identitycolonna di SQL Server con un intcampo normale e ho controllato personalmente l'allocazione dell'ID.

Ho visto miglioramenti delle prestazioni piuttosto impressionanti. A differenza dell'OP, non ho un UDF per generare l'id. Ma il principio è praticamente lo stesso: esiste una parte del software che mantiene un pool di ID. Una volta esauriti ottiene un altro lotto interrogando il database per il prossimo Low valore e incrementi di questo per la prossima alta .

Questo ci consente di generare ID e mettere in relazione tutte le entità al di fuori di una transazione nel nostro ORM prima di inviare i batch al database e anche di inviare batch più grandi senza roundtrip aggiuntivi per ottenere l'identità appena inserita (richiesta dalle colonne di identità).

Nella tabella ID abbiamo più di una riga, che ci consente di utilizzare intervalli specifici se lo desideriamo. cioè per riutilizzare blocchi cancellati e ID negativi.


0

Uso l'identità da anni e sto seriamente pensando di sostituire il numero di identità con UNIQUEIDENTIFIER. È un incubo quando è necessario modificare il tipo di dati se qualcuno lo ha progettato per essere un db compatto e un incubo se è necessario aggiungere identità a una colonna, inoltre, non è possibile aggiornare la colonna identità. Immagina di inserire un int e il tuo database supera i 2 miliardi di record, di nuovo incubo da cambiare (considera gli FK)! Cambiare qualsiasi cosa con l'identità è un incubo e non è adatto alla scala a meno che non si metta bigint! UNIQUEIDENTIFIER vs Identity = convenienza e robustezza vs forse un notevole miglioramento delle prestazioni (non ha fatto il benchmark).

Aggiornamento: Dopo che ho visto questo ho sicuramente magra verso UNIQUEIDENTIFIER. Questo non mostra alcun reale vantaggio dell'identità bigint e un sacco di vantaggi per UNIQUEIDENTIFIER! Versioni diverse di SQL Server potrebbero avere un risultato diverso. C'è solo bellezza nell'avere un ID unico in tutti i database e sistemi (robustezza)! Sposta, copia, trasforma i dati come preferisci! https://www.mssqltips.com/sqlservertip/5105/sql-server-performance-comparison-int-versus-guid/


Un INT a 64 bit durerà a lungo ...
Vérace,
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.