2

私はテーブル構造を持っていますが、最善の方法を作成する方法がよくわかりません。

基本的に、tblSystemItems と tblClientItems の 2 つのテーブルがあります。「アイテム」を参照する列を持つ 3 番目のテーブルがあります。問題は、この列がシステム アイテムまたはクライアント アイテムのいずれかを参照する必要があることです。どちらでもかまいません。システム アイテムには 1..2^31 の範囲のキーがあり、クライアント アイテムには -1..-2^31 の範囲のキーがあるため、衝突は発生しません。

アイテムをクエリするときはいつでも、2 つのテーブルの内容間で UNION ALL を実行するビューを使用してクエリを実行しています。

したがって、最適には、ID を一意に保ちながら、ビューは常に 2 つのテーブルの結合になるため、ビューの結果を参照する外部キーを作成したいと考えています。しかし、ビューを参照できないため、これを行うことはできません。

これで、外部キーをドロップするだけで問題ありません。ただし、参照チェックとカスケード削除/null 機能の設定が本当に必要です。トリガー以外にこれを行う方法はありますか?

4

6 に答える 6

1

返信が遅くなり申し訳ありません。深刻な週末炎に悩まされています。

クライアント テーブルとシステム テーブルの両方からの PK を含めるために 3 番目のテーブルを使用することについては、同期が過度に複雑になり、アプリが 3 番目のテーブルを認識している必要があるため、好ましくありません。

発生した別の問題は、アイテムを参照する必要がある 3 番目のテーブルがあることです。システムまたはクライアントのどちらでもかまいません。基本的に、テーブルを分離するということは、ClientItemID と SystemItemID の 2 つの列が必要であり、それぞれが null 可能性を持つテーブルごとに制約を持っているということです。

結局、別のソリューションを選択しました。全体の問題は、新しいシステム アイテムをテーブルに簡単に同期することであり、クライアント アイテムをいじったり、衝突を回避したりする必要はありませんでした。

最終的に、Items というテーブルを 1 つだけ作成しました。Items には、「SystemItem」という名前のビット列があり、これは明らかなことを定義しています。私の開発/システム データベースでは、PK を int ID(1,1) として取得しています。テーブルがクライアント データベースに作成された後、ID キーは (-1,-1) に変更されます。つまり、クライアント アイテムはネガティブになり、システム アイテムはポジティブになります。

同期の場合、IDENTITY INSERT ON を使用して残りを同期している間、基本的に (SystemItem = 1) を含むものはすべて無視します。したがって、クライアント アイテムを完全に無視し、衝突を回避しながら同期することができます。また、クライアント アイテムとシステム アイテムの両方をカバーする "Items" テーブルを 1 つだけ参照することもできます。覚えておくべき唯一のことは、クライアントが新しいアイテムを挿入するときにあらゆる種類のページの再構築を避けるために、標準のクラスター化されたキーを下降するように修正することです (クライアントの更新とシステムの更新は 99%/1% のようです)。

于 2008-11-10T20:45:41.470 に答える
0

アイテムを参照するテーブルの一意のID(db生成-シーケンス、autoincなど)を作成し、システムアイテムとクライアントアイテムをそれぞれ参照する2つの追加の列( tblSystemItemsFKtblClientItemsFk )を作成できます-一部のデータベースでは、null許容の外部キー。

ORMを使用している場合は、列情報のみに基づいて、クライアントアイテムとシステムアイテムを簡単に区別することもできます(このようにして、IDの重複を防ぐために負の識別子を使用する必要はありません)。

もう少しbakcground/contextを使用すると、最適なソリューションを決定するのがおそらく簡単になります。

于 2008-11-06T14:20:28.520 に答える
0

PK ItemiDを持つItemsというテーブルを追加し、ItemType ="System"または"Client"という単一の列にClientItemsテーブルPK(ClientItemIdという名前)とSystemItems PK(SystemItemIdという名前)を両方ともItems.ItemIdのFKにします。これらの関係は0対1の関係です(0-1)

次に、アイテムを参照する3番目のテーブルで、FK制約がこの追加の(Items)テーブルのitemIdを参照するようにします。

ストアドプロシージャを使用して挿入を実装している場合は、アイテムを挿入するストアドプロシージャに、最初に新しいレコードをItemsテーブルに挿入させてから、そのテーブルで自動生成されたPK値を使用して、実際のデータレコードをSystemItemsまたはシステムがItemsテーブルのItemId列に挿入した自動生成された(ID)値を使用して、同じストアドプロシージャ呼び出しの一部としてClientItems(どちらであるかによって異なります)。

これは「サブクラス化」と呼ばれます

于 2008-11-06T14:51:00.393 に答える
0

使用しているデータベースでも同様の状況が発生しています。EntityIDと呼ぶ各テーブルに「候補キー」があります。次に、他の複数のテーブルのアイテムを参照する必要があるテーブルがある場合は、EntityIDを使用してその行を参照します。すべてを相互参照するためのEntityテーブルがあります(EntityIDがEntityテーブルの主キーであり、他のすべてのEntityIDがFKであるように)が、Entityテーブルを頻繁に使用することはありません。

于 2008-11-11T04:50:59.963 に答える
0

おそらく、2 つのテーブルのすべての主キーを単純に格納する tblItems などのテーブルが必要です。アイテムを挿入するには、アイテムが tblSystemItems テーブルに入力されたときに PK が tblItems テーブルに入力されるようにするために、2 つの手順が必要です。

3 番目のテーブルには、tblItems への FK があります。ある意味で、tblItems は他の 2 つの項目テーブルの親です。Item を照会するには、tblItems、tblSystemItems、および tblClientItems の間に JOIN を作成する必要があります。

[以下のコメントの編集] tblSystemItems と tblClientItems が独自の PK を制御している場合でも、それらを制御できます。おそらく最初に tblSystemItems に挿入し、次に tblItems に挿入します。Hibernate のようなツールを使用して継承構造を実装すると、このような結果になります。

于 2008-11-06T14:13:28.253 に答える
0

あなたのテーブルのデザインに頭を悩ませています。それが正しいかどうかはわかりません。3 番目のテーブルは詳細情報を提供しているだけかもしれませんが、主キーは実際には ITEM テーブルのものであり、FOREIGN キーはシステムおよびクライアント アイテム テーブルのものであると思わずにはいられません。次に、アイテムからシステムおよびクライアントのアイテム テーブルへの右外部結合を実行するだけで、すべての制約が正常に機能します。

于 2008-11-06T19:53:41.590 に答える