2009-07-24 19 views
6

こんにちは私はこれで少し苦労し、いくつかのアイデアを使用することができます...レコードはどのテーブルにもリンクされていますか?

私のデータベースには次のテーブルがあります。 お客様 Supplers SalesInvoices PurchaseInvoices 通貨

などなど、私は、レコード

のいずれかのタイプに注意テーブルを「メモ」レコードを追加できるようにしたいと思い

この

をしたいと思います
NoteID  Int (PK) 
NoteFK  Int 
NoteFKType Varchar(3) 
NoteText  varchar(100) 
NoteDate  Datetime 

ここで、NoteFKは顧客またはサプライヤなどのPKであり、NoteFKTypeはどのタイプのReco今度は、NoteFKを使わずに複数のテーブルを参照するFKを追加することができないことに気付きました。すべてのテーブルに存在する必要があります。

あなたはどのように上記を設計しますか? FKはなぜにあなたはそれを他の方法で回避を行うと、他のテーブル(顧客、サプライヤーなどなど)で外部キーを持っていけない上記の表のいずれかに

乾杯、 ダニエル

+0

データベースレベルの参照整合性が必要ですか、またはアプリケーション管理参照整合性を維持できますか? – tschaible

答えて

-2

にする必要があるノートNotesID。このようにして、1対1マッピングができます。

+1

もし彼が1対多数の関係を持ちたいのであれば? 1つのエンティティに対する多くの注釈。彼は、必要でない多くの追加のテーブルで終わるだろう。 – maciejkow

+1

これは、同じNoteIDが複数回参照されないことを保証するものではありません。しかし、それはビジネス要件に依存します。 –

+0

1対多の必要性がある場合、リンクするための異なるテーブルを用意する代わりに、コンマ区切りのnotesIDを格納することができます(これは単なる回避策です)。 –

0

GUIDフィールドをCustomersテーブル、Suppliersテーブルなどに追加できます。次に、Notesテーブルで、そのGUIDを参照するように外部キーを変更します。

これは、データの完全性には役立ちません。しかし、それはM対Nの関係を任意の数のテーブルに簡単に可能にし、NotesテーブルにNoteFKTypeカラムを定義する必要がなくなります。

2

DBシステムは、ノートが他のテーブル内の既存のエンティティを参照しているかどうかをチェックしないことを、あなたが受け入れることができれば、大丈夫です。それは私が考えることができる唯一の設計は、重複を必要とせず、より多くのテーブルにスケーラブルです。

あなたがそれをデザインした方法で、メモを付ける別のエンティティタイプを追加すると、モデルを変更する必要はありません。また、既存のモデルや追加の表に列を追加する必要はありません。

データの整合性を保証するために、トリガーのセットを作成するか、ノートテーブルをしばらく消去するソフトウェアソリューションを作成することができます。

3

この外部キー制約についてデータベースに教えることができないという制限を受け入れる必要があります。したがって、整合性チェック(およびカスケード削除)なしで行う必要があります。

デザインは問題ありません。 これは、余分なテーブルに簡単に拡張できます。エンティティごとに複数のメモを持つことができます。また、ターゲット表は、メモ機能を認識する必要もありません。

エンティティテーブルごとに別々のメモテーブルを使用する利点は、「最新のメモ」や「特定のユーザーによって作成されたすべてのメモ」など、すべてのメモのクエリを簡単に実行できることです。

このテーブルの引数が大きすぎるとすると、それを5つのテーブルに分割すると、テーブルはそのサイズの約5分の1に縮小されますが、インデックスベースのアクセスには違いはありません。データベースは、大きなテーブルを扱うように構築されています(適切なインデックスが作成されている限り)。

0

トリガーを使用して "マルチ"キーを簡単に実装できます。トリガーは非常に柔軟なメカニズムを提供し、あなたが望む完全性検査を行うことができます。

1

