22

私は写真の Web サイトを持っていますが、元のカテゴリのバケット化が失敗し始めているため、タグをサポートしたいと考えています (一部の写真は家族と休暇、または学校と友人です)。合意されたタグ付けデータベース スキーマはありますか?

アルバムの一部としての写真の保持を引き続きサポートしたいと考えています。

現在、いくつかのテーブルがあります。

写真

  • 写真付き身分証明書
  • 写真アルバムID
  • キャプション
  • 日にち

フォトアルバム

  • アルバムID
  • アルバム名
  • アルバムの日付
4

7 に答える 7

26

効果的なさまざまなスキーマがあり、タグ付けされたアイテムの数が増えるにつれて必要になる一般的なクエリに対して、それぞれ独自のパフォーマンスへの影響があります。

個人的には、タグ テーブルと、タグをアイテムに関連付けるリンク テーブルがあるのが好きです。これは、非正規化されており (タグ名の重複がない)、必要に応じてリンク テーブルに追加情報 (アイテムがタグ付けされたときなど) を格納できるためです。

気まぐれで単純な選択が必要な場合は、非正規化されたデータを追加することもできますが、使用回数をタグテーブルに保存するか、アイテムテーブル自体で使用されたタグ名を保存してヒットを回避することにより、追加のデータメンテナンスが必要になります各アイテムのリンク テーブルとタグ テーブル。これは、複数のアイテムをすべてのタグとともに表示したり、単純なタグのバージョン管理に役立ちます...そのようなことに興味がある場合;)

于 2008-10-05T20:58:41.827 に答える
15

私はこれを非常に多くのユーザーがいない小さなシステムで行ってきましたが、タグを管理するための「受け入れられた」方法があるかどうか以前は疑問に思いました。insinによって投稿されたリンクや、タグ付けに関する他の多くのブログ投稿を読んだ後、受け入れられた方法は、完全に正規化して保存し、データセットが大きくなりすぎた場合に特定のものをキャッシュすることです。

これは非常に多くの関係であるため(各タグは任意の数の写真に属することができます-各写真は多くのタグを持つことができます)、リレーショナルデータベース理論では、写真テーブル、タグテーブル、およびそれらをリンクする相互参照テーブルを作成します。

photos
  photoid
  caption
  filename
  date

tags
  tagid
  tagname

phototags
  photoid
  tagid

これには、非常に大きなデータセットから選択する際のスケーリングの問題がありますが、正規化されていないすべてのスキーマも同様です(たとえば、テキストフィールドによる並べ替えとフィルタリングは、整数を使用するよりも常に遅くなります)。おいしいもの、あるいはStackOverflowと同じくらい大きくなった場合は、おそらくタグセットのキャッシュを行う必要があります。

直面しなければならないもう1つの問題は、タグの正規化の問題です。これはデータベースの正規化とは何の関係もありません。たとえば、「StackOverflow」、「stackoverflow」、「stackoverflow」タグが同じであることを確認するだけです。多くの場所で空白が許可されないか、自動的に削除されます。句読点についても同じことが表示される場合があります。「StackOverflow」を「Stack-Overflow」と同じにします。自動小文字化はかなり標準的です。「c#」を「csharp」と同じにするなど、特殊なケースの正規化も表示されます。

ハッピータグ付け!

于 2008-10-05T23:24:25.980 に答える
2

タグの処理方法に関する簡単なメモ:

タグ付けシステムは、新しいタグを作成するために明示的な追加作業が必要な非常に厳密に定義されたタグ(Gmailラベルを考えてください)から、できるだけ多くのタグを追加することが推奨される非常に緩いシステム(flickr、または文字起こしが適用される可能性のあるオーディオコンテンツのタグ付け)までさまざまです。タグとして直接)。

一般に、コンテンツはすでに検索可能であるため、簡単にインデックスを作成できるメディア(テキスト!)は、より厳格なシステムを備えている必要があります。追加のタグは、分類専用に存在します。分類は、さまざまなユーザーが同じカテゴリに幅広く割り当てている場合にのみ役立ちます。生のテキストがある場合、新しいタグを作成するには、ほぼ神の行為が必要です。

