2011-02-06 13 views
-1

私は、次のtagsのテーブルを持っている:タグ検索を使用してウェブサイトを見つけるにはどうすればよいですか?

web   | tags 
------------------------------------------------------------ 
google.com | search,google,searchengine,engine,web 
facebook.com | facebook,social,networking,friends 
youtube.com | video,youtube,videos,entertainment 
yahoo.com  | yahoo,search,email,news,searchengine 
bing.com  | search,searchengine,microsoft,bing,tools 

私が達成しようとしている何がこの表からウェブサイトのリストを取得するには、タグで検索されます。

たとえば、google.comで検索した場合、yahoobingを上記のサンプルテーブルからリストしたいとします。

これをPHPとMySQLでどうすれば実現できますか? (私はこのテーブルのためにFULL TEXT SEARCHを有効にしました)

+4

この構造を使用してタグで検索することはできますが、インデックス作成のために最適に機能しません。正規化を検討する! – Konerak

+1

+1を正規化する。クエリの読み書きが容易になり、パフォーマンスも向上します。 –

+0

「google.comで検索し、yahooとbingを上のサンプルテーブルから検索したい場合は」という意味を明確にすることはできますか? – Justin

答えて

0

Webテーブルとタグテーブルの両方を両方ともリンクするテーブルを持つことはできませんか?

構造が本当に変更できない場合はSELECT * FROM web WHERE tags LIKE '%google%'のようなものが動作します。

+0

私はそのクエリが動作するとは思わない。 'web'という表はなく、google.comの行だけが' tags'列に「google」を含んでいます。 –

+0

ああ、 'web'は' tags'ではありませんでした。また、あなたが意味することを参照してくださいが、私はOPが 'google.com'で検索したいとは思わない。タイプミスである必要がありますか? OPが「タグによる検索」について語るように。もちろん、OPはgoogle.comから返されたタグの検索を暗示しようとしています。この場合、非常に長いSQLスニペットが素敵に見えます:P –

2

このようなものは、あなたが望む結果を与えるかもしれませんが、かなり遅いでしょう。たぶん他の誰かが、より効率的なソリューションを提供することができます

SELECT t1.* FROM tags AS t1 JOIN tags AS t2 
    ON LIST_INTERSECT(t1.tags, t2.tags) != '' 
    WHERE t1.web='google.com' 

をそして、あなたはまた、この保存された機能が必要になります(ただコピーして、サーバーに接続し、データベースを選択した後、mysqlクライアントにこのコードを貼り付けます) :

DELIMITER $$ 
CREATE FUNCTION LIST_INTERSECT(
    list1 VARCHAR(255), list2 VARCHAR(255) 
) RETURNS VARCHAR(255) 
BEGIN 
    SET @delim = ','; 
    SET @list = list1; 
    SET @overlap = ''; 
    LOOPING: LOOP 
     IF (LOCATE(@delim, @list) > 0) THEN 
      SET @word = SUBSTRING_INDEX(@list, @delim, 1); 
      SET @list = SUBSTR(@list, LOCATE(@delim, @list) + 1); 
     ELSE 
      SET @word = @list; 
      SET @list = NULL; 
     END IF; 
     IF (CONCAT(',',list2,',') LIKE CONCAT('%,',@word,',%')) THEN 
      SET @newword = @word; 
      IF (@overlap != '') THEN 
       SET @newword = CONCAT(',', @word); 
      END IF; 
      SET @overlap = CONCAT(@overlap, @newword); 
     END IF; 
     IF (@list IS NULL) THEN 
      LEAVE LOOPING; 
     END IF; 
    END LOOP LOOPING; 
    RETURN @overlap; 
END$$ 
DELIMITER ; 

DELIMITERコマンドがからの文の区切り文字を変更することです「;」「$$」に、バックあなたはcustom functions or proceduresを定義するためにこれを実行する必要があります。。)

基本的にこのコードルックスtのサイトの場合彼web列の場合、キーワードを共有する他のすべてのサイトがtags列にあります。これを使用して、 "google.com"を検索した場合、 "bing.com"と "yahoo.com"も返されます。これらのレコードの3つすべてがtagsに「検索」と「検索エンジン」を持つためです。

+0

この関数を保存するにはどうすればいいですか? –

+0

@aron n: 'delimiter $$'から 'END $$'まですべてをコピーアンドペーストすると、自動的に関数を保存するはずです。ただし、挿入権限を持つユーザーから実行する必要があります。 –

関連する問題