Domanda

Stiamo lavorando alla progettazione di un'applicazione tipicamente OLTP (si pensi:sistema di acquisto).Tuttavia, questo in particolare ha la necessità che alcuni utenti siano offline, quindi devono essere in grado di scaricare il DB sul proprio computer, lavorarci sopra e quindi sincronizzarsi nuovamente una volta che sono sulla LAN.

Vorrei sottolineare che so che questo è già stato fatto, semplicemente non ho esperienza con questo particolare modello.

Un'idea a cui ho pensato era l'utilizzo dei GUID come chiavi della tabella.Quindi, ad esempio, un ordine di acquisto non avrebbe un numero (autonumerico) ma un GUID, in modo che ogni client offline possa generarli e non ho conflitti quando mi ricollego al DB.

È una cattiva idea per qualche motivo?L'accesso a queste tabelle tramite la chiave GUID sarà lento?

Hai avuto esperienza con questo tipo di sistemi?Come hai risolto questo problema?

Grazie!
Daniele

È stato utile?

Soluzione

L'utilizzo delle GUId come chiavi primarie è accettabile ed è considerata una pratica abbastanza standard per gli stessi motivi per cui le stai considerando.Possono essere abusati, il che può rendere le cose un po' noiose da debuggare e gestire, quindi cerca di tenerli fuori dalle tabelle dei codici e da altri dati di riferimento, se possibile.

La cosa di cui devi preoccuparti è l'identificatore leggibile dall'uomo.Le guide non possono essere scambiate dalle persone: puoi immaginare di provare a confermare telefonicamente il numero dell'ordine se si tratta di una guida?Pertanto, in uno scenario offline potresti dover ancora generare qualcosa - come un ID editore (workstation/utente) e un numero di sequenza, quindi il numero dell'ordine potrebbe essere 123-5678 -.

Tuttavia, ciò potrebbe non soddisfare i requisiti aziendali di avere un numero sequenziale.In effetti, i requisiti normativi possono essere e influenzare: alcuni regolamenti (forse SOX) richiedono che i numeri delle fatture siano sequenziali.In questi casi potrebbe essere necessario generare una sorta di numero proforma che verrà corretto successivamente quando i sistemi si sincronizzeranno.Potresti ritrovarti con tabelle con OrderId (Guid), OrderNo (int), ProformaOrderNo (varchar): potrebbe insinuarsi una certa complessità.

Almeno avere le guide come chiavi primarie significa che non devi eseguire molti aggiornamenti a cascata quando alla fine avviene la sincronizzazione: aggiorni semplicemente il numero leggibile dall'uomo.

Altri suggerimenti

@SqlMenace

Ci sono altri problemi con i GUID, vedi che i GUID non sono sequenziali, quindi gli inserti saranno sparsi ovunque, questo causa divisioni di pagina e frammentazione dell'indice

Non vero. Chiave primaria! = indice cluster.

Se l'indice cluster è un'altra colonna (mi viene in mente "inserted_on"), gli inserimenti saranno sequenziali e non si verificherà alcuna suddivisione della pagina o frammentazione eccessiva.

Questo è un uso perfettamente corretto dei GUID.L'unico inconveniente sarebbe una leggera complessità nel lavorare con GUID su INT e la leggera differenza di dimensione (16 byte contro 4 byte).

Non penso che nessuno dei due sia un grosso problema.

L'accesso a queste tabelle tramite il tasto GUID sarà lento?

Ci sono altri problemi con i GUID, vedi che i GUID non sono sequenziali, quindi gli inserti saranno sparsi ovunque, questo causa divisioni di pagina e frammentazione dell'indice

In SQL Server 2005 MS ha introdotto NEWSEQUENTIALID() per risolvere questo problema, l'unico problema per te potrebbe essere che puoi utilizzare solo NEWSEQUENTIALID come valore predefinito in una tabella

Hai ragione nel dire che si tratta di un vecchio problema e ha due soluzioni canoniche:

  • Utilizza identificatori univoci come chiave primaria.Tieni presente che se sei preoccupato per la leggibilità puoi eseguire il rollover del tuo identificatore univoco invece di utilizzare un GUID.Un identificatore univoco utilizzerà le informazioni sulla data e sulla macchina per generare un valore univoco.

  • Utilizza una chiave composta da "Attore" + identificatore.Ogni utente riceve un ID attore numerico e le chiavi delle righe appena inserite utilizzano l'ID attore e il successivo identificatore disponibile.Pertanto, se due attori inseriscono entrambi una nuova riga con ID "100", il vincolo della chiave primaria non verrà violato.

Personalmente preferisco il primo approccio, poiché penso che le chiavi composte siano davvero noiose come chiavi esterne.Penso che il reclamo sulla leggibilità umana sia esagerato: gli utenti finali non dovrebbero comunque sapere nulla delle tue chiavi!

