3

現在、テクニカル Wiki サイトの 2 番目のバージョンを作成中ですが、改善したい点の 1 つはデータベースの設計です。問題 (またはそう思う) は、各ドキュメントを表示するには、15 以上のテーブルを結合する必要があることです。使用したプログラマー、CPU、タグ、周辺機器、PCB レイアウト ソフトウェア、難易度など、各 wiki エントリに関連付けられた説明データを含むルックアップ テーブルがたくさんあります。

レイアウトの例を次に示します。

    doc
--------------
id   | author_id   |    doc_type_id      .....
1    | 8           |        1
2    | 11          |        3
3    | 13          |        3

_

    lookup_programmer
--------------
doc_id   | programmer_id     
1        | 1                    
1        | 3                     
2        | 2                   

_

     programmer
--------------
programmer_id   | programmer      
1               | USBtinyISP        
2               | PICkit              
3               | .....              

一部のドキュメント ID には、単一の属性 (プログラマーなど) に対して複数のエントリがある場合があるため、これを補うために DB を作成しました。programmer他の 10 個の属性には、上記の 2 つのテーブルと同様のレイアウトがあります。1 つの文書記事を表示するために、約 20 のテーブルが結合されます。

特定の特徴を持つ記事を見つけるために、Sphinx 検索エンジンを使用しました。基本的に、Sphinx はすべてのデータにインデックスを付け (保存はしません)、提示されたフィルターに基づいて対象の wiki ドキュメント ID を返します。特定のプログラマーを使用する記事を見つけてから日付で並べ替えたい場合、MYSQL は最初にすべてのドキュメントを 2 つのプログラマー テーブルに結合し、次にフィルター処理を行い、最後に挿入時間で残りを並べ替える必要があります。一時テーブルで行われるため、フィルター処理された結果を並べ替えるのに役立つインデックスはありません (150k のドキュメント ID では長い時間がかかります)。ご想像のとおり、フィルタリングが必要なパラメータが増えると、すぐに悪化します。

それは、私がSphinxに頼らなければならないからです-特定のCPUとプログラマーを使用するすべてのwikiエントリを言う-現在のセットアップにはDBの匂いがあると私は信じています....

編集: [Entity–attribute–value モデル] を実装したようです1

4

1 に答える 1

1

EAV を実装したことを示唆するものは何もありません。代わりに、すべてのテーブルのすべての行に ID 番号を割り当てたように見えます。これは、結合数を増やすための保証された方法であり、正規化とはの関係もありません。(「ID 番号を追加しました」の標準形はありません。)

ルックアップ テーブルを 1 つ選択します。(私の例では「プログラマー」を使用します。) このようにビルドしないでください。

create table programmer (
  programmer_id integer primary key,
  programmer varchar(20) not null,
  primary key (programmer_id),
  unique key (programmer)
);

代わりに、このようにビルドします。

create table programmer (
  programmer varchar(20) not null,
  primary key (programmer)
);

また、それを参照する表では、カスケード更新と削除を検討してください。

create table lookup_programmer (
  doc_id integer not null,
  programmer varchar(20) not null,
  primary key (doc_id, programmer),
  foreign key (doc_id) references doc (id) 
    on delete cascade,
  foreign key (programmer) references programmer (programmer)
    on update cascade on delete cascade
);

あなたは何を得ましたか?外部キー参照が提供するすべてのデータ整合性を維持し、行がより読みやすくなり、結合が排除されました。すべての「ルックアップ」テーブルをそのように構築すると、ルックアップ テーブルごとに 1 つの結合がなくなります。(何百万もの行がない限り、おそらくパフォーマンスの低下は見られません。)

于 2012-09-08T00:09:15.307 に答える