11

今後のスーパーヒーロー映画のリリースに関するインサイダー情報を収集していて、メインの映画テーブルが次のようになっているとします。

表1

Title              Director   Leading Male      Leading Female    Villain
--------------------------------------------------------------------------
Green Lantern      Kubrick    Robert Redford     Miley Cyrus     Hugh Grant  
The Tick          Mel Gibson  Kevin Sorbo        Linda Hunt    Anthony Hopkins

これは一般的に非常にうまく機能し、非常に簡単なクエリと行間の比較を可能にするはずです。

ただし、各データファクトのソースと、ファクトを発見したジャーナリストの名前を追跡する必要があります。これは、次のようなEAVテーブルのようなものを示唆しているようです。

表2

Movie             Attribute            Value          Source          Journalist
----------------------------------------------------------------------------------
Green Lantern      Director           Kubrick         CHUD              Sarah
Green Lantern    Leading Male      Robert Redford     CHUD              James
Green Lantern   Leading Female      Miley Cyrus    Dark Horizons        James
Green Lantern      Villain           Hugh Grant       CHUD              Sarah
The Tick           Director          Mel Gibson       Yahoo            Cameron
...

これにより、必要なメタデータを簡単にキャプチャできますが、クエリが難しくなります。1つの映画のすべての基本データを取得するには、もう少し時間がかかります。より具体的には、ここで4つの行を処理して、グリーンランタンに関する4つの重要な情報を取得する必要がありますが、表1では、1つの適切にカプセル化された行です。

だから私の質問は、私が今説明した複雑さを考慮して、そして私は一般的にEAVテーブルが避けられるべきであることを知っているので、EAVはまだ最良の解決策ですか?このデータを表現する唯一の合理的な方法のようです。私が見る他の唯一の選択肢は、次のようなメタデータのみを格納する別のテーブルと組み合わせてテーブル1を使用することです。

表3

Movie             Attribute            Source          Journalist
----------------------------------------------------------------------------------
Green Lantern      Director             CHUD              Sarah
Green Lantern    Leading Male           CHUD              James
Green Lantern   Leading Female      Dark Horizons         James
Green Lantern      Villain              CHUD              Sarah
The Tick           Director             Yahoo            Cameron
...

ただし、これは非常に危険です。テーブル1の列名を「Villain」から「PrimaryVillain」に変更しても、テーブル3の行は単に「Villain」と表示されるため、残念ながら関連データが分離されます。これは、「属性」列がテーブル1の列の列挙として機能する別のテーブルにリンクされている場合に役立ちます。もちろん、DBAは、この列挙テーブルをテーブル1の実際の列と一致するように維持する責任があります。列挙テーブルを手動で作成する代わりに、テーブル1の列の名前を格納するSQL Serverのシステムビューを使用することで、これをさらに改善できる可能性があります。システムビュー。

何を指示してるんですか?EAVは行く唯一の方法ですか?

そして、それが1つのメタデータ列(「ジャーナリスト」なしの「ソース」のみ)であった場合はどうなりますか?それでもEAVルートに進む必要がありますか?「Director」、「Director_Source」、「Leading Male」、「Leading Male_Source」などの列を作成できますが、すぐに醜くなります。私が考えていないより良い解決策はありますか?

不明な点がありましたらコメントしてください。必要に応じて追加します。そうそう、私が使用した映画データは作成されています:)

編集:私の主な質問を簡潔に言い換えると、テーブル1のシンプルさと真のRDBMS設計が必要です。これは、安全でアクセス可能な方法で属性のメタデータを保存しながら、映画のエントリを実際によく説明しています。これは可能ですか?それともEAVが唯一の方法ですか?

編集2:さらにいくつかのWeb調査を行った後、メタデータを列に格納したいという願望を中心としたEAVに関する議論はまだ見つかりません。EAVを実装する主な理由は、ほとんどの場合、動的で予測不可能な列ですが、私の例ではそうではありません。私の例では、常に同じ4つの列があります。ディレクター、主要な男性、主要な女性、悪役です。ただし、各行の各列に関する特定の事実(ソースおよびジャーナリスト)を保存したいと思います。EAVはこれを容易にしますが、私はそれに頼ることを避けたいと思います。

アップデート

列の名前を「Movie」から「Name」に変更し、テーブル全体を「Movie」と呼ぶことを除いて、表2の設計を使用して、表1に戻るためのSQLServer2008のピボット操作を次に示します。

SELECT Name, [Director], [Leading Male], [Leading Female], [Villain]
FROM (Select Name, Attribute, Value FROM Movie) as src
PIVOT
(
Max(Value)
FOR Attribute IN ([Director], [Leading Male], [Leading Female], [Villain])
)  AS PivotTable
4

