2009-11-12 6 views
33

1対1の関係を定義する必要があり、SQL Serverで適切な方法を見つけることができないようです。SQL Serverで1対1の関係を定義する

なぜ1対1の関係になっているのですか?

私はDAL(Linq)としてWCFを使用していますが、BLOB列を含むテーブルがあります。 BLOBはほとんど変更されず、クエリが作成されるたびにBLOBを転送するのは帯域幅の無駄になります。

私はthis solutionを見ました。このアプローチを実装しようとすると、Linqがちょっとしたことに気付くことができます。

アイデア?

答えて

76

スーパータイプとサブタイプの関係では、実際には1対1が頻繁に使用されます。子テーブルでは、主キーは親テーブルの外部キーとしても機能します。ここでの例である:同じテーブルの同じ行に1関連項目:

org_model_00

CREATE TABLE Organization 
( 
    ID  int PRIMARY KEY, 
    Name  varchar(200), 
    Address varchar(200), 
    Phone varchar(12) 
) 
GO 

CREATE TABLE Customer 
( 
    ID    int PRIMARY KEY, 
    AccountManager varchar(100) 
) 
GO 

ALTER TABLE Customer 
    ADD FOREIGN KEY (ID) REFERENCES Organization(ID) 
     ON DELETE CASCADE 
     ON UPDATE CASCADE 
GO 
+5

ここで神に感謝している人は、SQLとリレーショナルデータベースを知っています。あなたは関係が**明示的**であることを示しました。関係が1 :: 1であるかどうかわからない人は、Organisation.IDであるCustomer.IDが**ユニーク**であることに注意してください。任意の組織行。 – PerformanceDBA

+30

@PerformanceDBA:親テーブルの各行に対して、サブタイプテーブルの1つに一致する行があることを保証する制約がないため、関係は「1:0..1」です。投稿されたスキーマの場合、 'Organization'の各行について、Customerには0行または1行、したがって、1:0..1があります。 – onedaywhen

+1

@oneday。ありがとうございます。しかし、表面の問題(明白)のあなたの説明は、深い問題には関係ありません。コメント自体ではなく、あなたのコメントの根拠は間違っています。あなたはアダムと同じ誤解をしています(彼はその後、彼の答えを削除しています)。この問題はコメントでは対処できません。リレーショナルデータベースの命名法を理解することに本当に関心があるなら、新しい質問をしてください。私は完全にそれに答えます。私はそれ以上のコメントには答えません。 – PerformanceDBA

4

なぜ各テーブルの外部キーを一意にしないのですか?

+0

したがって、tableA = 3のキーとtableB = 4のキーを持つ場合、テーブル内で一意ですが、関係はありません。 – JeffO

+1

ただし、tableA.id = 3、tableB.tableAId = 3、tableB.tableAIdが一意で、tableBをtableAと同じにすると、最大で1対1になることが保証されます。 – Myles

2

明示的な1対1の関係はありません。

しかし、tbl1.idとtbl2.idが主キーであり、tbl2.idがtbl1.idを参照する外部キーであることから、暗黙の1:0..1の関係が作成されています。

1

1を置きます。それは、「リレーショナルデータベース」の「関係」は、関連するものが同じ行に入るところです。

あなたは、ワイヤ上を移動するデータのサイズを小さくしたい場合はいずれかの必要なカラムだけを投影考える:

SELECT c1, c2, c3 FROM t1 

のみ関連する列を投写するビューを作成し、必要なときにそのビューを使用します。

CREATE VIEW V1 AS SELECT c1, c2, c3 FROM t1 
SELECT * FROM t1 
UPDATE v1 SET c1=5 WHERE c2=7 

BLOBはSQL Serverではオフラインで格納されるため、データを垂直分割することで多くのディスクIOを節約することはできません。これらがBLOB以外の列であった場合は、前述のように垂直パーティショニングに役立つことがあります。これは、ディスクIOを少なくしてベーステーブルをスキャンするためです。

0

これはどうですか。最初のテーブルのプライマリキーを2番目のテーブルのプライマリキーにリンクします。

Tab1.ID(PK)< - > Tab2.ID(PK)

私の問題は、私は両方で必須フィールドを持つ2段階のプロセスを持っていました。プロセス全体を1つのエピソード(同じテーブルに入れる)として分類できますが、初期段階と最終段階があります。

+0

私はダミールが最初の答えで示唆したものだと思います。 –

+1

必須の双方向制約を設定することはできません。トランザクションを実装し、SQLコンテキスト内でトランザクションを順番に処理する必要があります。それは簡単です。 – PerformanceDBA

0

私の意見では、LINQクエリでBLOBを読み取らない方がよい解決策は、ビューを作成してBLOBの列を除くすべての列を含むことです。

ビューに基づいてEFエンティティを作成できます。

+0

あなたの投稿に署名する必要はありませんので、それはあなたのために自動的に行います。また、答えには一般的に、あなたが示唆していることをするコードの例が示されるべきです。 :| – vdbuilder