6 Stimmen

Warum sind die von aspnet_regsql generierten Primärschlüssel GUIDs?

Ich entwickle eine ASP.NET-Website in Visual Studio 2010 (mit Service Pack 1, vielen Dank!). Ich möchte die in .NET integrierten Membership- und Role-Provider für SQL Server 2008 nutzen.

Ich entwickle nun schon sehr lange Microsoft-Technologien und habe mit einigen der besten SQL Server-DBAs der Branche zusammengearbeitet. Jeder von ihnen hat mir gesagt, dass ich wegbleiben von GUIDS als Primärschlüssel beim Aufbau einer Datenbanktabelle, die:

  1. Sie haben eine sehr hohe Rekordzahl.
  2. Sie haben ein hohes Volumen an Einfügungen und Löschungen.

Grund: Weil der Primärschlüssel ein geclustert Index!

Dies bedeutet, dass jeder in die Tabelle eingefügte Datensatz muss gehorchen die Beschränkungen des Indexes. Wenn der Index also nach ASC sortiert ist, muss der Datensatz mit der neu generierten GUID physisch und in der richtigen Reihenfolge in die betreffende Datentabelle eingefügt werden.

Dies wäre für eine Tabelle mit nur ein paar tausend Datensätzen oder so in Ordnung. SQL Server müsste nur eine Handvoll davon neu positionieren. Wenn die Datentabelle jedoch mehrere Millionen Datensätze enthält und der neue Datensatz in Zeile 216 eingefügt werden muss, kann dies (nach Web-Standards) eine beträchtliche Zeit in Anspruch nehmen. Es muss nämlich all diese Zeilen physisch nach unten verschieben, um den neuen Datensatz einzufügen.

Meine Frage ist also einfach die folgende. Da Microsoft und alle DBS, die wir kennen und lieben, NEIN zu GUIDs als Primärschlüssel gesagt haben... warum erstellt das ASPNET_REGSQL-Tool Tabellen mit einer GUID als Primärschlüssel?

Oder übersehe ich etwas? Gibt es eine neue Funktion in der SQL Profiler-Engine in 2008, die GUIDS nicht mehr als Aufgabe sieht?

3voto

Chris Shaffer Punkte 31499

Guids haben einige Vorteile: Wenn Sie beispielsweise Guids im Anwendungscode generieren, können sie in einer Webfarm generiert werden, ohne dass Sie sich Sorgen machen müssen, dass Sie am Ende dieselbe ID haben. Ein weiterer Vorteil ist, dass Seiten in der Datenbank gesperrt werden können, ohne dass es zu Problemen kommt, da es unwahrscheinlich ist, dass zwei zufällig ausgewählte Zeilen in derselben Datenseite vorhanden sind.

Was Ihre Aussage über mehrere Millionen Datenzeilen angeht, so sind Guids in Ordnung, solange Sie den SQL-Server immer um die Rückgabe einer einzigen Datenzeile bitten. Das größte Problem entsteht, wenn Sie eine große Teilmenge der Daten abfragen oder eine große Anzahl von Zeilen im Stapel einfügen. Dann werden Sie wahrscheinlich eine Menge zufälliger E/A durchführen, um alle Zeilen zu erhalten, die Ihren Kriterien entsprechen, oder alle Zeilen an den zufälligen Stellen einfügen, auf die die Guids am Ende zeigen. Außerdem muss SQL nicht "all diese Zeilen physisch nach unten verschieben, um die neue Zeile einzufügen"; Daten werden auf Seiten gespeichert, und SQL muss in der Regel nur die Daten auf einer Seite in der Datendatei ändern, um die Zeile einzufügen, möglicherweise mit ein paar anderen aktualisierten Seiten, aber es ist nicht wie das Einfügen einer Zeile in eine große Textdatei.

All das gesagt - ja, ich auch im Allgemeinen bevorzugen eine ganze Zahl für einen Primärschlüssel, aber wollte nur darauf hinweisen, dass es definitiv Situationen, in denen Guids einige Sinn machen.

1voto

Scott Mitchell Punkte 8549

Es spricht nichts dagegen, GUIDs als Primärschlüssel zu verwenden. Aber denken Sie an ein Szenario, in dem Sie verschiedene Datenbanken in Geschäften oder anderen Verkaufsstellen haben und jeden Abend alle Daten von jedem Standort in eine einzige Hauptdatenbank im Unternehmen zusammenführen müssen. GUIDs sind hier eine großartige Option, da Sie sich keine Sorgen um Identitätskonflikte machen müssen.

Jeder von ihnen hat mir gesagt, ich solle GUIDS nicht als Primärschlüssel verwenden, wenn ich eine Datenbank aufbaue ... denn der Primärschlüssel ist ein geclusterter Index!

Ein Primärschlüssel muss keinen geclusterten Index verwenden, das ist nur der Standard-Indextyp, der beim Erstellen eines Primärschlüssels verwendet wird.

Wenn Sie sich das Datenbankschema ansehen, das von der SqlMembershipProvider werden Sie sehen, dass es eine nicht geclustert Index auf die Primärschlüsselspalte.

Im Folgenden wird das SQL-Skript aus dem InstallCommon.sql Skript in %WINDIR%\Microsoft.NET\Framework\v4.0.30319 :

  CREATE TABLE [dbo].aspnet_Users (
    ApplicationId    uniqueidentifier    NOT NULL FOREIGN KEY REFERENCES [dbo].aspnet_Applications(ApplicationId),
    UserId           uniqueidentifier    NOT NULL PRIMARY KEY NONCLUSTERED DEFAULT NEWID(),
    UserName         nvarchar(256)       NOT NULL,
    LoweredUserName  nvarchar(256)       NOT NULL,
    MobileAlias      nvarchar(16)        DEFAULT NULL,
    IsAnonymous      bit                 NOT NULL DEFAULT 0,
    LastActivityDate DATETIME            NOT NULL)

   CREATE UNIQUE CLUSTERED INDEX aspnet_Users_Index ON [dbo].aspnet_Users(ApplicationId, LoweredUserName)
   CREATE NONCLUSTERED INDEX aspnet_Users_Index2 ON [dbo].aspnet_Users(ApplicationId, LastActivityDate)

Beachten Sie, dass die Primärschlüsselspalte ( UserId ) wird mit der Anweisung PRIMARY KEY NONCLUSTERED und dass die Tabelle CLUSTERED Index wird als zusammengesetzter Index auf ApplicationId y LoweredUserName .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X