9 に答える 9

6

設計でファクト値と見なすものを変更できます...データモデルのファクトは、次のNタプルとして表現できるようです。

Movie | FactType | FactValue | FactSource | FactJournalist

次のテーブル構造は、必要なデータモデルをサポートする必要があり、比較的簡単にインデックスを作成して結合できます。次のパースペクティブを作成できるように、ファクト値とファクトタイプのみをピボットするビューを作成することもできます。

MovieID | Movie Name | Director | LeadingMale | LeadingFemale | PrimaryVillain | etc

興味深いことに、これは、EAVモデルをデータに完全に適用し、個々の映画(監督、リード、悪役などの直感的な帰属)を、属性がソースに焦点を当てるピボット構造に分解する論理的な拡張と見なすことができます。代わりに情報の。

提案されたデータモデルの利点は次のとおりです。

  • 十分に正規化されています(ただし、完全を期すために、FactTypeフィールドを参照テーブルに正規化する必要があります)。
  • ファクトタイプを効率的に表形式の構造にピボットするビューを作成することが可能です
  • これは比較的拡張可能であり、データベースが参照整合性と(必要に応じて)カーディナリティ制約を適用できるようにします
  • MovieFactテーブルは、単純なテキストフィールドだけでなく、さまざまな種類の映画のファクトをサポートするようにサブクラス化できます。
  • データに対する単純なクエリは比較的効率的です

データモデルの欠点のいくつかは次のとおりです。

  • 複合的な条件付きクエリは、書くのが難しいです(ただし、不可能ではありません)(たとえば、監督がAで、主役の男性がBであるすべての映画を検索するなど)。
  • このモデルは、従来のアプローチやEAV構造を含むアプローチよりもややわかりにくいです。
  • 複数のファクトを更新するには、複数の列ではなく複数の行を更新する必要があるため、挿入と更新は少し注意が必要です。

構造を正規化するためにMovieデータをレベルアップしました。一貫性を保つために、MovieFact構造に映画名をプッシュすることができます(一部の映画では、名前がソース情報を追跡したい場合でも想像できるため) 。

Table Movie
========================
MovieID   NUMBER, PrimaryKey
MovieName VARCHAR

Table MovieFact
========================
MovieID          NUMBER,  PrimaryKeyCol1
FactType         VARCHAR, PrimaryKeyCol2
FactValue        VARCHAR
FactSource       VARCHAR
FactJournalist   VARCHAR

架空の映画データは次のようになります。

Movie Table
====================================================================================
MovieID  MovieName
====================================================================================
1        Green Lantern
2        The Tick

MovieFact Table
====================================================================================
MovieID  FactType       FactValue         FactSource       FactJournalist
====================================================================================
1        Director       Kubrick           CHUD             Sarah
1        Leading Male   Robert Redford    CHUD             James
1        Leading Female Miley Cyrus       Dark Horizons    James
1        Villain        Hugh Grant        CHUD             Sarah
2        Director       Mel Gibson        Yahoo            Cameron
2        Leading Male   John Lambert      Yahoo            Erica
...
于 2009-07-02T17:59:43.140 に答える
1

興味深いシナリオ。エンティティをファーストクラスのオブジェクトと考えることで、EAVゲットーらしさを回避できます。それらをファクトと呼びましょう。そして、この場合、すべての映画にまったく同じ4つの事実があるという点で、かなり直交していることが役立ちます。EAVテーブルは、元の/正しいテーブルにすることができます。次に、そのテーブルをマイニングし、データを適切に正規化された形式(つまり、最初のテーブル)に複製する外部プロセスを使用できます。このようにして、必要なデータとそのメタデータを取得し、マイニングプロセスの実行頻度に正確な映画情報を簡単に照会できます。

通常のテーブルとEAVテーブル全体で整合性を維持するデータベース内の方法はないように思われるため、データが有効なままであることを確認するには、「データベース外」の筋が必要だと思います。複雑な一連のトリガーを使用すると、ほとんど何でも達成できると思いますが、問題を「取得」する1人の人間の管理者はおそらくはるかに扱いやすいでしょう。

于 2009-06-30T21:05:14.117 に答える
1

別のアイデアがあります...それに穴を開けてください:)

Table: Movie
Columns: MovieId|Movie|Director|LeadMale|LeadFemale|Villain

Table: MovieSource
Columns: MovieSourceId|MovieId|MovieRoleId|Source|Journalist

Table: MovieRole
Columns: MovieRoleId|MovieRole
Values: 1|Director, 2|LeadMale, 3|LeadFemale, 4|Villain

