Frage

Wir arbeiten daran, eine Anwendung zu entwerfen, die typischerweise OLTP ist (denken Sie an:Einkaufssystem).Insbesondere hier ist es jedoch erforderlich, dass einige Benutzer offline sind, sodass sie in der Lage sein müssen, die Datenbank auf ihren Computer herunterzuladen, daran zu arbeiten und sie dann wieder zu synchronisieren, sobald sie im LAN sind.

Ich möchte anmerken, dass ich weiß, dass dies schon einmal gemacht wurde, ich aber keine Erfahrung mit diesem speziellen Modell habe.

Eine Idee, über die ich nachgedacht habe, war die Verwendung von GUIDs als Tabellenschlüssel.So hätte eine Bestellung beispielsweise keine Nummer (automatisch numerisch), sondern stattdessen eine GUID, sodass jeder Offline-Client diese generieren kann und es keine Konflikte gibt, wenn ich mich wieder mit der Datenbank verbinde.

Ist das aus irgendeinem Grund eine schlechte Idee?Wird der Zugriff auf diese Tabellen über den GUID-Schlüssel langsam sein?

Haben Sie Erfahrungen mit solchen Systemen?Wie haben Sie dieses Problem gelöst?

Danke!
Daniel

War es hilfreich?

Lösung

Die Verwendung von Guids als Primärschlüssel ist akzeptabel und wird aus den gleichen Gründen, aus denen Sie sie in Betracht ziehen, als ziemlich gängige Vorgehensweise angesehen.Sie können überbeansprucht werden, was das Debuggen und Verwalten etwas mühsam machen kann. Versuchen Sie daher, sie nach Möglichkeit aus Codetabellen und anderen Referenzdaten herauszuhalten.

Die Sache, mit der Sie sich befassen müssen, ist die für den Menschen lesbare Kennung.Anleitungen können nicht von Personen ausgetauscht werden. Können Sie sich vorstellen, Ihre Bestellnummer telefonisch zu bestätigen, wenn es sich um eine Anleitung handelt?In einem Offline-Szenario müssen Sie also möglicherweise noch generieren etwas - wie eine Herausgeber-ID (Workstation/Benutzer) und eine Sequenznummer, sodass die Bestellnummer 123-5678 sein kann -.

Allerdings erfüllt dies möglicherweise nicht die geschäftlichen Anforderungen an eine fortlaufende Nummer.Tatsächlich können behördliche Anforderungen Einfluss darauf haben – einige Vorschriften (vielleicht SOX) verlangen, dass die Rechnungsnummern fortlaufend sind.In solchen Fällen kann es notwendig sein, eine Art Proforma-Nummer zu generieren, die später bei der Synchronisierung der Systeme festgelegt wird.Möglicherweise landen Sie bei Tabellen mit OrderId (Guid), OrderNo (int), ProformaOrderNo (varchar) – es kann sich eine gewisse Komplexität einschleichen.

Wenn Sie Guids als Primärschlüssel haben, bedeutet dies zumindest, dass Sie nicht viele kaskadierende Aktualisierungen durchführen müssen, wenn die Synchronisierung schließlich erfolgt – Sie aktualisieren einfach die für Menschen lesbare Zahl.

Andere Tipps

@SqlMenace

Es gibt noch andere Probleme mit GUIDs. Sie sehen, dass GUIDs nicht sequentiell sind, sodass Einfügungen überall verstreut sind, was zu Seitenaufteilungen und Indexfragmentierung führt

Nicht wahr. Primärschlüssel != Clustered-Index.

Wenn es sich bei dem Clustered-Index um eine andere Spalte handelt („inserted_on“, fällt mir da ein), erfolgen die Einfügungen sequentiell und es treten keine Seitenaufteilungen oder übermäßige Fragmentierung auf.

Dies ist eine vollkommen gute Verwendung von GUIDs.Die einzigen Nachteile wären eine leichte Komplexität bei der Arbeit mit GUIDs gegenüber INTs und der geringfügige Größenunterschied (16 Byte gegenüber 4 Byte).

