MySQLでは、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
FIND_IN_SET
に注意してください 文字列はカンマである必要があります カンマとスペースではなく、分離されている 分離。したがって、最後のタグに問題がある可能性があります。本当に最善の方法は、テーブルを正規化することです。;そうしないと、tags
からスペースを消去する可能性があります 桁;最後に、tags
にスペースを追加することで、問題を回避できます。 列:
SELECT * FROM mytable WHERE FIND_IN_SET('ios ', CONCAT(tags,' ')) > 0;
タグの数が限られている場合は、列をSET
に変換することを検討してください。 。これにより、効率が大幅に向上します。
更新
スペースが間違っていることを除いて 。それらは前です 後ではなく文字列。
だから:
SELECT * FROM mytable WHERE FIND_IN_SET(' ios', CONCAT(' ', tags)) > 0;
しかし、繰り返しになりますが、これらのスペースを取り除きます-それらは問題に他なりません:-)
アップデート2
上記はうまくいきます。しかし、それはあなたが私の好意で言うことができるほとんどすべてです。このソリューションは非常に非効率的であるだけでなく、システムを保守不可能な状態にします(そこで、Tシャツとかみ砕いたお尻を同じものの下に置きます)。そこで、正規化を支持するように少しハープします。つまり、少なくとも次の2つのテーブルを追加します。
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 );
これはどれくらい良いですか?方法を数えさせてください。
- より柔軟なクエリを簡単に追加できます(「iOS、C ++、...にすべてのタグがあります」または「これらの中に少なくとも3つのタグがあります:(iOS、Python、SQL、.NET、Haskell)」。はい、これは
FIND_IN_SET
で行うことができます 、しかし私を信じてください、あなたはそれを楽しむことはありません 。 - 管理された辞書があります タグの数。これにより、タグが既知であるかどうかを確認できます(また、ドロップダウンコンボボックスなどのリストを簡単に生成できます。または、「jQueryオートコンプリート」と言った人はいますか?)
- ディスクのスペースを節約します(タグは1回だけ書き込まれます)
- 検索は高速 。探しているタグがすでにわかっていて、それらをタグIDにプリコンパイルしている場合、実行時にSQLラバースコーチマークが舗装に残ります(整数のインデックス検索 価値!)。また、コンパイルされないタグは存在しません 、検索を開始する前でもこれを知ることができます。
- タグの名前を変更するのがはるかに簡単になります
- 任意の数を保持できます タグの数(遅かれ早かれ「iOSDevelopm」に切り捨てられるタグがあるリスクがあります...)
「CSVフィールド」はSQLアンチパターンの中で検閲されていると思います ( http://pragprog.com/book/bksqla/sql-antipatterns )、そして正当な理由があります。