S MySQL můžete použít 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
Všimněte si, že FIND_IN_SET
očekává, že řetězce budou čárka oddělené, nikoli čárka a mezera oddělené. Takže můžete mít problémy s poslední značkou. Opravdu nejlepším způsobem by bylo normalizovat tabulku; jinak byste mohli vymazat mezery z tags
sloupec; nakonec můžete problém obejít přidáním mezery do tags
sloupec:
SELECT * FROM mytable WHERE FIND_IN_SET('ios ', CONCAT(tags,' ')) > 0;
Pokud je počet značek omezený, můžete zvážit převod sloupce na SET
. To výrazně zvýší efektivitu.
AKTUALIZACE
Až na to, že mám špatné mezery . Jsou před řetězce a ne po.
Takže:
SELECT * FROM mytable WHERE FIND_IN_SET(' ios', CONCAT(' ', tags)) > 0;
Ale zase se zbavte těch mezer - nejsou nic jiného než potíže :-)
AKTUALIZACE 2
Výše uvedené funguje, dobře. Ale to je téměř vše, co můžete říci v můj prospěch. Nejen, že řešení je docela *ne*efektivní, ale také dělá systém vedle neudržovatelný (byl jsem tam, udělal jsem to, dostal tričko a pod ním rozkousaný zadek). Takže teď budu trochu harpunovat ve prospěch normalizace, tedy mít alespoň tyto dvě další tabulky:
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 );
O kolik je to lepší? Nech mě počítat způsoby.
- můžete snadno přidávat flexibilnější dotazy („má všechny značky v iOS, C++, ...“ nebo „má mezi nimi alespoň tři značky:( iOS, Python, SQL, .NET, Haskell )“. Ano, můžete to udělat pomocí
FIND_IN_SET
, ale věřte mi, že se vám to nebude líbit . - máte řízený slovník tagů, což vám umožňuje zkontrolovat, zda je nějaká značka známá (a také snadno generovat seznamy, jako jsou rozbalovací seznamy nebo -- řekl někdo 'jQuery Autocomplete'?).
- šetří část diskového prostoru (značky se zapisují jednou)
- vyhledávání jsou rychlá . Pokud již znáte značky, které hledáte, a předkompilujete je do ID značek, zanechají při spuštění na chodníku stopy po popálení pryže SQL (indexované vyhledávání celého čísla hodnota!). A značky, které se nezkompilují, nebudou , a budete to vědět ještě před zahájením vyhledávání.
- je mnohem snazší přejmenovat značky
- může obsahovat jakékoli číslo značek (riskujete, že některá značka bude dříve nebo později zkrácena na 'iOS Developm'...)
Domnívám se, že "pole CSV" je cenováno (nebo) mezi antipatterny SQL ( http://pragprog.com/book/bksqla/sql-antipatterns ), a to z dobrého důvodu.