MySQL in collations

Naletel sem na eno posebnost pri uporabi collationov v MySQL, pa bi malo z vami delil zadevo, za vsak primer, da se ne boste prevec cudili, ko boste kdaj naleteli na to zadevo. To obnasanje je sicer podrobno opisano tukaj, ampak kdo pa dandanasnji bere navodila? :)

Skratka, collations v MySQL niso namenjeni le zgolj pravilnemu urejanju po abecednem redu, ampak zelijo zadeve biti tudi pametne pri ugotavljanju, kateri sicer razlicni znaki so naceloma enaki. Da ponazorim:

mysql> select 'z' = 'ž' collate utf8_general_ci as test;
+------+
| test |
+------+
|    1 |
+------+

za razliko od:

mysql> select 'z' = 'ž' collate utf8_slovenian_ci as test;
+------+
| test |
+------+
|    0 |
+------+

Ce malo razmislimo, zadeva povsem stima, nam slovencem je seveda znak "z" razlicen od znaka "ž", vecino ostalih jezikov pa kratkomalo boli nekaj za te stresice, pa saj jih niti na tipkovnici nimajo :)

Ravno tako pa nas boli isti ze prej neomenjeni organ za nekatere druge znake, primer:

mysql> select 'n' = 'ñ' collate utf8_slovenian_ci as test;
+------+
| test |
+------+
|    1 |
+------+

za razliko od:

mysql> select 'n' = 'ñ' collate utf8_spanish_ci as test;
+------+
| test |
+------+
|    0 |
+------+

13 odgovorov

hm.. zanimivo, nivem vedu da je mysql tako internacionalno pameten.

jankoM:
hm.. zanimivo, nivem vedu da je mysql tako internacionalno pameten.

Ah, za moje pojme skoraj prepameten :) .

Res je HeXeR, vcasih si mogoce tega vedenja clovek ne bi zelel. Tega vedenja sicer nima utf8_bin collation, ampak na zalost postane zadeva potem case-sensitive.

Sicer se na my_sql ne spoznam toliko, sam pa pred kratkim delal na specifičnem primerjanju objektov preko comparatorja/primerjalnika in je bila stvar sila preprosta. Tako da po moje minimalen strošek (čas), če narediš svoje urejanje in mogoče ti še kje drugje prav pride.

Seveda če se gre samo za slovenščino in ne za vse charsete.

Alkimisticus, ni tak hud problem v primerjanju, to se seveda da resit blazno enostavno. Primer primerjanja sem dal le kot demonstracijo problema. Bolj je problem v tem, da se zgodi naslednje:

mysql> CREATE TABLE imena (
        ime CHAR(100) CHARSET utf8 COLLATE utf8_general_ci,
        INDEX (ime)
    );
mysql> INSERT
    INTO
        imena
        (ime)
    VALUES
        ('Joze'),
        ('Jože');
mysql> SELECT
        *
    FROM
        imena
    WHERE
        ime = 'Jože';
+-------+
| ime   |
+-------+
| Joze  |
| Jože |
+-------+

Razumes?

Ja, razumem, zaradi preveč ohlapnega primerjanja imaš netočne rezultate. Torej bolj strog primerjalnik (slovenski) reši zadevo. In razumem da ti nimaš problema, samo prikazal si zanimivost.

Misli sem samo, da bi zadevo še malo naprej peljal in naredil custom comparator za kakšna bolj eksotična primerjanja.

Alkimisticus, problem bi vsekakor nastal, ker ta custom comparator ne bi mogel uporabljati indeksov za optimizacijo poizvedb. Verjetno bi bila resitev v tem, da bi napisal custom collation, kar bi pa to verjetno za sabo potegnilo poseganje v izvorno kodo MySQLa, kar spet ni prevec kul. Lahko se pa motim, povsem mozno je, da je dodajanje novega custom collationa povsem enostavno, le zasledil nisem tega nikjer.

Če je res potrebno vse to, potem se ne splača. Bolje urediti kr programsko.

Alkimisticus, si me zrajcal s tem problemom in sem sel raziskovat. Ocitno se da dodajati custom collations brez poseganja v izvorno kodo MySQLa in tudi brez recompilanja.

http://forge.mysql.com/wiki/HowtoAddaCollation

Tnx for shearing, Vini! No, pa sj v konkretnem primeru niti ni narobe, če ti vrne Joze in Jože - imam izkušnje, ko so ljudje sila površni pri vpisovanju podatkov v obrazce in tam ti tole pride pravzaprav celo kot nekaj uporabnega. :)