Met MySQL kunt u FIND_IN_SET()
. gebruiken :
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
Merk op dat FIND_IN_SET
verwacht dat strings komma zijn gescheiden, niet komma en spatie uit elkaar gehaald. U kunt dus problemen hebben met de laatste tag. De beste manier zou zijn om de tabel te normaliseren; anders zou je spaties uit de tags
kunnen verwijderen kolom; ten slotte kunt u het probleem omzeilen door een spatie toe te voegen aan de tags
kolom:
SELECT * FROM mytable WHERE FIND_IN_SET('ios ', CONCAT(tags,' ')) > 0;
Als het aantal tags beperkt is, kunt u overwegen de kolom te converteren naar een SET
. Dit zal de efficiëntie aanzienlijk verbeteren.
UPDATE
Alleen heb ik de spaties fout . Ze zijn voor de snaren en niet erna.
Dus:
SELECT * FROM mytable WHERE FIND_IN_SET(' ios', CONCAT(' ', tags)) > 0;
Maar nogmaals, doe die spaties weg - het zijn alleen maar problemen :-)
UPDATE 2
Bovenstaande werkt, oké. Maar dat is bijna alles wat je in mijn voordeel kunt zeggen. Niet alleen is de oplossing behoorlijk *in*efficiënt, het maakt het systeem ook bijna onhoudbaar (been there, done that, heb het T-shirt en een uitgekauwde kont eronder). Dus ik zal nu een beetje pleiten voor normalisatie, d.w.z. met ten minste deze twee extra tabellen:
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 );
Hoeveel is dit beter? Laat me de manieren tellen.
- u kunt eenvoudig flexibelere zoekopdrachten toevoegen ("heeft alle tags in iOS, C++, ..." of "heeft minstens drie tags:(iOS, Python, SQL, .NET, Haskell )". Ja, je kunt dit doen met
FIND_IN_SET
, maar geloof me, je zal er niet van genieten . - je hebt een gecontroleerd woordenboek van tags, waarmee u kunt controleren of een tag bekend is (en ook gemakkelijk lijsten kunt genereren zoals vervolgkeuzelijsten met invoervak, of -- zei iemand 'jQuery Autocomplete'?).
- bespaart wat schijfruimte (tags worden eenmaal geschreven)
- zoekopdrachten zijn snel . Als je de tags die je zoekt al kent en ze vooraf compileert in tag-ID's, zullen ze tijdens het hardlopen SQL-rubberen schroeiplekken op de stoep achterlaten (geïndexeerde zoekopdracht voor een integer waarde!). En tags die niet compileren zullen er niet zijn , en u weet dit zelfs voordat het zoeken begint.
- maakt het veel gemakkelijker om tags te hernoemen
- kan elk nummer bevatten van tags (u loopt het risico dat een tag vroeg of laat wordt afgekapt tot 'iOS Developm'...)
Ik geloof dat het "CSV-veld" wordt gecensureerd (of) onder de SQL-antipatronen ( http://pragprog.com/book/bksqla/sql-antipatterns ), en met een goede reden.