私が考えているのは、ムービーテーブルの列はさまざまなタイプである可能性があるということです(この例では、すべて文字列/変数ですが、たとえば、ソースもある数値情報または日付情報である可能性があります)。

ただし、ソースデータの列タイプは、映画データの列タイプの関数としてはおそらく変化しないため、データの整合性を失うことなく、ソースにEAVシステムをより多く使用できます。

MovieRoleテーブルを使用すると、役割を明示的に列挙できるため、ソースとムービーテーブルの特定のセルとの間に確実なリンクを作成できます。

-ダン

于 2009-06-30T21:31:43.983 に答える
1

ソースデータには2つのフィールド(ソースとジャーナリスト)しかないため、次のようなメタデータテーブルをお勧めします。

Movie    DirectorSource  DirectorJournalist  LeadingMaleSource  LeadingMaleJournalist ...
---------------------------------------------------------------------------------------
The Tick   Yahoo           Cameron           ...                ...

これにより、重要度の低いソースデータがメインテーブルに含まれなくなりますが、クエリが複雑になることはなく、コードが読みやすくなります。

私は次の場合にのみアドバイスしEAVます...

  • ソースメタデータのフィールドが3つ以上あります
  • 映画のフィールドを簡単に追加または変更できる必要があります。(「Villain」から「PrimaryVillain」への変更は1日に数回行われます)
于 2009-07-01T00:23:05.433 に答える
0

私の反応は、SOには少し哲学的すぎるように思えるかもしれません。我慢して。

「ソース」列は主題データではなく、メタデータだと思います。これは、実際には、他のデータをどのようにして知るようになるかについてのデータです。それはそれをデータに関するデータにします、そしてそれはメタデータです。

EAVが問題を引き起こす理由の中には、データとメタデータが1行に混在しているという事実があります。結果に向けた中間段階として、自分で意図的にやったことがあります。しかし、私は成果物にデータとメタデータを混在させようとはしませんでした。

なぜそんなことをしなかったのかはわかりますが、簡潔に説明することはできません。

于 2009-06-26T20:42:43.123 に答える
0

誰も実際にそれをクラックしているわけではないので、私は自分の質問に答えるつもりです。EAVのようなテーブルが実際に行く唯一の方法であると私はかなり確信しています。各列にメタデータを保存するには(この場合はソースとジャーナリストに関して)、実際には各列をそれ自体がエンティティとして扱っています。これはEAVで許可されていることです。

データを格納するために元の列ごとに2番目と3番目の列を追加するなど、他のルートに進むこともできますが、それは確かにいくつかの基本的な正規化ルールに違反しており、おそらく後で痛みを引き起こすだけです。

于 2009-06-30T14:34:12.467 に答える
0

うーん....私はこれを使用したことがないので、経験から話しているわけではありません(つまり、機能しない場合でも私を責めないでください)が、表面的には、「一般的な」データを保存できるようです。通常のテーブルと同じように常にそこにあり、XMLとして変更される可能性のある「メタデータ」があります。問題は、それをうまくクエリする方法です。ここで説明するように、それを実行できる可能性があると思います。

于 2009-06-30T20:30:30.550 に答える
0

考慮すべきもう1つのアプローチは、クラステーブル継承です。Bill Karwinは、このSO回答のEAVオプションの優れたレビューと、多くの優れたコンテキストを持っています。

于 2009-07-01T00:37:56.743 に答える
0

コーディングする必要があるものに基づいて決定を下します。

src / journalnoが単なる追加情報である場合は、さらに列を追加します。しかし、複雑なsrc / journalnoクエリを作成することになった場合は、EAVを使用します。これは、LeadingFemaleJournalistVillainJournalistなどに移動するよりも、メタテーブルでジャーナリストの参照を検索する方が簡単だからです。

個人的には、src / journalデータを別のテーブルEAVスタイルにダンプする傾向がありますが、FKを使用して属性定義テーブルを定義します。自由形式の属性テキストフィールドを持つことは災害のレシピです-常に制約を介して属性を制御します。必要に応じて、参照整合性を向上させるためにトリガーを実装できます。

私にとって、それは視点に帰着します。ソースとジャーナリストはそれ自体が関係の懸念であると思いますか、それとも映画を補完するための単なる追加のデータですか?次のレベルの改良は、MovieDataSourceMovieDataJournalistに異なるテーブルを作成することです。これにより、FKを有効なソースジャーナリストを定義するテーブルにマップできます(これらのソース/ジャーナリストに関する詳細情報を具体化できます)。ここで行うことは、MovieエンティティとSource(およびJournalist)エンティティの間に多対多の関係を確立することです。

于 2009-07-02T08:04:28.923 に答える