Der standardmäßige Sortierungstyp in SQL Server ermöglicht die Indizierung von Zeichenfolgen, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird, wobei die Groß- und Kleinschreibung der Daten beibehalten wird. Wie funktioniert das eigentlich? Ich suche nach den richtigen Schrauben und Muttern, nach Bits und Bytes oder nach einer guten Ressource, die es ausführlich erklärt.
create table casetest (fruitnames nvarchar(50) not null);
create unique index IX_fruitnames on casetest(fruitnames);
insert into casetest values ('apples');
insert into casetest values ('Pears');
-- this insert fails
insert into casetest values ('pears');
-- this yields 'Pears' as a result
select * from casetest (forceseek) where fruitnames = 'PEARS'
update casetest set fruitnames = 'pears' where fruitnames = 'pEArs'
-- this yields 'pears' as a result
select * from casetest (forceseek) where fruitnames = 'PEARS'
Fragen zu SQL Server-Kollatierungen, die Sie zu schüchtern gestellt haben Robert Sheldon behandelt die Verwendung der Kollatierung. Es wird nicht behandelt, wie die Sortierung funktioniert. Ich bin daran interessiert, wie ein Index effizient erstellt / abgefragt werden kann, ohne sich um den Fall zu kümmern, während gleichzeitig Falldaten gespeichert werden.
quelle
Antworten:
Dies ist eigentlich kein SQL Server-spezifisches Verhalten, es ist nur so, wie diese Dinge im Allgemeinen funktionieren.
Die Daten sind also die Daten. Wenn Sie speziell über einen Index sprechen, die Daten müssen gespeichert werden , wie es ist , sonst wäre es eine Nachschau in der Haupttabelle jedes Mal benötigt den tatsächlichen Wert zu erhalten, und es gäbe keine Möglichkeit einen abdeckenden Index (zumin zumindest nicht für String-Typen).
Die Daten, die entweder in der Tabelle / gruppierten Index oder nicht gruppierten Index, sind nicht enthalten jede Kollation / Sortieranlagen info. Es sind einfach Daten. Die Sortierung (Gebietsschema / Kulturregeln und Sensitivitäten) besteht nur aus Metadaten, die an die Spalte angehängt sind und verwendet werden, wenn eine Sortieroperation aufgerufen wird (sofern sie nicht von einem überschrieben wird)
COLLATE
Klausel), die die Erstellung / Neuerstellung eines Indexes umfassen würde. Die durch eine nicht-binäre Kollatierung definierten Regeln werden verwendet, um Sortierschlüssel zu generieren, die binäre Darstellungen der Zeichenfolge sind (Sortierschlüssel sind in binären Kollatierungen nicht erforderlich). Diese binären Darstellungen enthalten alle Regeln für das Gebietsschema / die Kultur und ausgewählte Empfindlichkeiten. Die Sortierschlüssel werden verwendet, um die Datensätze in der richtigen Reihenfolge zu platzieren, werden jedoch nicht selbst im Index oder in der Tabelle gespeichert. Sie werden nicht gespeichert (zumindest habe ich diese Werte nicht im Index gesehen und wurde darüber informiert, dass sie nicht gespeichert werden), weil:Es gibt zwei Arten von Kollatierungen: SQL Server und Windows.
SQL Server
SQL Server-Kollatierungen (mit Namen, die mit beginnen
SQL_
) sind die älteren Sortier- / Vergleichsmethoden vor SQL Server 2000 (obwohl dies unter US-englischen Betriebssystemen leiderSQL_Latin1_General_CP1_CI_AS
immer noch die Standardinstallation ist). In diesem älteren, vereinfachten Nicht-Unicode-Modell wird jeder Kombination aus Gebietsschema, Codepage und den verschiedenen Empfindlichkeiten eine statische Zuordnung der einzelnen Zeichen in dieser Codepage gegeben. Jedem Zeichen wird ein Wert (dh ein Sortiergewicht) zugewiesen, der angibt, wie es mit den anderen Zeichen gleichgesetzt wird. Vergleiche in diesem Modell scheinen eine Operation mit zwei Durchläufen durchzuführen:Die einzigen Empfindlichkeiten, die in diesen Kollatierungen eingestellt werden können, sind: "case" und "accent" ("width", "kana type" und "variant selector" sind nicht verfügbar). Außerdem unterstützt keine dieser Kollatierungen zusätzliche Zeichen (was sinnvoll ist, da diese Unicode-spezifisch sind und diese Kollatierungen nur für Nicht-Unicode-Daten gelten).
Dieser Ansatz gilt nur für Nicht-Unicode-
VARCHAR
Daten. Jede eindeutige Kombination aus Gebietsschema, Codepage, Groß- und Kleinschreibung und Akzentabhängigkeit verfügt über eine bestimmte "Sortier-ID", die Sie im folgenden Beispiel sehen können:Der einzige Unterschied zwischen den ersten beiden Kollatierungen ist die Groß- und Kleinschreibung. Die dritte Kollatierung ist eine Windows-Kollatierung und verfügt daher nicht über eine statische Zuordnungstabelle.
Außerdem sollten diese Sortierungen schneller als die Windows-Sortierungen sortiert und verglichen werden, da einfach nach Zeichen gesucht wird, um die Gewichtung zu sortieren. Diese Kollatierungen sind jedoch auch weitaus weniger funktional und sollten im Allgemeinen nach Möglichkeit vermieden werden.
Windows
Windows-Kollatierungen (solche mit Namen, die nicht mit beginnen
SQL_
) sind die neueren Sortier- / Vergleichsmethoden (ab SQL Server 2000). In diesem neueren, komplexen Unicode-Modell wird jeder Kombination aus Gebietsschema, Codepage und den verschiedenen Empfindlichkeiten keine statische Zuordnung zugewiesen. Zum einen gibt es in diesem Modell keine Codepages. Dieses Modell weist jedem Zeichen einen Standardsortierwert zu. Anschließend kann jedes Gebietsschema / jede Kultur jeder beliebigen Anzahl von Zeichen Sortierwerte zuweisen. Auf diese Weise können mehrere Kulturen dieselben Zeichen auf unterschiedliche Weise verwenden. Dies hat den Effekt, dass mehrere Sprachen auf natürliche Weise mit derselben Sortierung sortiert werden können, wenn sie nicht dieselben Zeichen verwenden (und wenn einer von ihnen keine Werte neu zuweisen muss und einfach die Standardwerte verwenden kann).Die Sortierwerte in diesem Modell sind keine Einzelwerte. Sie sind ein Array von Werten, die dem Basisbuchstaben, diakritischen Zeichen (dh Akzenten), Groß- und Kleinschreibung usw. relative Gewichte zuweisen. Wenn bei der Kollatierung die Groß- und Kleinschreibung beachtet wird, wird der Teil "case" dieses Arrays verwendet, andernfalls wird er ignoriert ( daher unempfindlich). Wenn die Sortierung akzentabhängig ist, wird der "diakritische" Teil des Arrays verwendet, andernfalls wird er ignoriert (daher unempfindlich).
Vergleiche in diesem Modell sind eine Operation mit mehreren Durchläufen:
Weitere Einzelheiten zu dieser Sortierung, werde ich veröffentlichen schließlich einen Beitrag , dass zeigt die Sortierschlüsselwerte, wie sie berechnet werden, die Unterschiede zwischen SQL Server und Windows - Sortierungen etc. Aber jetzt bitte meine Antwort sehen: Accent Sensitive Sort ( Bitte beachten Sie, dass die andere Antwort auf diese Frage eine gute Erklärung des offiziellen Unicode-Algorithmus ist, SQL Server jedoch stattdessen einen benutzerdefinierten, wenn auch ähnlichen Algorithmus und sogar eine benutzerdefinierte Gewichtstabelle verwendet.
In diesen Kollatierungen können alle Empfindlichkeiten angepasst werden: "Groß- / Kleinschreibung", "Akzent", "Breite", "Kana-Typ" und "Variationsauswahl" (ab SQL Server 2017 und nur für japanische Kollatierungen). Außerdem unterstützen einige dieser Sortierungen (bei Verwendung mit Unicode-Daten) zusätzliche Zeichen (ab SQL Server 2012). Dieser Ansatz gilt für beide
NVARCHAR
undVARCHAR
Daten (auch Nicht-Unicode - Daten). Dies gilt für Nicht-Unicode-VARCHAR
Daten, indem zunächst der Wert intern in Unicode konvertiert und anschließend die Sortier- / Vergleichsregeln angewendet werden.Bitte beachten Sie:
SQL_Latin1_General_CP1_CI_AS
für US-englische Systeme gilt, stimmen Sie also für diesen Vorschlag ab ). Dies kann während der Installation geändert werden. Diese Kollatierung auf Instanzebene legt dann die Kollatierung für die[model]
Datenbank fest, die beim Erstellen neuer DBs als Vorlage verwendet wird. Die Kollatierung kann jedoch bei der AusführungCREATE DATABASE
durch Angabe derCOLLATE
Klausel geändert werden . Diese Kollatierung auf Datenbankebene wird für Variablen- und Zeichenfolgenliterale sowie für neue (und geänderte!) Spalten verwendet, wenn dieCOLLATE
Klausel nicht angegeben ist (was für den Beispielcode in der Frage der Fall ist).quelle
In der Regel wird dies mithilfe von Sortiertabellen implementiert, die jedem Zeichen eine bestimmte Punktzahl zuweisen. Die Sortierroutine verfügt über einen Komparator, der eine geeignete Tabelle verwendet, ob standardmäßig oder explizit angegeben, um Zeichenfolgen zeichenweise anhand ihrer Sortierergebnisse zu vergleichen. Wenn beispielsweise eine bestimmte Sortiertabelle eine Bewertung von 1 bis "a" und 201 bis "A" zuweist und eine niedrigere Bewertung in dieser bestimmten Implementierung eine höhere Priorität bedeutet, wird "a" vor "A" sortiert. Eine andere Tabelle weist möglicherweise umgekehrte Bewertungen zu: 201 bis "a" und 1 bis "A", und die Sortierreihenfolge wird anschließend umgekehrt. Noch eine andere Tabelle könnte "a", "A", "Á" und "Å" gleiche Werte zuweisen, was zu einem Vergleich und einer Sortierung führen würde, bei denen die Groß- und Kleinschreibung nicht beachtet wird.
In ähnlicher Weise wird ein solcher auf einer Kollationstabelle basierender Komparator verwendet, wenn ein Indexschlüssel mit dem im Prädikat angegebenen Wert verglichen wird.
quelle
SQL_
) korrekt, wenn sie fürVARCHAR
Daten verwendet werden. Dies gilt nicht genau fürNVARCHAR
Daten oderVARCHAR
Daten, wenn eine Windows-Kollatierung verwendet wird (Namen, die nicht mit beginnenSQL_
).