49

外部キーとは、単一の行が単一の行を参照する必要があることを意味すると思いましたが、そうではないいくつかのテーブルを見ています。テーブル 1 には、テーブル 2 のカラム 2 に外部キー制約を持つカラム 1 がありますが、カラム 2 に同じ値を持つテーブル 2 には多くのレコードがあります。column2 にも一意でないインデックスがあります。これは何を意味するのでしょうか?外部キー制約は、正しい列に正しい値を持つレコードが少なくとも 1 つ存在する必要があることを意味するだけですか? そのようなレコードが 1 つだけ存在する必要があることを意味していると思いました (null がどのように画像に収まるかはわかりませんが、現時点ではそれほど心配していません)。

更新:どうやら、この動作は私が使用していたMySQLに固有のものですが、元の質問では言及していませんでした。

4

7 に答える 7

54

MySQLのドキュメントから:

InnoDB では、外部キー制約で一意でないキーを参照できます。これは、標準 SQL に対する InnoDB 拡張です。

ただし、参照されるテーブルの一意でない列に外部キーを使用しないようにする実際的な理由があります。つまり、その場合の「ON DELETE CASCADE」のセマンティックはどうあるべきでしょうか?

ドキュメントはさらにアドバイスします:

一意でないキーまたは NULL 値を含むキーへの外部キー参照の処理は、明確に定義されていません (...) UNIQUE (PRIMARY を含む) および NOT NULL キーのみを参照する外部キーを使用することをお勧めします。

于 2010-02-01T19:15:31.707 に答える
7

あなたの分析は正しいです。キーは一意である必要はなく、制約は一致する行のセットに作用します。通常は有用な動作ではありませんが、必要な状況が発生する可能性があります。

于 2009-02-26T01:36:28.107 に答える
3

これが発生した場合、通常は 2 つの外部キーが相互にリンクされていることを意味します。多くの場合、キーを主キーとして含むテーブルは、スキーマにも含まれていません。

例: COLLEGES と STUDENTS の 2 つのテーブルには、どちらも ZIPCODE という列が含まれています。

ざっくりチェックしてみると

SELECT * FROM COLLEGES JOIN STUDENTS ON COLLEGES.ZIPCODE = STUDENTS.ZIPCODE

この関係が多対多であることがわかるかもしれません。スキーマに、主キー ZIPCODE を持つ ZIPCODES というテーブルがある場合、実際に何が起こっているかは明らかです。

しかし、私たちのスキーマにはそのようなテーブルはありません。ただし、スキーマにそのようなテーブルがないからといって、そのようなデータが存在しないわけではありません。USPO のどこかに、まさにそのようなテーブルがあります。そして、COLLEGES.ZIPCODE と STUDENTS.ZIPCODE の両方が、認識していなくても、そのテーブルへの参照です。

これは、データベース構築の実践というよりもデータの哲学に関係していますが、基本的なことをきちんと示しています。つまり、データには、私たちが発明した特性だけでなく、発見した特性があります。もちろん、私たちが発見したものは、他の誰かが発明したものかもしれません。それは確かにZIPCODEの場合です。

于 2009-02-26T06:20:54.070 に答える
3

はい、基本的に任意のテーブルの任意の列に外部キーを作成できます。ただし、ほとんどの場合、それらを主キーに作成します。

主キーを指していない外部キーを使用する場合は、パフォーマンスのために、参照されている列に (一意ではない) インデックスを作成することもできます。

使用している RDBMS によって異なります。暗黙的にこれを行う人もいれば、他のトリックを使用する人もいると思います。RTM。

于 2009-02-26T02:02:24.783 に答える
1

PostgreSQL もこれを拒否します (とにかく、可能であっても、それが良い考えであるとは限りません)。

essais=> CREATE TABLE Cities (name TEXT, country TEXT);
CREATE TABLE
essais=> INSERT INTO Cities VALUES ('Syracuse', 'USA');
INSERT 0 1
essais=> INSERT INTO Cities VALUES ('Syracuse', 'Greece');
INSERT 0 1
essais=> INSERT INTO Cities VALUES ('Paris', 'France');
INSERT 0 1
essais=> INSERT INTO Cities VALUES ('Aramits', 'France');
INSERT 0 1
essais=> INSERT INTO Cities VALUES ('Paris', 'USA');
INSERT 0 1

essais=> CREATE TABLE People (name TEXT, city TEXT REFERENCES Cities(name));
ERROR:  there is no unique constraint matching given keys for referenced table "cities"
于 2009-02-26T13:09:52.980 に答える
0

どのデータベースについて話しているのですか? SQL 2005 では、一意の制約 (主キーなど) を持たない列を参照する外部キー制約を作成できません。

create table t1
(
  id int identity,
  fk int
);

create table t2
(
  id int identity,
);

CREATE NONCLUSTERED INDEX [IX_t2] ON [t2] 
(
    [id] ASC
);
ALTER TABLE t1 with NOCHECK
ADD CONSTRAINT FK_t2 FOREIGN KEY (fk)
    REFERENCES t2 (id) ;


Msg 1776, Level 16, State 0, Line 1
There are no primary or candidate keys in the referenced table 't2' 
that match the referencing column list in the foreign key 'FK_t2'.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint. See previous errors.

実際にこれを行うことができれば、効果的に多対多の関係を持つことになりますが、これは中間テーブルなしでは不可能です。私はこれについてもっと聞くことに本当に興味があります...

この関連する質問と回答も参照してください。

于 2009-02-26T02:21:49.167 に答える