Je conçois une base de données qui stockera des données dans différentes langues (en utilisant UTF-8), donc je pense que la meilleure façon d'afficher les résultats de la requête est de les ordonner en fonction de la langue de l'utilisateur pendant la requête elle-même ( car il y en a plusieurs bonnes façons de le faire ), comme suit:
SELECT a < b COLLATE "de_DE" FROM test1;
En supposant que c'est la bonne façon de travailler avec des données internationales, quel est le meilleur classement pour la base de données elle-même? La documentation PostgreSQL dit :
Les classements C et POSIX spécifient tous deux un comportement "C traditionnel", dans lequel seules les lettres ASCII "A" à "Z" sont traitées comme des lettres, et le tri est strictement effectué par des valeurs d'octets de code de caractère.
Je pense que c'est le meilleur choix dans ce cas, ou je me trompe?
(Question bonus: est-il trop lent pour sélectionner le classement dans la requête elle-même?).
Réponses:
Le
C
classement est le bon choix.Tout est un peu plus rapide sans locale. Et comme aucun classement n'est correct de toute façon, créez la base de données sans classement, c'est-à-dire avec
C
.Il peut être difficile de devoir fournir un classement pour de nombreuses opérations. Cependant, il ne devrait pas y avoir de différence notable de vitesse entre le classement par défaut et un classement ad hoc. Après tout, ce ne sont que des données non triées et des règles de classement sont appliquées lors du tri.
Sachez que Postgres s'appuie sur les paramètres régionaux fournis par le système d'exploitation sous-jacent, vous devez donc générer des paramètres régionaux pour chaque paramètre régional à utiliser. Plus dans la réponse connexe sur SO ici et ici .
Cependant, comme @Craig l'a déjà mentionné , les index sont le goulot d'étranglement dans ce scénario. Le classement de l'index doit correspondre au classement de l'opérateur appliqué dans de nombreux cas qui impliquent des données de caractères.
Vous pouvez utiliser le
COLLATE
spécificateur dans les index pour produire des index correspondants. Les index partiels peuvent être le choix parfait si vous mélangez des données dans la même table.Par exemple, une table avec des chaînes internationales:
Et vous êtes surtout intéressé par une langue à la fois:
Créez ensuite des index partiels comme:
Un pour chaque langue dont vous avez besoin.
En fait, l' héritage pourrait être une approche supérieure pour une table comme celle-ci. Ensuite, vous pouvez avoir un index simple sur chaque table héritée contenant uniquement des chaînes pour un seul paramètre régional. Vous devez bien sûr être à l'aise avec les règles spéciales pour les tables héritées.
la source
Je vous suggère de choisir un classement qui fournit la commande Unicode par défaut. De cette façon, vous obtenez des résultats raisonnables même si vous ne remplacez pas le classement dans chaque requête. Malheureusement, la plupart (tous?) Des systèmes d'exploitation ne fournissent pas de paramètres régionaux qui sont simplement appelés "Unicode par défaut" ou quelque chose comme ça, vous devrez donc deviner et / ou rechercher un bon choix. Par exemple, sur Linux / glibc, les paramètres régionaux de_DE.utf8 ou en_US.utf8 passent simplement par le comportement par défaut, donc les deux sont de bons choix.
Je ne pense pas que l'utilisation des paramètres régionaux C soit une bonne idée, car le comportement par défaut de votre application sera alors inutile. Et vous pourriez ne pas obtenir un comportement correct des opérations de conversion de cas.
(Remplacer le classement dans une requête n'a pas beaucoup de surcharge. C'est juste une opération d'analyse.)
la source
utf8_unicode_ci
la voie à suivre .Nous utilisons postgres dans un conteneur docker, donc nous avons toujours ICU disponible et utilisons
und-x-icu
par défaut.Ceci est mentionné au chapitre 23.2.2.2.2. Les classements ICU des postres docs mentionnent:
la source