Indizierung gegen Zeichenfolgen, bei denen die Groß- und Kleinschreibung nicht beachtet wird. Die Groß- und Kleinschreibung der Daten wird jedoch beibehalten. Wie funktioniert das eigentlich?
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:
- Sie werden für die Sortierung nicht wirklich benötigt, da sie ohnehin nur in derselben Reihenfolge wie die Zeilen in der Tabelle oder im Index vorliegen würden. Die physische Reihenfolge des Indexes ist jedoch nur Sortieren, nicht Vergleichen.
- Während das Speichern die Vergleiche beschleunigt, vergrößert sich der Index, da die Mindestgröße für ein einzelnes Zeichen 5 Byte beträgt, und das ist nur "Overhead" (der Sortierschlüsselstruktur). Die meisten Zeichen bestehen aus jeweils 2 Byte plus 1 Byte, wenn ein Akzent vorhanden ist, plus 1 Byte, wenn es sich um Großbuchstaben handelt. Beispielsweise ist "e" ein 7-Byte-Schlüssel, "E" und "é" sind beide 8 Byte und "É" ist ein 9-Byte-Schlüssel. Daher lohnt es sich nicht, diese am Ende zu speichern.
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 leider SQL_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:
- Zuerst werden alle Akzente entfernt (so dass " ü " zu " u " wird), Zeichen wie " Æ " zu " A " und " E " erweitert und dann eine erste Sortierung durchgeführt, sodass die Wörter in einer natürlichen Reihenfolge sind (wie Sie es tun würden) erwarten, sie in einem Wörterbuch zu finden).
- Dann wird Zeichen für Zeichen die Gleichheit anhand dieser zugrunde liegenden Werte für jedes Zeichen ermittelt. Dieser zweite Teil beschreibt mustaccio in seiner Antwort .
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:
SELECT COLLATIONPROPERTY(N'SQL_Latin1_General_CP1_CI_AS', 'SortID'), -- 52
COLLATIONPROPERTY(N'SQL_Latin1_General_CP1_CS_AS', 'SortID'), -- 51
COLLATIONPROPERTY(N'Latin1_General_100_CI_AS', 'SortID'); -- 0
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:
- Zunächst wird die Zeichenfolge normalisiert, sodass verschiedene Darstellungsweisen für dasselbe Zeichen gleich sind. Beispielsweise könnte " ü " ein einzelnes Zeichen / Code-Punkt (U + 00FC) sein. Sie können auch ein nicht akzentuiertes " u " (U + 0075) mit einer kombinierten Diaeresis " ̈ " (U + 0308) kombinieren , um Folgendes zu erhalten: " ü ", das nicht nur beim Rendern gleich aussieht (es sei denn, es liegt ein Problem mit vor) Ihre Schriftart), wird aber auch als dieselbe wie die Einzelzeichenversion (U + 00FC) angesehen, sofern keine binäre Kollatierung verwendet wird (die Bytes anstelle von Zeichen vergleicht). Bei der Normalisierung wird das einzelne Zeichen in verschiedene Teile aufgeteilt, einschließlich der Erweiterungen für Zeichen wie " Æ " (wie oben für SQL Server-Kollatierungen angegeben).
- Die Vergleichsoperation in diesem Modell erfolgt zeichenweise für jede Empfindlichkeit . Sortierschlüssel für die Zeichenfolgen werden durch Anwenden der entsprechenden Elemente der Sortierreihenfolge der einzelnen Zeichen von Werten bestimmt, auf deren Grundlage die Empfindlichkeiten "empfindlich" sind. Die Sortierschlüsselwerte sind nach allen primären Empfindlichkeiten jedes Zeichens (dem Basiszeichen), gefolgt von allen sekundären Empfindlichkeiten (diakritischem Gewicht), gefolgt von dem Fallgewicht jedes Zeichens usw. angeordnet.
- Die Sortierung erfolgt anhand der berechneten Sortierschlüssel. Mit jeder Sensitivität, die in Gruppen zusammengefasst ist, können Sie beim Vergleichen von Zeichenfolgen mit mehreren Zeichen eine andere Sortierreihenfolge erhalten als mit einer entsprechenden SQL Server-Kollatierung. Dabei handelt es sich um Akzente auch Groß- und Kleinschreibung beachten).
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
und VARCHAR
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:
- Es gibt keine universelle Standardkollatierung für SQL Server. Es gibt einen Installationsstandard, der sich basierend auf der aktuellen Ländereinstellung / Spracheinstellung des Betriebssystems zum Zeitpunkt der Installation unterscheidet (was leider
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ührung CREATE DATABASE
durch Angabe der COLLATE
Klausel geändert werden . Diese Kollatierung auf Datenbankebene wird für Variablen- und Zeichenfolgenliterale sowie für neue (und geänderte!) Spalten verwendet, wenn die COLLATE
Klausel nicht angegeben ist (was für den Beispielcode in der Frage der Fall ist).
- Weitere Informationen zu Kollatierungen / Kodierungen / Unicode finden Sie unter: Kollatierungsinformationen