« HP Pavilion DV7 functietoetsen of action keys | CentOS: waar blijven de updates? » |
Accented letters
probleem waar ik tegenaan liep:
Ik moet zoeken in een database tabel op bezoekers van wie de naam begint met een gegeven invoer. Alleen kunnen sommige letters voorzien zijn van een accent. Ik zoek bijvoorbeeld op "Veronique", maar ik wil dan ook "Véronique" vinden. En omgekeerd. Daarnaast wil ik natuurlijk ook dat namen die ingevoerd zijn als "veronique" of "VERONIQUE" te vinden zijn.
De oplossing voor het probleempje case insensitive is te vinden in het gebruik van UPPER, danwel LOWER.
SELECT * FROM tabel
WHERE UPPER(naam) LIKE UPPER('Vero%')
Het probleem met de accented letters was wat lastiger, maar de oplossing is gevonden in het gebruik van Oracle's CONVERT:
SELECT * FROM tabel
UPPER(CONVERT(naam, 'US7ASCII')) like UPPER(CONVERT('Véro%','US7ASCII'))
Mysql
Voor Mysql is dit probleem minder relevant, aangezien
SELECT 'a' = 'A', 'a' = 'À', 'a' = 'á';
oplevert:
+-----------+-----------+-----------+ | 'a' = 'A' | 'a' = 'À' | 'a' = 'á' | +-----------+-----------+-----------+ | 1 | 1 | 1 | +-----------+-----------+-----------+
3 comments
Kwam via via op je site en ik heb veel belangstelling voor Oracle.
Hierboven las ik:
SELECT * FROM tabel
WHERE UPPER(naam) LIKE UPPER(’Vero%’)
Hier maak je een beginnersfout, Oracle zal door deze upper() functies altijd een full table scan ipv index-scan doen, elk record door de upper functie halen (waarschijnlijk andere db-engines ook). Bij een enkele miljoenen records zal de performance dalen en in joins wordt het een probleem.
Ook dit UPPER(CONVERT(naam, ‘US7ASCII’)) like UPPER(CONVERT(’Véro%’,'US7ASCII’)) levert al snel een performance probleem. Moet je dus anders oplossen.
Voor mij is het Oracle verhaal helaas momenteel niet actueel. Ik werk nu aan andere projecten.
Ik heb dit indertijd gepost, omdat het me wel even tijd gekost had om tot deze oplossing te komen.
Ik snap wel hoe dit een performance probleem geeft, maar ik heb geen andere oplossing gevonden.
of het zou iets met binary search moeten worden.
Maar zoals gezegd: ik heb geen Oracle beschikbaar op het moment.
sta open voor suggesties.
De oplossing voor WHERE UPPER(naam) LIKE UPPER(’Vero%’) is een function based index: create index ix_u_naam on (uppper(naam).
De WHERE wordt dan where naam like LIKE UPPER(’Vero%’).
De oplossing voor het tweede is inderdaad binary search. Oracle heeft daar ook snelle en makkelijk te implementeren oplossingen voor.