Con MySQL, puoi usare 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
Nota che FIND_IN_SET
si aspetta che le stringhe siano virgola separati, non virgola e spazio separato. Quindi potresti avere problemi con l'ultimo tag. Il modo migliore sarebbe normalizzare la tabella; altrimenti potresti cancellare gli spazi dai tags
colonna; infine puoi aggirare il problema aggiungendo uno spazio ai tags
colonna:
SELECT * FROM mytable WHERE FIND_IN_SET('ios ', CONCAT(tags,' ')) > 0;
Se il numero di tag è limitato, potresti considerare di convertire la colonna in un SET
. Ciò migliorerà notevolmente l'efficienza.
AGGIORNAMENTO
Solo che ho gli spazi sbagliati . Sono prima le stringhe e non dopo.
Quindi:
SELECT * FROM mytable WHERE FIND_IN_SET(' ios', CONCAT(' ', tags)) > 0;
Ma ancora una volta, sbarazzati di quegli spazi:non sono altro che problemi :-)
AGGIORNAMENTO 2
Quanto sopra funziona, ok. Ma questo è quasi tutto ciò che puoi dire a mio favore. Non solo la soluzione è abbastanza *in*efficiente, ma rende anche il sistema quasi ingestibile (ci sono stato, l'ho fatto, ho la maglietta e un culo masticato sotto lo stesso). Quindi ora parlerò un po' a favore della normalizzazione, cioè avere almeno queste due tabelle in più:
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 );
Quanto è meglio? Fammi contare i modi.
- puoi aggiungere facilmente query più flessibili ("ha tutti i tag in iOS, C++, ..." o "ha almeno tre tag tra questi:( iOS, Python, SQL, .NET, Haskell )". Sì, puoi farlo con
FIND_IN_SET
, ma fidati, non ti divertirai . - hai un dizionario controllato di tag, che ti consente di verificare se un tag è noto (oltre a generare facilmente elenchi come caselle combinate a discesa o -- qualcuno ha detto "Completamento automatico jQuery"?).
- salva un po' di spazio su disco (i tag vengono scritti una sola volta)
- le ricerche sono veloci . Se conosci già i tag che stai cercando e li precompili in ID tag, lasceranno segni di bruciature di gomma SQL sul pavimento durante l'esecuzione (ricerca indicizzata di un intero valore!). E i tag che non verranno compilati non ci saranno , e lo saprai anche prima che inizi la ricerca.
- rende molto più semplice rinominare i tag
- può contenere qualsiasi numero di tag (rischi prima o poi che qualche tag venga troncato in 'iOS Developm'...)
Credo che il "campo CSV" sia censurato (o) classificato tra gli SQL Antipatterns ( http://pragprog.com/book/bksqla/sql-antipatterns ), e per una buona ragione.