2017-11-07 9 views
1

私は自分の練習用の小さな検索エンジンをコーディングしています。私はそれに検索機能を追加したい。タイトル、説明、キーワードが一致すると、questionsのテーブルをすべて選択しようとしています。PHPを使用してMySQLデータベースからタイトル、説明、キーワードを選択

私は、次の3つのテーブルを作成しました:これまでのところ、私のSQLクエリは次のようになります

questions(id(PK), title, description) 

keywords(id(PK), label); 

questions_keywords(id(PK), question_id(FK), keyword_id(FK)); 

を:このクエリで

SELECT q.* FROM question_keywords qk 
JOIN keywords k ON qk.keyword_id=k.id 
JOIN questions q ON qk.question_id=q.id 
WHERE q.description LIKE '%javascript%' 
OR 
k.keyword_label LIKE '%java%' 

、私は部分文字列を含むquestionsテーブルからすべての行を選択していますjavaまたはjavascript

私はそれを正しくやっていますか良い方法がありますか?

ありがとうございます。

+2

クエリで重複行が生成される可能性があるため、おそらく 'SELECT DISTINCT q。*'を使用する必要があります。 –

+0

@PaulSpiegelはい。私も気づいた。返信いただきありがとうございます。 – Rebbeca

+0

あなたのテーブルの 'keywords'はどこですか?私はそれらを見ません、あなたは 'keywords.label'を意味するのですか? – ArtisticPhoenix

答えて

0

他にも言及したとおり、私は別個のものを追加します。私はまたテーブルを並べ替えるだろう。機能的には私はそれはそれはちょうどあなたがこのDBfiddleで見ることができるように

https://www.db-fiddle.com/f/pcVqcMm1yUoU6NdSHitCVr/2

あなたは、重複を取得する理由は基本的にデカルトと呼ばれ

SELECT DISTINCT 
    q.* 
FROM 
    questions AS q 
JOIN 
    question_keywords AS qk ON q.id = qk.question_id 
JOIN 
    keywords AS k ON qk.keyword_id = k.id 
WHERE 
    q.description LIKE '%javascript%' 
OR 
    k.label LIKE '%java%'; 

ハハ...私を盗聴重要とは思いません製品は、簡単に言えば

https://en.wikipedia.org/wiki/Cartesian_product

「多対多」relationshiを持つだけの結果でありますp。あなたは、私が意図的に、私は最後の2を挿入

INSERT INTO question_keywords (question_id,keyword_id)VALUES(4,1); 
INSERT INTO question_keywords (question_id,keyword_id)VALUES(4,2); 

重複行の橋(またはジャンクション)テーブルquestion_keywordsに追加するもので、このような状況を作成しフィドルに表示されている場合は

は、2があるというだけの理由でありますの一致する値が4のこのテーブルのエントリ。したがって、Duplicatesという意味では、questionsという表のフィールドのみを選択しているという意味でのものです。キーワードテーブルのフィールドが含まれている場合。 1つの行にはキーワードJava #1があり、もう1つの行にはJavascript #2というキーワードがあります。

希望を説明することができます。

注意すべきいくつか他のもの:

  1. あなたはk.keyword_label LIKE '%java%'が問題のあなたのテーブル定義に従ってk.label LIKE '%java%'する必要があります投稿クエリで構文エラーがあります。

  2. は通常、ジャンクションテーブルには、(あなたがほとんどでした)、それは参加する両方のテーブルの組み合わせでなければなりませんが、複数形はquestion_keywordsそれは小さなことだが、クエリを記述する場合、それは混乱を引き起こす可能性がquestions_keywordsをする必要があります間違っています。

  3. 実際にジャンクションテーブル用の別のプライマリキーは必要ありません。

あなたは、私がバイオリンでテーブルを作成した様子がわかります。

CREATE TABLE question_keywords( 
    question_id INT(10) UNSIGNED NOT NULL, 
    keyword_id INT(10) UNSIGNED NOT NULL, 
    PRIMARY KEY(question_id,keyword_id) 
); 

プライマリキーは、2つの外部キーの複合です。これには、実際の重複行の作成を防止するという追加の利点があります。たとえば、これを試した場合

INSERT INTO question_keywords (question_id,keyword_id)VALUES(4,1); 
INSERT INTO question_keywords (question_id,keyword_id)VALUES(4,1); 

セットアップで私は複製を作成することができません。別のプライマリキー(サロゲートキー)を引き続き使用できますが、2つのキーの代わりに複合ユニークインデックスを作成する必要があります。

関連する問題