Med MySQL kan du använda FIND_IN_SET()
:
SELECT * FROM mytable WHERE FIND_IN_SET('ios ', tags) > 0;
http://dev.mysql .com/doc/refman/5.0/en/string-functions.html#function_find-in-set
Observera att FIND_IN_SET
förväntar sig att strängar är komma separerade, inte komma och blanksteg separerat. Så du kan ha problem med den sista taggen. Det verkligen bästa sättet vore att normalisera tabellen; annars kan du ta bort mellanslag från tags
kolumn; slutligen kan du komma runt problemet genom att lägga till ett mellanslag i tags
kolumn:
SELECT * FROM mytable WHERE FIND_IN_SET('ios ', CONCAT(tags,' ')) > 0;
Om antalet taggar är begränsat kan du överväga att konvertera kolumnen till en SET
. Detta kommer att förbättra effektiviteten avsevärt.
UPPDATERA
Förutom att jag fick mellanslag fel . De är före strängarna och inte efter.
Så:
SELECT * FROM mytable WHERE FIND_IN_SET(' ios', CONCAT(' ', tags)) > 0;
Men återigen, bli av med dessa utrymmen - de är inget annat än problem :-)
UPPDATERING 2
Ovanstående fungerar, okej. Men det är nästan allt du kan säga till min fördel. Lösningen är inte bara ganska *in*effektiv, den gör också systemet nästan omöjligt att underhålla (been there, done that, fick T-shirten och en uttuggad rumpa under densamma). Så jag ska nu harpa lite för normalisering, d.v.s. att ha åtminstone dessa två fler tabeller:
CREATE TABLE tags ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
tagName varchar(32) // I'm a bit of a cheapskate
);
CREATE TABLE has_tag ( tableid INTEGER, tagid INTEGER );
Hur mycket är detta bättre? Låt mig räkna vägarna.
- du kan enkelt lägga till mer flexibla frågor ("har alla taggar i iOS, C++, ..." eller "har minst tre taggar bland dessa:( iOS, Python, SQL, .NET, Haskell )". Ja, du kan göra detta med
FIND_IN_SET
, men tro mig, du kommer inte att njuta av det . - du har en kontrollerad ordbok av taggar, vilket ger dig möjlighet att kontrollera om någon tagg är känd (såväl som enkelt generera listor som kombinationsrutor eller -- sa någon "jQuery Autocomplete"?).
- sparar en del diskfastigheter (taggar skrivs en gång)
- sökningar är snabba . Om du redan känner till taggarna du letar efter och förkompilerar dem till tagg-ID:n kommer de att lämna SQL-gummibrännmärken på trottoaren när de körs (indexerad sökning efter ett heltal värde!). Och taggar som inte kommer att kompileras kommer inte att finnas där , och du kommer att veta detta redan innan sökningen startar.
- gör det mycket lättare att byta namn på taggar
- kan innehålla valfritt nummer av taggar (du riskerar att få någon tagg trunkerad till 'iOS Developm' förr eller senare...)
Jag tror att "CSV-fältet" är censerat(eller)erat bland SQL-antimönster ( http://pragprog.com/book/bksqla/sql-antipatterns ), och av goda skäl.