<\/HEAD>
Wenn Sie irgendeine Komponente der ESRI Enterprise-Technologie verwendet haben, sind Sie dem allgegenwärtigen Global ID eindeutigen Bezeichner begegnet.<\/P>
<\/P>
Wahrscheinlich durch Rechtsklick auf eine Feature-Class und Auswahl von "Add Global ID's" und dann aus den Augen verloren.<\/P>
<\/P>
Dieser Beitrag ist eher ein Wutanfall und Ärger über zufällige<\/STRONG> GUID's als alles andere. Sie benötigen sicherlich eine GUID-Spalte, wenn Sie Daten replizieren oder offline bearbeiten.<\/P><\/P>Ich hasse sie einfach! Mein Problem mit der Global ID-Spalte ist, wie ESRI sie implementiert. Sie ist nicht nur eindeutig (was sie sein sollte), sondern auch zufällig. Ich verwende SDE\/SQL-Daten für viel mehr als nur das Anzeigen von Punkten auf einer Karte. Wir verknüpfen diese Daten mit anderen Anwendungen, wie solchen, die die Nicht-GIS-Daten verwalten, die an diesen Punkt auf der Karte angehängt sind. In einigen Anwendungen habe ich dutzende Beziehungen und Tabellen, die an diese "GIS-Tabelle" hängen. All dies wird durch geschickte Nutzung der Global ID-Spalte erreicht, um Nicht-GIS-Daten mit GIS-Daten zu verknüpfen. Sicher, ich könnte etwas anderes verwenden, aber dann hätte ich keinen so aufmerksamkeitsstarken Blogpost-Titel.<\/P><\/P>Mein Problem mit der Global ID-Spalte ist ihre Zufälligkeit. Stellen Sie sich eine Feature-Class mit 10.000 (ich habe einige mit 500.000) Punkten vor. Das sind 10.000 zufällige GUID's. Nun verknüpfen Sie diese Tabelle über diese Spalte, sortieren oder filtern sie. Legen Sie einen gruppierten (oder nicht gruppierten) Index auf die Global ID-Spalte. Diese zufälligen GUID's verlangsamen die Dinge ganz schön, nicht wahr?<\/P><\/P>Sehen wir uns an, wie das funktioniert. Wenn Sie diesen Rechtsklick machen und es vergessen, fügt SDE eine Einschränkung zum Global ID-Feld hinzu:<\/P><\/P>ALTER TABLE [dbo].[TEST] ADD DEFAULT ('{00000000-0000-0000-0000-000000000000}') FOR [GlobalID]<\/PRE><\/P>Jedes neue Feature, das zu dieser Feature-Class hinzugefügt wird, ruft eine gespeicherte Prozedur auf, die einen SQL newid (GUID-Wert) nimmt und in einen String umwandelt.<\/P><\/P>CREATE PROCEDURE [dbo].[next_globalid]
@guid NVARCHAR(38) OUTPUT
AS SET NOCOUNT ON
BEGIN
SELECT @guid = '{' + CAST (NEWID() AS NVARCHAR(38)) + '}'
END
GO<\/PRE><\/P>Aber was wäre, wenn wir die GUID sequentiell und nicht zufällig machen könnten, aber trotzdem eindeutig? So etwas existiert, und eine Internetsuche wird Ihnen eine sehr hitzige Debatte mit vielen festgefahrenen Meinungen für oder gegen sequentielle GUID's zeigen. Hier nicht weiter behandelt....<\/P><\/P>Der Versuch, die SP so zu ändern, dass standardmäßig SQL newSEQUENTIALID verwendet wird, funktioniert nicht...<\/P><\/P>CREATE PROCEDURE [dbo].[next_globalid]
@guid NVARCHAR(38) OUTPUT
AS SET NOCOUNT ON
BEGIN
SELECT @guid = '{' + CAST (NEWSEQUENTIALID() AS NVARCHAR(38)) + '}'
END
GO
Die eingebaute Funktion newsequentialid() kann nur in einem DEFAULT-Ausdruck für eine Spalte vom Typ 'uniqueidentifier' in einer CREATE TABLE- oder ALTER TABLE-Anweisung verwendet werden. Sie kann nicht mit anderen Operatoren kombiniert werden, um einen komplexen skalaren Ausdruck zu bilden.<\/PRE>Hier ist also mein Workaround: Setzen Sie einen Trigger zwischen die Delta- und Basistabelle und ignorieren Sie die ESRI-SP, die den zufälligen GUID schreibt. Wir können dies mit einem instead of insert Trigger und Änderung des Defaults der Global ID-Spalte erreichen.<\/P><\/P>Zuerst:<\/P><\/P>ALTER TABLE [dbo].[TEST] DROP CONSTRAINT [DF__TEST__GlobalID__65FFA925]
GO
ALTER TABLE [dbo].[TEST] ADD CONSTRAINT [DF__TEST__GlobalID__65FFA925] DEFAULT (newsequentialid()) FOR [GlobalID]
GO<\/PRE><\/P>Dann:<\/P><\/P>CREATE TRIGGER [dbo].[TEST_GLOBAL_ID]
ON [dbo].[TEST]
INSTEAD OF INSERT NOT FOR REPLICATION
AS BEGIN
SET NOCOUNT ON;
INSERT [TEST](
OBJECTID, SOMEFIELD, SHAPE, LON, LAT, QuadName, Watershed, County, State, PARKDISTRICT, ELEVATION, StreamName, RiverOrder
)
SELECT
OBJECTID, a.SOMEFIELD, a.SHAPE, a.LON, a.LAT, a.QuadName, a.Watershed, a.County, a.State, a.PARKDISTRICT, a.ELEVATION, a.StreamName, a.RiverOrder
From
(SELECT
OBJECTID, SOMEFIELD, SHAPE, LON, LAT, QuadName, Watershed, County, State, PARKDISTRICT, ELEVATION, StreamName, RiverOrder
FROM inserted)
AS a
;
end
GO<\/PRE>Fügen Sie ein paar neue Punkte hinzu und<\/P><\/P>SELECT
[GlobalID]
FROM [FISH].[dbo].[TEST]<\/PRE><\/P><\/P>GlobalID
C10EB116-8B14-45AB-924D-0C734E5AB5B6
61AE23FA-F02D-45C1-991D-571B77592014
0695789D-35A7-4BE4-B5F6-5EAF68D2A50B
5A20B628-6048-4D48-8380-AC005A0E70EC
CF52E6DE-5F60-456E-9DEF-C006D9BBD348
58F80A07-F8A8-4D62-BBB3-D012EA781F0C
5E7B9C91-2891-E411-B57C-E41F134196DA
BE30E498-2891-E411-B57C-E41F134196DA
BF30E498-2891-E411-B57C-E41F134196DA
C030E498-2891-E411-B57C-E41F134196DA
C130E498-2891-E411-B57C-E41F134196DA
38C5A6F2-60FF-4C39-BF37-F7AFCBDFDE90<\/PRE><\/P>Beachten Sie, wie meine neuen Punkte (beginnend bei Zeile 08 bis 12) sequentielle IDs enthalten. Ich verwende hier einen instead of statt eines after update Triggers weil ich möchte dass dies VOR dem Eintrag in die Basistabelle geschieht.<\/P><\/P>Leider ist diese "Änderung" nicht sehr robust und kann nicht verwendet werden wenn Ihre Daten versioniert sind OHNE Edits in die Basis zu verschieben oder gar nicht versioniert sind (wie es bei Verwendung von Collector for ArcGIS erforderlich ist). Ebenfalls hier nicht diskutiert ist mein sehr überzeugender Grund für die Verwendung des Global ID-Feldes in einigen Nicht-GIS-Anwendungen die diese Daten nutzen. Wir ordnen das unter "Basteln" ein. ESRI hat sicher einen sehr guten Grund für die Implementierung des Global ID Defaults wie sie es tun und dieser Beitrag wird sicherlich einige hitzige Debatten und Kommentare hervorrufen.<\/P><\/P>Dies zusammen mit dem after update\insert Trigger vorgestellt in Hey Neighbor? What's Your Value?<\/A> führt zu einer schönen sauberen Feature-Class bei der fast alle Attribute automatisch befüllt werden und Ihre Global ID's geordnet sind.<\/P><\/P>
<\/P>