Non j'ai juste appelé dans mon coin la collation dont on parle depuis des pages comme ça :
Code:create collation fr_ci_ai (provider = icu, locale = 'fr-u-ks-level1-kc-false', deterministic=false);
Version imprimable
Non j'ai juste appelé dans mon coin la collation dont on parle depuis des pages comme ça :
Code:create collation fr_ci_ai (provider = icu, locale = 'fr-u-ks-level1-kc-false', deterministic=false);
SQLpro qui se pose en victime ! J'aurais tout lu :ptdr:
Tu cherches ce genre de réaction de la part de tout le monde. A la moindre occasion, tu défonces les gens.
T'es une publicité vivante pour SQL Server et en plus tu n'as aucun tact ni doigté. En face, ce n'est pas que des neuneus non plus.
T'es le style de gars à se poser là où se posent ses fesses même si c'est la bouche de quelqu'un d'autre, mais bon, la vie en général ne fonctionne pas ainsi. Tu y gagnerais à être plus cool et nous aussi au passage.
C'est un forum d'entraide, de débats et surtout à l'ambiance "bon enfant" et cela d'autant plus que ce n'est pas de la politique mais de l'informatique et de la technique.
Reste cool, :ccool:
En fait non parce que tes exemples utilisent uniquement %, pas de _
et surtout parce que french_ci_ai ne comprend aucune suppression de caractères (ou alors tu dois trouver un exemple de caractère qui est équivalent à une chaîne vide)
donc ce n'est pas le même problème!
On ne l'aurait peut-être pas fait si l'article en question ne contenait pas des "bilans comparatifs" bien en évidence en rouge:
Et évidemment ça n'a jamais été le but de prouver cela, non pas du tout...
Et évidemment ça n'a jamais été le but de prouver cela, non pas du tout...
Bizarre je viens de refaire le test et ça marche chez moi (Debian 9):
C'est surtout SQLPro qui est encore plus de mauvaise foi que je le croyais: il ne comprend même pas que quand il y a un message "le collationnement « fr_ci_ai » pour l'encodage « UTF8 » n'existe pas" ça peut vouloir signifier que ce collationnement n'a pas été créé, et donc que l'auteur du message précédent a juste oublié de mettre la commande CREATE COLLATION dans le code présent dans son message, juste parce qu'il l'avait appelée bien avant...Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 testICU=# insert into t_accents2(datum) VALUES ('veau'), ('vache'), ('cochon'), ('éléphant'); INSERT 0 4 testICU=# select * from t_accents2 where datum = 'elephant'; id | datum --------+---------- 100013 | éléphant (1 row) testICU=# select * from t_accents2 where datum IN ('veau', 'elephant'); id | datum --------+---------- 100013 | éléphant 100010 | veau (2 rows)
Bonjour Frédéric,
Je ne reproduis pas ce phénomène, avec DB fiddle et PG 12 voici le résultat :
Pièce jointe 540234
Je ne connais pas l'encodage interne de ICU, mais Java utilise :Citation:
Dans ma compréhension actuelle du sujet, les problèmes de performance avec UTF8 viennent principalement du fait que Microsoft a poussé dans son coin pour UTF16.
ICU vient de Sun Microsystem et du monde Java, donc c'est normal qu'il reste quelques problèmes.
- Historiquement une version pétée d'UTF-16 en représentation interne
- Depuis Java 9, LATIN-1 pour toutes les chaines de caractères représentables dans cet encodage, et la version pétée d'UTF-16 sinon
Pourquoi «*Une version pétée d'UTF-16*?*»
Parce que si UTF-16 est une représentation à longueur variable des caractères, en pratique jusqu'à il y a environ 10 ans, personne n'utilisait les points de code Unicode qui ont besoin de 2 mots dans cette représentation : les caractères en question, c'était quelques langues antiques, et donc on pouvait se permettre de les gérer manuellement.
Sauf que depuis, on a ajouté les emojis. Qui nécessitent pratiquement tous 2 mots en UTF-16. Et qui ne tiennent donc plus dans un «*char*» en Java (il en faut 2, cf la notion de «*surrogate pair*»). Et qui sont utilisés absolument partout.
Du coup la remarque qui veut que MS SQL Server serait plus performant parce qu'il utilise UTF-16 (ou je ne sais quelle représentation interne sur 16 bits) au lieu d'UTF-8 m'étonne : soit la représentation ne gère pas tous les caractères Unicode (plus d'un million, ce qui ne tient pas sur 16 bits) et donc MS SQL*Server est limité (typiquement au Basi _Multilingual Plane d'Unicode), soit il utilise une représentation à longueur variable auquel cas l'argument de la performance ne tient plus.
PS : c'est normal que le forum remplace toutes mes espaces insécables par des étoiles ?!
StringBuilder, déjà je te remercie d'avoir vraiment tenté de répondre à la question, plutôt que d'essayer comme une autre personne qui se reconnaîtra de noyer l'ignorance dans des copier-coller totalement hors sujet.
C'est peut-être justement parce que le cas de figure que j'évoque n'existe pas avec les collations SQL Server qu'ils peuvent se permettre de traiter correctement le LIKE sans ambiguïté. Je dis bien peut-être, puisque comme elles ne sont pas documentées, on ne peut pas en être sûr. Alors essayons d'y réfléchir.
Examinons un peu les 4 "flags" :
- c rend insensible à la casse, donc fait que C <=> c, É <=> é, et même peut-être ß <=> SS
- a rend insensible à tous les signes diacritiques, donc fait que é <=> e, œ <=> oe
- k rend insensible aux différences hiragana/katakana, donc fait que タ <=> た
- w rend insensible à la largeur, donc fait que ² <=> 2 et タ <=> タ
Si je regarde toutes ces équivalences, je remarque une chose importante: même si parfois la longueur diffère, à chaque fois, ni ce qu'il y a à gauche ni à droite n'est vide. Or, dans 'und(at)colAlternate=shifted', je remarque tout de suite que l'équivalent des ponctuations c'est... l'absence de ponctuation. Il est fort possible que ce détail, que j'appellerai substitution vide dans la suite de ce message, crée une ambiguïté dans la signification de l'opérateur _ du LIKE, ambiguïté qui n'existe pas quand toutes les substitutions sont non vides!
Oui, et du coup tu peux comprendre qu'à partir du moment où il y a des équivalences avec un côté vide, le joker _ peut avoir deux interprétations: est-ce qu'on parle d'un seul caractère avant ou après avoir fait la substitution? Faute de trancher, pour le moment l'auteur de l'implémentation a choisi de bloquer cette fonction, quitte à pouvoir y revenir plus tard. Et si on pouvait trouver un autre SGBD qui a résolu ce problème, alors on pourrait vouloir implémenter la même solution que lui, pour permettre la compatibilité. C'est bien la raison pour laquelle la question de savoir ce que fait SQL Server dans ce cas-là est pertinente.
à défaut d'opérateur LIKE, on peut quand même tester ça avec l'opérateur d'égalité, qui lui fonctionne bien avec les collations non déterministes.
Donc oui, les espaces font bien partie des caractères ignorés.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 testICU=# CREATE COLLATION "nd3alt" ( provider = 'icu', locale='und@colAlternate=shifted', deterministic = false ); CREATE COLLATION testICU=# create table test_nopunkt (data text collate "nd3alt"); CREATE TABLE testICU=# insert into test_nopunkt values ('abc. ...de'); INSERT 0 1 testICU=# select * from test_nopunkt where data = 'abcde'; data ------------ abc. ...de (1 row)
Ton interprétation repose sur le fait que _ signifie 1 caractère non-ignoré. Je ne dis pas que c'est une mauvaise interprétation, je dis juste que dès qu'on parle d'ignorer des caractères, ce n'est pas/plus la seule interprétation possible.
Déjà, ce ne sont pas les collations PostgreSQL, mais les collations ICU. PostgreSQL n'a pas ses propres collations mais plusieurs providers, ICU n'étant que l'un d'entre eux.
Comme l'a remarqué ensuite MaximeCH, la notion de collations non déterministes n'est pour le moment utilisée que par le provider ICU. Au passage au cours de mes recherches je suis tombé sur un article très intéressant, notamment pour comprendre les options ICU, surtout l'option colStrength qui n'est pas évidente de prime abord. On y apprend notamment (section 8) que toutes les collations ICU de niveau inférieur à 3 ignorent systématiquement les caractères de contrôle. D'où on peut conclure facilement que toutes ces collations font au moins une substitution vide! Et donc, pas possible d'implémenter LIKE pour les collations ICU non-déterministes mais sans substitution vide, puisqu'il n'y en a pas!
Un autre point que je connaissais mais que l'article m'a rappelé (section 1): toutes les collations ICU implémentent l'équivalence canonique, donc 'é' = 'é' (ça ne se voit pas mais la chaîne de gauche contient en réalité deux caractères Unicode, l'accent étant codé séparément de la lettre principale). Est-ce le cas des collations SQL Server? Pour en revenir au LIKE, est-ce que _ devrait accepter é mais refuser é (qui contient 2 caractères), alors que = l'accepterait? Vous voyez, ce n'est pas simple...
Voir l'ajout que j'ai fait ce matin ici: si tu trouves que les collations SQL Server sont mieux, rien ne t'empêche de créer un provider pour les implémenter. Enfin si, il y a bien quelque chose qui t'en empêche: elles ne sont pas documentées...
En tant que développeur, j'apprécie le fait que PosgreSQL donne accès à des librairies externes comme ICU plutôt que d'implémenter les choses lui-même. L'avantage, c'est que je peux aussi utiliser la librairie ICU dans un programme n'ayant aucun lien avec une base de données, et si un jour ce programme communique avec PostgreSQL, on est certain que les collations fonctionneront de la même façon. Allez donc faire la même chose avec les collations non documentées de SQL Server...
J'ai vaguement vu dans la doc Elastic l'emploi de filtre "should", qui nécessiterait sûrement un peu de se creuser la tête pour faire la même chose dans un where.
Elastic c'est sûrement très bien dans une stack hadoop (inefficace), mais probablement inutile au-dessus d'un SGBD.
D'ailleurs quand je lis ça :
https://www.elastic.co/fr/blog/how-t...using-logstash
:roll:
Je suis très d'accord.
Notons quand même que les cubes existaient avant MS (chez Hyperion par exemple) et répondait bien à une problématique de la fin des années 1990 / début des années 2000 d'analyse de données.
Mais depuis les bases de données (et le reste) a énormément progressé, l'intérêt des cubes reste très discutable.
Merci à escartefigue d'avoir parlé de DB Fiddle, que je ne connaissais pas. Alors du coup j'ai cherché un équivalent SQL Server et j'ai trouvé SQL Fiddle, qui supporte MS SQL Server 2017.
Alors allons-y:
Précision importante, le contenu de la chaîne qui apparaît comme e&769; est en fait un é encodé sur 2 caractères: le &769; correspond au point Unicode 769, ou en hexadécimal 0301, qui correspond à l'accent aigu dans les diacritiques génériques.Code:
1
2
3
4 CREATE TABLE T_ACCENTS (ID INT IDENTITY PRIMARY KEY, DATUM VARCHAR(256) COLLATE French_CS_AI); insert into t_accents(datum) values ('é');
Du coup en Unicode é a deux représentations, une sur 1 caractère et une sur 2. La seconde rend les traitements linguistiques plus facile, mais elle prend évidemment plus de place.
C'est la balise CODE du forum qui le montre sous cette forme: moi j'ai utilisé un convertisseur Unicode pour insérer réellement le caractère accent aigu dans le texte.
Et maintenant :avec cette fois un é sur 1 caractère...Code:select * from t_accents where datum = 'é'
ne donne aucun résultat !!!
Maintenant le même test avec PostgreSQL :
En fin de compte, heureusement que la balise CODE du forum transforme l'accent, on voit bien qu'ici, ça marche. Et hop, voici donc une fonction des collations ICU non supportée par SQL Server et son French_AI_CI !!!Code:
1
2
3
4
5
6
7
8 testICU=# insert into t_accents2 (datum) values ('é'); INSERT 0 1 testICU=# select * from t_accents2 where datum='é'; id | datum --------+------- 100015 | é (1 row)
Au passage ça explique bien pourquoi le support du LIKE et surtout de son joker _ est compliqué: si j'ai le mot 'été' dans la base mais sous sa forme canonique (2 caractères) et que je cherche avec LIKE '_té', alors ça devrait être rejeté alors que = 'été' (sans forme canonique) devrait être accepté. Et j'imagine que c'est pas le genre de choses faciles à expliquer à un utilisateur...
SQL Pro vantait le mérite de Microsoft de supporter ça depuis 22 ans... alors qu'en fait ils sont restés aux conventions de l'époque, quand les formes canoniques Unicode n'en étaient encore qu'à leurs balbutiements !!!
Le site de conversion dont tout le monde rêve : https://cryptii.com/
https://github.com/cryptii/cryptii - logiciel libre!
Encodage/décodage point de code Unicode vers décimal, hexadécimal, binaire, texte...
En même temps, j'avoue ne pas comprendre ce débat à 2 centimes qui depuis le début est totalement faussé par :
- D'un côté, SQL Pro, certes, pas forcément avec beaucoup de tact, démontre les problèmes qu'on a quand on passe de SQL Server utilisant la collation french_ci_ai (donc basée sur le charset windows-1252) vers PostgreSQL
- De l'autre, les défenseurs de PostgreSQL qui vantent les métires ICU qui permet de supporter plus de caractères (que french_ci_ai)
Dans le charset windows-1252 le "é" est un e avec un accent dessus, pas un e avec un accent à côté qu'on recolle ensuite dessus en post-production.
Par conséquent, il est parfaitement normal que SQL Server ne comprennent pas ce qu'est ce caractère supplémentaire, puisqu'il est en dehors de la plage du charset utilisé (ce sont mêmes deux caractères, tous deux non imprimables, le 1 (NUL) et le 3 (STX)
Avec l'arrivée d'UTF8 sous SQL Server 2019 (pas encore dispo sous Linux par contre il me semble) la donne a peut-être changé, mais j'avoue ne pas avoir eu le courage de lire la doc : on est hors sujet, le topic initiale par le de travailler avec french_ci_ai, pas de savoir lequel des deux SGBD supporte le plus de caractères et de règles.
A savoir qu'au final, un "e accentué", ou un "e avec un accent en plus qu'un rajoute au dessus", ça ne change rien :
- à la lecture
- à la signification du caractères dans la culture courante
Et donc ne devrait aucunement impacter le résultat d'une comparaison : ce n'est donc pas une raison recevable, selon moins, pour le non support du LIKE.
Résultat, dans mon cas... (je rappelle que je suis sous Windows :
ERROR: ERREUR: le collationnement « fr_ci_ai » pour l'encodage « UTF8 » n'existe pasCode:
1
2 select distinct MOT from T_MOT where MOT collate fr_ci_ai in ('veau','elephant');
LINE 1: select distinct MOT from T_MOT where MOT collate fr_ci_ai in...
^
SQL state: 42704
Character: 42
je rappelle que je suis sous Windows et non sous Linux ! Voici comment a été créée la base :
Donc, je persiste et signe, cela ne fonction pas sous Windows... En conclusion, PostGreSQL est incapable d'avoir un fonctionnement équivalent pour des besoins basiques entre les différentes OS soit-disant supportés !Code:
1
2
3
4
5
6
7
8 CREATE DATABASE "TESTS" WITH OWNER = postgres ENCODING = 'UTF8' LC_COLLATE = 'French_France.1252' LC_CTYPE = 'French_France.1252' TABLESPACE = pg_default CONNECTION LIMIT = -1;
A +
À moins de travailler spécifiquement avec des produits Microsoft, on ne monte pas un serveur sous Windows, cet argument n'a donc pas d'intérêt. Un paquet de technologies web fonctionnent moins bien (quand elles fonctionnent) sous Windows, tout simplement parce que leurs mainteneurs n'ont pas d'intérêt à investir du temps de développement pour un OS qui dans 99% des cas n'est pas adapté.
Dans ton monde, probablement, mais chez 100% de mes clients, il n'y a aucun serveur Linux.
Pour la simple et bonne raison que :
- Historiquement, Linux est arrivé sur le tard dans le monde des serveurs d'entreprises. Autant 100% ou presque des "nouveaux marchés" sont pour Linux, autant l'existant est reste très majoritairement sous Windows. Quand on a un admin habitué à Windows, on n'a pas forcément envie d'investir (formation, temps, recrutement, etc.) pour aller vers Linux, surtout si les coûts Windows (1 serveur, youhou ! je suis ruiné) restent maîtrisés et qu'on n'y trouve aucun gain (si mon serveurs existant sous Windows fait l'affaire, que va-t-il faire de mieux sous Linux ? Je vais pas revendre ma barette de mémoire qui sert plus...).
- L'intégration avec LDAP par exemple est loin d'être évidente avec Linux,et la pléthore de demi-solutions existantes sous Linux, souvent incompatibles entres elles, ne permet pas d'avoir une gestion centralisée des droits et des mots de passes. Bref, la merde, et tout de suite obligé de se former, embaucher, voir acheter des outils pour singer ce que fait Windows en natif.
Le Web ne représente pas 100% du monde informatique, loin s'en faut.
Les CRM, ERP, GPAO sous Linux sont bien plus rares, et la plupart des majors de ces outils sont sous Windows.
Rares sont ceux qui se sont emmerdés à maintenir deux version (Windows + Linux) tout comme ceux qui se sont emmerdés à maintenir deux SGBD : soit ils ont abandonné au 3/4 l'une des solution, soit à 100%, soit ont coulés.
On constate actuellement un léger regain de versions Linux orientées Cloud, à voir ce que ça donnera dans 10 ans : il y a 20 ans, tous les ERP étaient compatibles Oracle et DB2. Maintenant, la plupart sont SQL Server uniquement.
Quant au "gain" de licences Windows, va expliquer au client qu'il va économiser 1000 euros tous les 5 ans à passer sous Linux alors qu'il paie près de 1000 euros de maintenance par utilisateur pour le produit.
Il y a beaucoup de gens qui développent sous Windows, c'est mon cas, bien que grâce au WSL on puisse maintenant faire tourner son serveur local sous Linux. Quand on met un serveur web en production par contre, sauf exception on utilise de l'unix.
Cf mon post : À moins de travailler spécifiquement avec des produits Microsoft...
Salut
Avec windows il faut faire...
Dans l'article cité par esperanto, il est dit que windows n'accepte pas les raccourcis ks, kc, ka.Code:CREATE COLLATION ignore_accents (provider = icu, locale = '@colStrength=primary', deterministic=false);
@+
Bien vu, ça fonctionne pour la casse, pas pour les diacritiques/accents.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 PS C:\Program Files\PostgreSQL\12\bin> .\initdb.exe --encoding=UTF-8 --lc-collate fr_FR --lc-ctype fr_FR -U postgres -D 'C:\Users\maxim\pg12\clusters\data1' PS C:\Program Files\PostgreSQL\12\bin> .\pg_ctl.exe -D 'C:\Users\maxim\pg12\clusters\data1' -l 'C:\Users\maxim\pg12\clusters\data1\trace' start PS C:\Program Files\PostgreSQL\12\bin> .\psql.exe -U postgres create table t(m text); insert into t(m) values ('Elephant'),('Eléphant'),('elephant'),('éléphant'),('veau'),('cochon'); postgres=# \l+ Liste des bases de donnÚes Nom | PropriÚtaire | Encodage | Collationnement | Type caract. | Droits d'accÞs | Taille | Tablespace | Description -----------+--------------+----------+-----------------+--------------+-----------------------+---------+------------+-------------------------------------------- postgres | postgres | UTF8 | fr_FR | fr_FR | | 7937 kB | pg_default | default administrative connection database template0 | postgres | UTF8 | fr_FR | fr_FR | =c/postgres +| 7769 kB | pg_default | unmodifiable empty database | | | | | postgres=CTc/postgres | | | template1 | postgres | UTF8 | fr_FR | fr_FR | =c/postgres +| 7769 kB | pg_default | default template for new databases | | | | | postgres=CTc/postgres | | | (3 lignes) postgres=# \dO Liste des collationnements SchÚma | Nom | Collationnement | Type caract. | Fournisseur | DÚterministe ? --------+----------+--------------------------------------+--------------------------------------+-------------+---------------- public | fr_ci_ai | @colStrength=primary;caseLevel=false | @colStrength=primary;caseLevel=false | icu | non (1 ligne) postgres=# select * from t where m collate fr_ci_ai = 'elephant' collate fr_ci_ai; m ---------- Elephant elephant (2 lignes)
Je soupçonne la version 53.1 de la lib icu, packagée par enterprisedb, d'être en cause, elle date d'il y a quatre ans.
P.S. oups il le dit dans son article, ce qui laisse à penser que "les diacritiques ont fonctionné sur windows" chez lui...^^
J'essaierai une compil msvc, et/ou minGW.
Ce que d'autres ont déjà fait et apparemment ça a été : https://www.postgresql.org/message-i...9590868e75ae2b
Salut
accent, casse, diacritique (ex Cœur) marchent bien chez mois. pg 12.2 (de enterprisedb) win10.
réponse...Code:
1
2
3
4 INSERT INTO T_MOT (MOT) VALUES ('Cur'); SELECT * FROM T_MOT WHERE MOT IN ('Veau', 'coeur','elephant')
@+Citation:
5 veau
8 éléphant
9 Cœur