2012-05-08 18 views
3

私は、タグデータベーススキーマのToxiソリューションで頭を壊しています。私はユーザーがアイテムを提出できるシステムに取り組んでいます。これらのアイテムにはタグが関連付けられています。タグスキーマを読んだ後、私は最も必要なToxiソリューションを見つけました。しかし、私はこの権利を計画しているかどうかは完全にはわかっていないので、私はあなたの意見をお願いしたい。タグ付けシステム:Toxiソリューションの質問

私は3つのデータベースを持っています。
itemsitem_idを使用してitem_id、他
tagmapを含むとtag_id新しい項目を追加するとき、私は右のデータベースにタグを追加するプロセスを想定していますtag_idtag_text

を含むtags
外部キーとしてのとおりです続く?アレイ内のすべてのタグの配列

    1. ソート提出タグ:
      1. GET TAG_IDそれが0行を返した場合tag_textは現在のタグ
      2. に一致するタグから:
        1. 追加タグをタグテーブルへ
        2. タグを取得
    2. 仕上げ(ユーザーがA-大丈夫、などを与える)

    これは、我々はすべての項目ごとにタグのtagmapのエントリになってしまいます意味tagmapするのitem_idとTAG_IDを追加します。それは正しいようですが、私は助けることができないが、そこに膨大な量のエントリで終わるより良い方法があると思うことはできません...

    私はタグを編集するために、私はまだ見つけられていないより良い方法があると思うが。

    1. ユーザーが変更を行うのitem_id使ってタグを取得し、
    2. 編集可能なフィールドに挿入します。提出:ITEM_IDは、私は一種のあやふやがポイント3程度だ

    上記の一つとして

  • 同じプロセスを編集しているものと一致tagmapから
  • 削除行を。削除されたタグがあるかどうかを確認する方法はありますか?タグを削除して再追加するのではなく、選択的に削除することはできますか? タグマップ行を削除するときに関連項目が削除されることはありません。なぜなら、関連する項目は外部キーを指し示すのではなく、外部キーを指しているからです。

    また、タグの使用回数を把握したいかもしれませんが、表示する必要があるたびにそれらを数えるためにクエリを実行する必要はありません。私はcronジョブを1時間に1度、またはbihourly、タグマップのすべてのtag_idのインスタンスの数をカウントして、タグテーブルのtag_use値を更新することを考えています。それは正しい方法ですか、それとも良い方法がありますか?

    これはかなりの量のテキストです。情報が欠けているというよりはむしろ細かいことではなく、あまりにも多くの質問をしたり、少なすぎることを尋ねるよりも多くの新しいことを学びます。 今日、これを調べるには多すぎる時間を費やしたばかりのチャンスがあり、明日はもっと明白になります。

    ありがとうございます!

  • 答えて

    10

    まず、「毒素」は標準用語ではありません。常にあなたの条件を定義してください!少なくとも関連するリンクを提供する。

    そして今、質問自体...

    に私は3つのデータベースを持っています。

    いいえ、テーブルは3つあります。

    新しいアイテムを追加...

    あなたはこれらの多くを「マージ」するためにSQLのセットベースの自然を使用することができます例外を除いて、正しい軌道に乗って、かなりありますステップ。たとえば、アイテムのタグと1タギング:「TAG1を」、「TAG2」と「TAG3」はこのように行うことができます...

    INSERT IGNORE INTO tagmap (item_id, tag_id) 
    SELECT 1, tag_id FROM tags WHERE tag_text IN ('tag1', 'tag2', 'tag3'); 
    

    項目がすでにいくつかに接続されている場合でもIGNOREは、これが成功することができますこれらのタグの

    これは、すべての必要なタグが既にtagsにあることを前提としています。

    INSERT IGNORE INTO tags (tag_text) VALUES ('tag1'), ('tag2'), ('tag3'); 
    

    これは、我々はすべての項目ごとにタグのtagmapのエントリになってしまいます意味:tag.tag_idは自動インクリメントであると仮定すると、あなたは彼らがしていることを確認するために、このような何かを行うことができます。

    魔法はありません...正しいようだが、私は助けるが、その後そこにエントリの膨大な量で終わることを行うには良い方法だと思うことはできません。 「アイテムが特定のタグに接続されている」が記録したい知識の場合、にデータベースに何らかの物理的表現を持たせることになります。タグを編集するためとして

    ...

    あなたは(タグ自体を変更していない)を再タグ付けアイテムを意味ですか?

    DELETE FROM tagmap 
    WHERE 
        item_id = 1 
        AND tag_id NOT IN (
         SELECT tag_id FROM tags 
         WHERE tag_text IN ('tag1', 'tag3') 
        ); 
    

    これは「TAG1」と「TAG3」を除くすべてのタグからアイテムを切断します:

    はこのような何かを、リストに含まれていないすべてのタグを削除します。上記のINSERTとDELETEを1つずつ実行して、タグの追加と削除の両方をカバーします。

    SQL Fiddleでこれを再生できます。

    タグマップ行を削除すると、関連する項目は外部キーを指すので削除されません。

    正しい。 FKの子エンドポイントは参照アクション(ON DELETE CASCADEなど)をトリガーしません。親イベントのみをトリガーしません。

    tags(追加のフィールドはtag_textの横にある)にしたいので、このスキーマを使用しています。そうした場合、すべての接続がなくなっただけでこの追加データを失うことは望ましくありません。

    しかし、あなただけのtag_textを望んでいた場合は、すべての接続を削除すると、タグ自体を削除することと同じになりシンプルなスキーマを使用したい:

    enter image description here

    これは単にSQLを簡素化しません、それはまた、より良いclusteringを提供するでしょう。

    一見「毒性」はスペースを節約しているように見えるかもしれませんが、実際にはそうではないかもしれません。追加のテーブルとインデックスが必要です(タグは短くなる傾向があります)。

    また、私はあなたがこのような何かを行うことを決定する前に倍の量のタグ... cronジョブ...

    測定を追跡することができます。上記の私のSQLフィドルは、tagmap PKのフィールドの非常に意図的な順序を使用するので、この種のカウントに非常にやさしい方法でデータがクラスタリングされます(覚えておいてください:InnoDB tables are clustered)。これが問題になる前に、本当に膨大な量のアイテムを用意する必要があります。

    どちらの場合でも、対策現実的な量のデータ!

    +0

    うわー、それは本当に精巧な答えです!かなり学んだ、と私はこれが私を得るために十分だと思う。どうもありがとうございます! (また、あなたが気にしていない小さな質問:このソリューションの例は、しばしば 'tagmap'テーブルに' map_id'を持っています。それをそのまま残して、すべて(/両方)の列を外部キー?私は個人的に 'map_id'が必要なものは見当たりません。ありがとう!) – Fang

    +0

    @Fang' map_id'が何であるか、あなたが参照している例は何もわかりません。インターネットは巨大な場所です、覚えていますか?私の答えと "あなたの条件を定義する"(または少なくともリンクを提供する)の助言に従ってください! –

    +0

    'tagmap'テーブルの' map_id'は、それぞれのテーブルのbook_idとtag_idに似た、上記テーブルの自動インデックス付き主キーとなります。スキーマの例[here](http://www.pui.ch/phives/archives/2005/04/tags-database-schemas.html#toxi)再度、感謝します! – Fang

    関連する問題