Ich entwerfe eine Datenbank, in der Daten in verschiedenen Sprachen gespeichert werden (unter Verwendung von UTF-8). Ich denke, die beste Möglichkeit, die Ergebnisse der Abfrage anzuzeigen, besteht darin, sie gemäß der Sprache des Benutzers während der Abfrage selbst zu ordnen ( da es mehr als eine gibt) richtige Art und Weise zu tun , dass ), wie folgt:
SELECT a < b COLLATE "de_DE" FROM test1;
Angenommen, dies ist die richtige Art und Weise, mit internationalen Daten zu arbeiten. Welches ist die beste Sortierung für die Datenbank selbst? In der PostgreSQL-Dokumentation heißt es :
Die Sortierungen C und POSIX geben das "traditionelle C" -Verhalten an, bei dem nur die ASCII-Buchstaben "A" bis "Z" als Buchstaben behandelt werden, und die Sortierung erfolgt streng nach Zeichencode-Bytewerten.
Ich denke, das ist die beste Wahl in diesem Fall, oder irre ich mich?
(Bonusfrage: Ist es zu langsam, die Sortierung in der Abfrage selbst auszuwählen?)
Antworten:
Die
C
Zusammenstellung ist die richtige Wahl.Ohne Gebietsschema ist alles etwas schneller. Und da ohnehin keine Sortierung richtig ist, erstellen Sie die Datenbank ohne Sortierung, dh mit
C
.Es kann schwierig sein, für viele Operationen eine Sammlung bereitzustellen. Es sollte jedoch keinen merklichen Geschwindigkeitsunterschied zwischen der Standardkollatierung und einer Ad-hoc-Kollatierung geben. Schließlich handelt es sich nur um unsortierte Daten, und beim Sortieren werden Sortierungsregeln angewendet.
Beachten Sie, dass Postgres auf den Gebietsschemaeinstellungen aufbaut, die vom zugrunde liegenden Betriebssystem bereitgestellt werden. Daher müssen für jedes zu verwendende Gebietsschema Gebietsschemas generiert werden. Mehr in verwandter Antwort auf SO hier und hier .
Wie @Craig bereits erwähnte , sind Indizes der Engpass in diesem Szenario. Die Kollatierung des Index muss in vielen Fällen mit der Kollatierung des angewendeten Operators übereinstimmen, bei denen es sich um Zeichendaten handelt.
Sie können den
COLLATE
Bezeichner in Indizes verwenden, um übereinstimmende Indizes zu erstellen. Teilindizes sind möglicherweise die perfekte Wahl, wenn Sie Daten in derselben Tabelle mischen.Zum Beispiel eine Tabelle mit internationalen Zeichenfolgen:
Und Sie interessieren sich hauptsächlich für jeweils eine Sprache:
Dann erstelle Teilindizes wie:
Eine für jede Sprache, die Sie benötigen.
Tatsächlich könnte die Vererbung für eine Tabelle wie diese ein überlegener Ansatz sein. Dann können Sie für jede geerbte Tabelle einen einfachen Index erstellen, der nur Zeichenfolgen für ein einzelnes Gebietsschema enthält. Natürlich müssen Sie mit den Sonderregeln für geerbte Tabellen vertraut sein.
quelle
Ich schlage vor, dass Sie eine Sortierung auswählen, die die Standard-Unicode-Reihenfolge bietet. Auf diese Weise erhalten Sie vernünftige Ergebnisse, auch wenn Sie die Sortierung in jeder Abfrage nicht überschreiben. Leider bieten die meisten (alle?) Betriebssysteme kein Gebietsschema mit dem Namen "Standard-Unicode" oder ähnlichem an, sodass Sie eine gute Wahl treffen und / oder nachforschen müssen. Unter Linux / glibc durchlaufen die Gebietsschemas de_DE.utf8 oder en_US.utf8 einfach das Standardverhalten. Beide sind also eine gute Wahl.
Ich halte die Verwendung des Gebietsschemas C nicht für eine gute Idee, da das Standardverhalten Ihrer Anwendung dann unbrauchbar wird. Und bei Konvertierungsvorgängen für Groß- und Kleinschreibung tritt möglicherweise kein ordnungsgemäßes Verhalten auf.
(Das Überschreiben der Kollatierung in einer Abfrage ist nicht sehr aufwändig. Es handelt sich lediglich um eine Syntaxanalyse.)
quelle
utf8_unicode_ci
der richtige Weg ist .Wir verwenden Postgres in einem Docker-Container, daher haben wir immer die ICU zur Verfügung und verwenden sie
und-x-icu
als Standard.Dies wird in Kapitel 23.2.2.2.2 erwähnt. ICU- Kollatierungen der postres docs erwähnen:
quelle