一方、インデックス作成がより難しいメディア(画像、ビデオ、オーディオ)は、タグやその他のメタデータが検索時の唯一の希望であるため、多くのタグを奨励する柔軟なシステムを備えている必要があります。

必要なデータベーススキーマは、そのスペクトルのどちらの端を見つけたかによって多少変わる可能性があるため、これは重要です。

于 2008-10-06T15:44:08.700 に答える
2

このようなことが頭に浮かびます: これらの 2 つのテーブルを追加します。

タグ

  • タグ ID
  • タグ名
  • タグの説明

写真タグ

  • 写真付き身分証明書
  • タグ ID

これをアルバムに拡張して、フォト アルバムとタグの間に共通テーブルを作成することもできます。

于 2008-10-05T21:00:02.340 に答える
2

確立されたオープンソース ソフトウェアがどのようにそれを行っているかを確認することをお勧めします。たとえば、Galleryはメタデータをデータベースに保存しますが、これは非常に豊富です。

ただし、「標準」スキーマは見つからないと思います。私が考えることができる最も近いものは、(カメラなどによって) 画像ファイル自体に埋め込まれている EXIF メタデータ形式です。

于 2008-10-05T21:01:52.397 に答える
2

何百万ものレコードで実際のパフォーマンスが必要な場合は、タグを 1 つのフィールドに格納し、カンマで区切って、sphinxsearch などの全文インデックス/検索デーモンを使用してレコードを取得できます。追加する必要があるのは、すべてのタグをカウント値とともにリストしたテーブルで、タグがアイテムに添付される頻度を知ることだけです。

通常の方法ではなく、純粋なデータベース ソリューションよりも少し複雑であることはわかっていますが、タグ関連のアイテムを検索するのは本当に高速です。

データベース エンジンの全文検索機能を使用することもできますが、多くのレコードがある場合、ほとんどのエンジンは遅くなる傾向があります。

それが小さなプロジェクトの場合は、自分のやり方でうまくいくことができます。しかし、私はこの他の解決策をあなたと共有したいと思います. どう思いますか?

于 2008-10-05T21:33:10.573 に答える
0

私のアプリBugTracker.NETでは、バグが多すぎないことを前提としています。たぶん数万人ですが、数千万人ではありません。この仮定により、タグとそれらが参照するアイテムのIDをキャッシュできます。

データベースでは、タグは、バグとともに、コンマ区切りのテキストフィールドに入力されたとおりに保存されます。

タグフィールドが追加または変更されると、すべてのバグIDとそのタグを選択するバックグラウンドスレッドが開始され、テキストが解析され、キーがタグであり、値がそのタグを持つすべてのIDのリストであるマップが作成されます。 。次に、そのマップをAsp.NetApplicationオブジェクトにキャッシュします。

以下は、今説明したコードです。

コードを最適化して、すべてのバグを調べる代わりに、キャッシュされたマップを段階的に変更するだけで、最適化されていない場合でも正常に機能するようにすることができます。

誰かがタグを使用して検索を行うとき、私はマップ内の値を検索し、IDのリストを取得してから、「where id in(1、2、3 ...)」句を指定したSQLを使用してそれらのバグをフェッチします。

    public static void threadproc_tags(object obj)
    {
        System.Web.HttpApplicationState app = (System.Web.HttpApplicationState)obj;

        SortedDictionary<string,List<int>> tags = new SortedDictionary<string,List<int>>();

        // update the cache
        DbUtil dbutil = new DbUtil();
        DataSet ds = dbutil.get_dataset("select bg_id, bg_tags from bugs where isnull(bg_tags,'') <> ''");

        foreach (DataRow dr in ds.Tables[0].Rows)
        {
            string[] labels = btnet.Util.split_string_using_commas((string) dr[1]);

            // for each tag label, build a list of bugids that have that label
            for (int i = 0; i < labels.Length; i++)
            {

                string label = normalize_tag(labels[i]);

                if (label != "")
                {
                    if (!tags.ContainsKey(label))
                    {
                        tags[label] = new List<int>();
                    }

                    tags[label].Add((int)dr[0]);
                }
            }
        }

        app["tags"] = tags;

    }
于 2008-10-05T23:37:21.023 に答える