Ich denke nicht, dass beides eine große Sache ist.

Der Zugriff auf diese Tabellen erfolgt über der GUID-Schlüssel langsam ist?

Es gibt noch andere Probleme mit GUIDs. Sie sehen, dass GUIDs nicht sequentiell sind, sodass Einfügungen überall verstreut sind, was zu Seitenaufteilungen und Indexfragmentierung führt

In SQL Server 2005 hat MS NEWSEQUENTIALID() eingeführt, um dieses Problem zu beheben. Das einzige Problem für Sie besteht möglicherweise darin, dass Sie NEWSEQUENTIALID nur als Standardwert in einer Tabelle verwenden können

Sie haben Recht, dass dies ein altes Problem ist und es zwei kanonische Lösungen gibt:

  • Verwenden Sie eindeutige Bezeichner als Primärschlüssel.Beachten Sie, dass Sie, wenn Sie Bedenken hinsichtlich der Lesbarkeit haben, Ihre eigene eindeutige Kennung erstellen können, anstatt eine GUID zu verwenden.Eine eindeutige Kennung verwendet Informationen über das Datum und die Maschine, um einen eindeutigen Wert zu generieren.

  • Verwenden Sie einen zusammengesetzten Schlüssel aus „Akteur“ + Bezeichner.Jeder Benutzer erhält eine numerische Akteur-ID, und die Schlüssel neu eingefügter Zeilen verwenden die Akteur-ID sowie die nächste verfügbare Kennung.Wenn also zwei Akteure beide eine neue Zeile mit der ID „100“ einfügen, wird die Primärschlüsseleinschränkung nicht verletzt.

Persönlich bevorzuge ich den ersten Ansatz, da ich denke, dass zusammengesetzte Schlüssel als Fremdschlüssel sehr mühsam sind.Meiner Meinung nach ist die Beschwerde bezüglich der menschlichen Lesbarkeit übertrieben – Endbenutzer sollten sowieso nichts über Ihre Schlüssel wissen müssen!

Stellen Sie sicher, dass Sie guid.comb verwenden – es kümmert sich um die Indizierung.Wenn Sie danach mit Leistungsproblemen zu kämpfen haben, sind Sie in kurzer Zeit ein Experte für Skalierung.

Ein weiterer Grund für die Verwendung von GUIDs besteht darin, Datenbank-Refactoring zu ermöglichen.Angenommen, Sie entscheiden sich dafür, Polymorphismus oder Vererbung oder was auch immer auf Ihre Kundenentität anzuwenden.Sie möchten nun, dass Kunden und Mitarbeiter von „Person“ abgeleitet werden und dass sie sich eine Tabelle teilen.Wirklich eindeutige Identifikatoren machen die Datenmigration einfach.Es gibt keine Sequenzen oder Ganzzahlidentitätsfelder, mit denen man kämpfen muss.

Ich möchte Sie nur darauf hinweisen Was sind die Leistungsverbesserungen von Sequential Guid gegenüber Standard Guid?, das den GUID-Vortrag abdeckt.

Um die Lesbarkeit für den Menschen zu gewährleisten, sollten Sie in Betracht ziehen, Maschinen-IDs zuzuweisen und dann fortlaufende Nummern dieser Maschinen zu verwenden.Dies erfordert jedoch die Verwaltung der Zuweisung von Maschinen-IDs.Könnte in einer oder zwei Spalten erfolgen.

Ich persönlich mag jedoch die SGUID-Antwort.

Guids sind sicherlich langsamer (und verbrauchen mehr Speicher) als Standard-Integer-Schlüssel, aber ob das ein Problem darstellt oder nicht, hängt von der Art der Auslastung ab, die Ihr System sieht.Abhängig von Ihrer Backend-Datenbank kann es zu Problemen mit der Indizierung von GUID-Feldern kommen.

Die Verwendung von Guids vereinfacht eine ganze Klasse von Problemen, aber Sie zahlen dafür, zum Teil für die Leistung und auch für die Debugbarkeit – das Eingeben von Guids in diese Testabfragen wird sehr schnell langweilig!

