List of databases
Name | Owner | Encoding | Collate | Ctype |
-------------------------+----------+----------+----------------------------+----------------------------|
MyDatabase | postgres | UTF8 | English_United States.1252 | English_United States.1252 |
Quelqu'un peut-il expliquer comment Encoding, Collate et Ctype sont liés les uns aux autres?
Je sais que l'encodage affecte la façon dont les informations sont réellement stockées (IE, que "A" nécessite un octet ou plusieurs octets, et quelle valeur ces octets ont, dépendent de l'encodage).
On m'a dit que l'assemblage spécifie les règles de comparaison des personnages. Si vous deviez trier un tas de chaînes, le type d'assemblage dicterait l'ordre.
J'ai eu du mal à trouver ce qu'est Ctype; peut-être lié à des concepts comme les majuscules et les minuscules (étant donné "a" sachant que "A" est la forme majuscule?).
Je ne comprends pas comment (comme dans mon exemple) je peux avoir une base de données encodée UTF8 et utiliser une valeur d'assemblage de l'anglais 1252. UTF8 a beaucoup de caractères que win1252 n'a pas; que se passe-t-il si j'essaie de les trier ou de les comparer? Ma configuration actuelle est-elle absurde ... il semble que je souhaiterais toujours que l'encodage/assemblage/le type soit d'accord?
Je sais que l'encodage affecte la façon dont les informations sont réellement stockées (IE si "A" nécessite un octet ou plusieurs octets, et quelle valeur ont ces octets, dépendent de l'encodage).
Oui. L'encodage est l'algorithme de conversion caractère-octet. Pour l'encodage mono-octet tel que LATIN1, c'est trivialement valeur = nombre de caractères, mais pour UTF-8 c'est plus compliqué.
On m'a dit que l'assemblage spécifie les règles de comparaison des personnages. Si vous deviez trier un tas de chaînes, le type d'assemblage dicterait l'ordre.
Oui, collate spécifie comment les chaînes sont comparées. Le service de classement est fourni par le système d'exploitation ou éventuellement par la bibliothèque ICU pour PostgreSQL 10 ou plus récent. Le tri de chaînes arbitraires avec des règles linguistiques est une entreprise compliquée. La norme Unicode et l'ISO fournissent des règles mais elles sont fortement personnalisables et toutes les bibliothèques C ne les implémentent pas complètement de toute façon. Voir par exemple https://en.wikipedia.org/wiki/Unicode_collation_algorithm pour en savoir plus.
J'ai eu du mal à trouver ce qu'est Ctype; peut-être lié à des concepts comme les majuscules et les minuscules (étant donné "a" sachant que "A" est la forme majuscule?).
LC_CTYPE dans POSIX est lié aux fonctions dans ctype.h Postgres est fortement influencé par POSIX à cet égard et utilise une base de données par lc_ctype
plus ou moins comme POSIX utilise LC_CTYPE
.
Mis à part upper () et lower (), il est également pertinent pour les expressions régulières et la recherche en texte intégral (casse des jetons).
Je pense que Postgres pourrait se passer d'un lc_ctype indépendant (en utilisant la même valeur que lc_collate) sauf pour une chose: c'est intéressant d'avoir lc_ctype
à something.UTF-8
par exemple, pour que la gamme complète de caractères soit correctement prise en charge, et lc_collate
à C
parce que C comme classement est beaucoup plus rapide que tout tri linguistique impliqué par lc_collate=lang_country.UTF-8
.
Robert Haas (committer postgres) a écrit un article intéressant sur essentiellement ce sujet lorsque le support COLLATE a été amélioré dans Postgres: "Les dangers des comparaisons conscientes de la collation"
Je ne comprends pas comment (comme dans mon exemple) je peux avoir une base de données encodée UTF8 et utiliser une valeur d'assemblage de l'anglais 1252. UTF8 a beaucoup de caractères que win1252 n'a pas
Ceci est spécifique à Windows, car Windows ne suit pas le modèle POSIX avec les paramètres régionaux et les classements. Sous Windows et avec des classements non ICU, Postgres convertira les chaînes du codage db en UTF-16 (wchar_t
) et appelez wcscoll_l () . C'est pourquoi l'encodage est décorrélé des classements.
Avec ICU classements, soit Postgres transmet directement le contenu UTF-8 s'il le peut, soit il convertit les chaînes en UTF-16, donc encore une fois les classements ne sont pas liés à un codage de base de données particulier, contrairement à la Modèle POSIX et sa famille de fonctions strcoll.