私はあなたの提案をする前に2度考えます。短期間でシンプルでエレガントに見えるかもしれませんが、データの完全性とパフォーマンスに本当に関心がある場合は、親テーブルごとに個別のメモテーブルを用意することが最善の方法です。長年にわたり、私はこの問題に、他の回答(トリガー、GUIDなど)にある解決策を使用してアプローチしました。私は、追加された複雑さとパフォーマンスの低下がそれに値するものではないという結論に達しました。適切な外部キー制約を持つ親テーブルごとに別々のノートテーブルを持つことで、ルックアップと結合が簡単かつ高速になります。関連する項目を1つの表に結合すると、結合構文が醜くなり、メモ表が大きくなり、遅くなります。

+0

+1私は同意し、これを保証することができます。長期的には、ソリューションを複雑にし、最終的に対処する必要がある技術的負債を追加するだけです。 –

+0

一方、現在のソリューションでは、複数のノートテーブルでは難しいすべてのノートでクエリを実行できます。 – Thilo

+1

@Thilo - Michaelのアドバイスを念頭に置いて、SQLビューは、すべてのノートテーブルを単一のクエリソースに集約するより適切な方法です。 –

1

私はマイケルMcLosky、ある程度に同意します。

私の心の質問は:複数のノートテーブルを持つ技術的なコストはいくらですか?

私の考えでは、同じ機能を1つのテーブルに統合することをお勧めします。レポート作成やその他の開発が簡単になります。テーブルのリストを小さくして管理しやすくすることは言うまでもありません。

これはバランスの取れた行為であり、あなたはこのようなことをするコストとコストの両方をあらかじめ決めておく必要があります。 My -personal- preferenceは、データベースの参照整合性です。私の見解では、インテグリティのアプリケーション管理は、ビジネスロジックから除外されるべきです。データベースは、実際にあなたの質問に答えるために...データは常に一貫して有効である


を確実にしなければならない...私が使用する

オプションは、ユーザー定義を使用してチェック制約であります値をチェックする機能。これはM $ SQL Serverで動作します...

CREATE TABLE Test_Table_1 (id INT IDENTITY(1,1), val INT) 
GO 
CREATE TABLE Test_Table_2 (id INT IDENTITY(1,1), val INT) 
GO 
CREATE TABLE Test_Table_3 (fk_id INT, table_name VARCHAR(64)) 
GO 

CREATE FUNCTION id_exists (@id INT, @table_name VARCHAR(64)) 
RETURNS INT 
AS 
BEGIN 
    IF (@table_name = 'Test_Table_1') 
     IF EXISTS(SELECT * FROM Test_Table_1 WHERE id = @id) 
      RETURN 1 
    ELSE 
    IF (@table_name = 'Test_Table_2') 
     IF EXISTS(SELECT * FROM Test_Table_2 WHERE id = @id) 
      RETURN 1 

    RETURN 0 
END 
GO 

ALTER TABLE Test_Table_3 WITH CHECK ADD CONSTRAINT 
    CK_Test_Table_3 CHECK ((dbo.id_exists(fk_id,table_name)=(1))) 
GO 
ALTER TABLE [dbo].[Test_Table_3] CHECK CONSTRAINT [CK_Test_Table_3] 
GO 

INSERT INTO Test_Table_1 SELECT 1 
GO 
INSERT INTO Test_Table_1 SELECT 2 
GO 
INSERT INTO Test_Table_1 SELECT 3 
GO 
INSERT INTO Test_Table_2 SELECT 1 
GO 
INSERT INTO Test_Table_2 SELECT 2 
GO 
INSERT INTO Test_Table_3 SELECT 3, 'Test_Table_1' 
GO 
INSERT INTO Test_Table_3 SELECT 3, 'Test_Table_2' 
GO 

この例では、最後の挿入ステートメントは失敗します。

1

FK参照整合性を得るには、他のテーブルごとに1つの列をnotesテーブルに入れる必要があります。

create table Notes (
    id int PRIMARY KEY, 
    note varchar (whatever), 
    customer_id int NULL REFERENCES Customer (id), 
    product_id int NULL REFERENCES Product (id) 
) 

次に、列が1つしか設定されていないことを確認するための制約が必要です。

お客様と商品の両方に関連付けることができます。あなた次第。

別の参照テーブルを追加する場合、このデザインではNotesに新しい列を追加する必要があります。

+0

これはこれまでのところ最も洗練されたソリューションでしょう。 – Thilo

関連する問題