Das Backend wird SQL Server 2005 sein
Frontend/Anwendungslogik wird .Net sein

Können Sie sich neben GUIDs auch andere Möglichkeiten vorstellen, die „Zusammenführung“ zu lösen, die auftritt, wenn der Offline-Computer die neuen Daten wieder mit der zentralen Datenbank synchronisiert?
Ich meine, wenn die Schlüssel INTs sind, muss ich beim Import grundsätzlich alles neu nummerieren.GUIDs werden mir das ersparen.

Die Verwendung von GUIDs hat uns viel Arbeit erspart, als wir zwei Datenbanken zu einer zusammenführen mussten.

Wenn Ihre Datenbank klein genug ist, um sie auf einen Laptop herunterzuladen und offline damit zu arbeiten, müssen Sie sich wahrscheinlich keine großen Gedanken über die Leistungsunterschiede zwischen Ints und Guids machen.Aber unterschätzen Sie nicht, wie nützlich Ints bei der Entwicklung und Fehlerbehebung eines Systems sind!Sie müssen sich wahrscheinlich eine ziemlich komplexe Import-/Synchronisierungslogik ausdenken, unabhängig davon, ob Sie Guids verwenden oder nicht, sodass diese möglicherweise nicht so viel helfen, wie Sie denken.

@Simon,

Sie sprechen sehr gute Punkte an.Ich habe bereits über die „temporären“, „für Menschen lesbaren“ Zahlen nachgedacht, die ich offline generieren und bei der Synchronisierung neu erstellen würde.Aber ich wollte vermeiden, mit Fremdschlüsseln usw. umzugehen.

Ich würde mir dafür die SQL Server Compact Edition ansehen!Es hilft bei all Ihren Problemen.

Datenspeicherarchitektur mit SQL Server 2005 Compact Edition

Es wurde speziell für entwickelt

Field Force-Anwendungen (FFAs).FFAs in der Regel eine oder mehrere der folgenden Attributen

Sie ermöglichen es dem Benutzer, seine Arbeitsfunktionen, während die Verbindung zu das Backend-Netzwerk – vor Ort an einem Kundenstandort, unterwegs, in einem Flughafen oder von zu Hause aus.

FFAs sind in der Regel konzipiert für gelegentliche Konnektivität, d. h. Wenn Benutzer den Client ausführen Anwendung, müssen sie nicht eine Netzwerkverbindung jeglicher Art.FFAs Oft sind mehrere Kunden beteiligt, die kann gleichzeitig auf Daten zugreifen und diese verwenden aus der Backend-Datenbank, sowohl in einem Verbundener und getrennter Modus.

FFAs müssen in der Lage sein, Daten zu replizieren von der Backend-Datenbank in die Clientdatenbanken für die Offline-Unterstützung.Sie müssen auch in der Lage sein, sich zu replizieren Geänderte, hinzugefügte oder gelöschte Daten Datensätze vom Client zum Server Wenn die Anwendung in der Lage ist, Herstellen einer Verbindung mit dem Netzwerk

Der erste Gedanke, der mir in den Sinn kommt:Hat MS das DataSet- und DataAdapter-Modell nicht zur Unterstützung solcher Szenarien entwickelt?

Ich glaube, ich habe gelesen, dass MS sein ADO-Recordset-Modell auf das aktuelle DataSet-Modell geändert hat, sodass es auch offline hervorragend funktioniert.Und das gibt es auch Synchronisierungsdienste für ADO.NET

Ich glaube, ich habe Code gesehen, der das DataSet-Modell verwendet, das auch Fremdschlüssel verwendet, und die bei Verwendung des DataAdapter immer noch perfekt synchronisiert werden.Ich habe die Sync-Dienste zwar noch nicht ausprobiert, aber ich denke, dass auch Sie davon profitieren können.

Hoffe das hilft.

@Portman Standardmäßig wird bei PK == Clustered Index durch das Erstellen einer Primärschlüsseleinschränkung automatisch ein Clustered-Index erstellt. Sie müssen „Non Clustered“ angeben, wenn Sie nicht möchten, dass er Clustered ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top