Med MySQL kan du bruge 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
Bemærk, at FIND_IN_SET
forventer, at strenge er komma adskilt, ikke komma og mellemrum adskilt. Så du kan have problemer med det sidste tag. Den virkelig bedste måde ville være at normalisere tabellen; Ellers kan du fjerne mellemrum fra tags
kolonne; endelig kan du omgå problemet ved at tilføje et mellemrum til tags
kolonne:
SELECT * FROM mytable WHERE FIND_IN_SET('ios ', CONCAT(tags,' ')) > 0;
Hvis antallet af tags er begrænset, kan du overveje at konvertere kolonnen til et SET
. Dette vil i høj grad forbedre effektiviteten.
OPDATERING
Bortset fra at jeg tog mellemrummene forkert . De er før strengene og ikke efter.
Så:
SELECT * FROM mytable WHERE FIND_IN_SET(' ios', CONCAT(' ', tags)) > 0;
Men igen, slip med de mellemrum - de er intet andet end problemer :-)
OPDATERING 2
Ovenstående virker, okay. Men det er næsten alt, du kan sige til min fordel. Ikke kun er løsningen ret *in*effektiv, den gør også systemet nærmest uvedligeholdeligt (been there, done that, fik T-shirten og en udtygget røv under samme). Så jeg vil nu harpe lidt til fordel for normalisering, dvs. at have mindst disse to tabeller mere:
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 );
Hvor meget er dette bedre? Lad mig tælle måderne.
- du kan nemt tilføje mere fleksible forespørgsler ("har alle tags i iOS, C++, ..." eller "har mindst tre tags blandt disse:( iOS, Python, SQL, .NET, Haskell )". Ja, du kan gøre dette med
FIND_IN_SET
, men tro mig, du vil ikke nyde det . - du har en styret ordbog af tags, som giver dig mulighed for at kontrollere, om et tag er kendt (samt nemt at generere lister såsom drop-down kombinationsbokse, eller -- var der nogen, der sagde "jQuery Autocomplete"?).
- gemmer noget diskfast ejendom (tags skrives én gang)
- søgninger er hurtige . Hvis du allerede kender de tags, du leder efter, og prækompilerer dem til tag-id'er, vil de efterlade SQL-gummi-scorb-mærker på fortovet, når de kører (indekseret søgning efter et heltal værdi!). Og tags, der ikke vil kompilere, vil ikke være der , og du vil vide dette, allerede inden søgningen starter.
- gør det meget nemmere at omdøbe tags
- kan indeholde et hvilket som helst nummer af tags (du risikerer at få nogle tag afkortet til 'iOS Developm' før eller siden...)
Jeg tror, at "CSV-feltet" er cens(eller) blandt SQL-antimønstrene ( http://pragprog.com/book/bksqla/sql-antipatterns ), og med god grund.