1

状況: 複数のインストール可能なモジュールを持つ PHP アプリケーションは、mod_A、mod_B、mod_C などのスタイルで、それぞれのデータベースに新しいテーブルを作成します。それぞれにセクション ID 列があります。

現在、特定の section_id のすべてのエントリを探しています。「Select * from mod_a、mod_b、mod_c ... mod_xyzzy where section_id=value」以外の方法があることを願っています...さらに悪いことに、別の各モジュールのクエリ。

4

8 に答える 8

1

2つの提案があります。

  1. おそらく、すべてのテーブルを統合する必要があります。それらがすべて同じ構造を含んでいる場合は、モジュールを識別する1つの新しい列( "A"、 "B"、 "C"、....)を追加するだけの1つの「マスター」モジュールテーブルを用意しないのはなぜですか。

    モジュールテーブルがほとんど同じであるが、異なる列がいくつかある場合でも、すべての共通情報を1つのテーブルに統合し、それらの違いを備えた小さなモジュール固有のテーブルを保持できる場合があります。次に、それらに参加する必要があります。

    この提案は、言及した列section_idに対するクエリが、すばやく検索するために非常に重要であることを前提としています。1つのクエリですべての一般的な情報を取得し、2つ目のクエリで、必要に応じて特定の情報を取得します。(そして、そうではないかもしれません-たとえば、セクションの存在を検証しようとした場合、共通のテーブルでそれを見つけるだけで十分です)

  2. または、section_idをそれらが含まれるモジュールにマップする別のテーブルを追加することもできます。

    section_id | モジュール
    ----------- + -------
          1 | A
          2 | B
          3 | A
         ... | ..。
    

    これは、2つのクエリを実行する必要があることを意味します。1つはこのマッピングテーブルに対して、もう1つはモジュールテーブルに対して実行して、有用なデータを引き出します。

    すべてのモジュールに共通する他の列を検索する必要がある場合は、このテーブルを他の列およびそれらの列のインデックスで拡張できます。

    この方法には、データが複製されるという明らかな欠点があります。

于 2008-09-19T19:08:37.090 に答える
1

どうですか?

SELECT * FROM mod_a WHERE section_id=value
UNION ALL
SELECT * FROM mod_b WHERE section_id=value
UNION ALL
SELECT * FROM mod_c WHERE section_id=value
于 2008-09-19T18:20:05.520 に答える
1

テーブルが時間の経過とともに変化している場合は、SP でソリューションをインライン コード生成できます (疑似コード - 記入する必要があります)。

SET @sql = ''

DECLARE CURSOR FOR
SELECT t.[name] AS TABLE_NAME
FROM sys.tables t
WHERE t.[name] LIKE 'SOME_PATTERN_TO_IDENTIFY_THE_TABLES'

-- またはこれ

DECLARE CURSOR FOR
SELECT t.[name] AS TABLE_NAME
FROM TABLE_OF_TABLES_TO_SEACRH t

START LOOP

IF @sql <> '' SET @sql = @sql + 'UNION ALL '
SET @sql = 'SELECT * FROM [' + @TABLE_NAME + '] WHERE section_id=value '

END LOOP

EXEC(@sql)

私は、動的 SQL を使わずにこの手法を将来的に保証する明らかな方法がない場合に、この手法をときどき使用しました。

注: ループでは、COALESCE/NULL 伝播トリックを使用して、ループの前に文字列を NULL のままにしておくことができますが、イディオムに慣れていない場合は明確ではありません。

SET @sql = COALESCE(@sql + ' UNION ALL ', '')
    + 'SELECT * FROM [' + @TABLE_NAME + '] WHERE section_id=value '
于 2008-09-19T18:54:01.837 に答える
0

データベース側のオプションは、さまざまなテーブルのUNIONALLのビューを作成することです。テーブルを追加するときは、ビューに追加する必要がありますが、そうでない場合は、単一のテーブルのように見えます。

CREATE VIEW modules AS (
    SELECT * FROM mod_A
    UNION ALL 
    SELECT * FROM mod_B
    UNION ALL 
    SELECT * FROM mod_C
);

select * from modules where section_id=value;
于 2008-09-19T21:58:32.143 に答える
0
SELECT * FROM (
    SELECT * FROM table1
    UNION ALL
    SELECT * FROM table2
    UNION ALL
    SELECT * FROM table3
) subQry
WHERE field=value
于 2008-09-19T21:41:03.103 に答える
0

私はボルジャブと同じ考えを提案するつもりでした。唯一の問題は、別のテーブルを追加する場合、これらのクエリをすべて更新する必要があることです。私が見る唯一の他のオプションは、ストアドプロシージャです。

ここで別のオプション、または少なくともこれを提示するより簡単な方法を考えました。これらの複数のテーブルに対するビューを使用して、それらを 1 つとして表示することもできます。これにより、クエリがよりきれいに見え、理解しやすくなり、これらに対して他のクエリを実行するときに長いユニオン クエリを書き直す必要がなくなります。複数のテーブル。

于 2008-09-19T18:22:23.427 に答える
0

追加情報が役立つかもしれませんが、すでに解決策があるようです。section_id を持つすべてのテーブルから選択する必要があります。section_id で結合するテーブル リストの代わりに結合を使用できます。例えば

select a.some_field, b.some_field.... 
from mod_a a
inner join mod_b b on a.section_id = b.section_id
...
where a.section_id = <parameter>

これをビューとしてパッケージ化することもできます。また、* の代わりにフィールド リストがあることに注意してください。実際に * を使用する場合は、これをお勧めします。

于 2008-09-19T18:26:08.893 に答える
0

複数のテーブルから情報を集計する方法は非常に多くあります。例で述べたように参加するか、複数のクエリを実行して、ボルジャブの回答のように結合することができます。すべてのモジュール テーブルと交差するテーブルを作成するというアイデアが役立つかどうかはわかりませんが、section_id がそのようなテーブルにある場合、単一のクエリからすべてを取得できます。そうでなければ、私はあなたの怠惰を賞賛しますが、言うのを恐れています、私はその仕事を楽にする方法がわかりません:)

于 2008-09-19T18:27:38.060 に答える