Assicurati di utilizzare guid.comb: si occupa delle operazioni di indicizzazione.Se successivamente avrai a che fare con problemi di prestazioni, diventerai, in breve tempo, un esperto di ridimensionamento.

Un altro motivo per utilizzare i GUID è abilitare il refactoring del database.Supponiamo che tu decida di applicare il polimorfismo o l'ereditarietà o qualsiasi altra cosa all'entità Clienti.Ora desideri che Customers e Employees derivino da Person e che condividano una tabella.Avere identificatori davvero univoci semplifica la migrazione dei dati.Non ci sono sequenze o campi di identità intera con cui combattere.

Ti indicherò semplicemente Quali sono i miglioramenti prestazionali della Guida sequenziale rispetto alla Guida standard?, che copre la discussione sul GUID.

Per la leggibilità umana, prendere in considerazione l'assegnazione di ID macchina e quindi l'utilizzo di numeri sequenziali da tali macchine come possibilità.Ciò richiederà tuttavia la gestione dell'assegnazione degli ID macchina.Potrebbe essere fatto in una o due colonne.

Personalmente sono affezionato alla risposta SGUID, però.

Le guide saranno sicuramente più lente (e utilizzeranno più memoria) rispetto alle chiavi intere standard, ma se questo sia o meno un problema dipenderà dal tipo di carico che vedrà il tuo sistema.A seconda del DB back-end potrebbero verificarsi problemi con l'indicizzazione dei campi GUID.

L'uso delle guide semplifica un'intera classe di problemi, ma ne paghi in parte le prestazioni e anche la possibilità di debug: digitare le guide in quelle query di prova invecchierà molto velocemente!

Il backend sarà SQL Server 2005
Il frontend/la logica dell'applicazione sarà .Net

Oltre ai GUID, riesci a pensare ad altri modi per risolvere la "unione" che si verifica quando il computer offline sincronizza i nuovi dati nel database centrale?
Voglio dire, se le chiavi sono INT, dovrò rinumerare tutto durante l'importazione in pratica.I GUID me ne risparmieranno.

L'uso dei GUID ci ha risparmiato molto lavoro quando abbiamo dovuto unire due database in uno solo.

Se il database è sufficientemente piccolo da poter essere scaricato su un laptop e utilizzato offline, probabilmente non è necessario preoccuparsi troppo delle differenze di prestazioni tra int e Guid.Ma non sottovalutare quanto siano utili gli int durante lo sviluppo e la risoluzione dei problemi di un sistema!Probabilmente dovrai elaborare una logica di importazione/sincronizzazione abbastanza complessa indipendentemente dal fatto che tu stia utilizzando o meno i Guid, quindi potrebbero non essere di aiuto quanto pensi.

@Simone,

Hai raccolto ottimi punti.Stavo già pensando ai numeri "temporanei" "leggibili dall'uomo" che avrei generato mentre ero offline, che avrei ricreato in sincronia.Ma volevo evitare di avere a che fare con chiavi esterne, ecc.

inizierei a guardare SQL Server Compact Edition per questo!Ti aiuta con tutti i tuoi problemi.

Architettura di archiviazione dei dati con SQL Server 2005 Compact Edition

È specificamente progettato per

Applicazioni di forza sul campo (FFA).I FFA di solito condividono uno o più dei seguenti attributi

Consentono all'utente di svolgere le loro funzioni lavorative mentre si disconnette dalla rete di back-end: in loco in una posizione del cliente, in viaggio, in un aeroporto o da casa.

Gli FFA sono generalmente progettati per una connettività occasionale, il che significa che quando gli utenti eseguono l'applicazione client, non devono avere una connessione di rete di alcun tipo.Gli FFA coinvolgono spesso più client che possono accedere e utilizzare contemporaneamente i dati dal database back-end, sia in modalità connessa che disconnessa.

FFAS deve essere in grado di replicare i dati dal database back-end ai database client per il supporto offline.Devono inoltre essere in grado di replicare i record di dati modificati, aggiunti o eliminati dal client al server quando l'applicazione è in grado di connettersi alla rete

Primo pensiero che mi viene in mente:MS non ha progettato il modello DataSet e DataAdapter per supportare scenari come questo?

Credo di aver letto che MS ha cambiato il modello di recordset ADO con l'attuale modello DataSet, quindi funziona benissimo anche offline.E c'è anche questo Servizi di sincronizzazione per ADO.NET

Credo di aver visto codice che utilizza il modello DataSet che utilizza anche chiavi esterne e si sincronizzano ancora perfettamente quando si utilizza DataAdapter.Non ho provato i servizi di sincronizzazione, ma penso che potresti trarne vantaggio.

Spero che questo ti aiuti.

@Portman Per impostazione predefinita PK == Clustered Index, la creazione di un vincolo di chiave primaria creerà automaticamente un indice cluster, è necessario specificare non clustered se non si desidera che sia clusterizzato.

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