2

私のデータベース設計は次のようになっています。ショートフォーム:

CREATE TABLE LANDSLIDE (
      LNUMBER SERIAL NOT NULL,
      PRIMARY KEY (LNUMBER)
      ...

そこに 4 つのテーブルのような (地滑りの一部)

CREATE TABLE SCARP (
      SCPNUM CHAR(7) NOT NULL, 
      LNUMBER SMALLINT NOT NULL, 
      FOREIGN KEY (LNUMBER) REFERENCES LANDSLIDE (LNUMBER) ON DELETE CASCADE,
      ...
                   );

例: scpnum = scp0001

CREATE TABLE ACCUMULATION (
      ACCUNUM CHAR(8) NOT NULL,
      LNUMBER SMALLINT NOT NULL,
      FOREIGN KEY (LNUMBER) REFERENCES LANDSLIDE (LNUMBER) ON DELETE CASCADE,
      ...
                          );

例 accunum = accu0001

CREATE TABLE FRONT (
      FRNUM CHAR(6) NOT NULL,
      LNUMBER SMALLINT NOT NULL, 
      FOREIGN KEY (LNUMBER) REFERENCES LANDSLIDE (LNUMBER) ON DELETE CASCADE,
      ...
                    );

例: frnum = fr0001

CREATE TABLE OTHER (
      OTHERNUM CHAR(9) NOT NULL,
      LNUMBER SMALLINT NOT NULL,
      FOREIGN KEY (LNUMBER) REFERENCES LANDSLIDE (LNUMBER) ON DELETE CASCADE,
      ...
                   );

例: othernum = other0001

マテリアル (異なる石、異なる部分の土) と呼ばれる別のテーブルがあります。

CREATE TABLE MATERIAL (
     MATNUMBER VARCHAR(9) NOT NULL,
     ROCK,
     DISTRIBUTION,
     ...
     PRIMARY KEY(MATNUMBER,ROCK,DISTRIBUTION,...),
     CONSTRAINT material_matnumber_scarp_fkey FOREIGN KEY 
     (MATNUMBER) REFERENCES SCARP (SCPNUM) ON DELETE CASCADE,
     CONSTRAINT material_matnumber_accumulation_fkey FOREIGN KEY 
     (MATNUMBER) REFERENCES ACCUMULATION (ACCUNUM) ON DELETE CASCADE,
     CONSTRAINT material_matnumber_front_fkey FOREIGN KEY 
     (MATNUMBER) REFERENCES FRONT (FRNUM) ON DELETE CASCADE,
     CONSTRAINT material_matnumber_other_fkey FOREIGN KEY 
     (MATNUMBER) REFERENCES OTHER (OTHERNUM) ON DELETE CASCADE
                      );

(他のテーブルにエントリを作成した後) マテリアルにデータを挿入すると、エラーが返されます。エラー: テーブル "material" の挿入または更新が外部キー制約 "material_matnumber_accumulation_fkey" に違反しています 詳細: キー (matnumber)=(scp0001) がテーブル "accumulation" に存在しません

テーブル マテリアルは次のようになります。

MATNUMBER | ROCK | DISTRIBUTION | ...
----------+------+--------------+------
scp0001   |   A  |    lateral   | ...
scp0001   |   B  |    lateral   | ...
accu0001  |   B  |    central   | ...
scp0002   |   C  |    NULL      |
accu0002  |   A  |    lateral   |
fr0002    |   A  |    NULL      |
scp0003   |   B  |    cantral   |
accu0003  |   B  |    lateral   |
other0003 |   C  |    NULL      |

マット番号により、すべてのエントリが一意です。

4

2 に答える 2

2

私の理解が正しければ、これはスーパータイプ/サブタイプ パターンで解決できる一般的な問題です。テーブルに 4 つの null 許容 FK 列を含めることもできMaterialますが、ここに私の提案があります。

CREATE TABLE Landslide  (                  --- no change here
      LNumber SERIAL NOT NULL,
      PRIMARY KEY (LNumber)
      ...

あなたは言う:「(地滑りの一部)のようなテーブルが4つあります」

そこで、追加LandslidePartのテーブルを作成します (これが「スーパータイプ」テーブルです)。

CREATE TABLE LandslidePart (
      PartType CHAR(1) NOT NULL, 
      PartNumber INT NOT NULL, 
      LNumber SMALLINT NOT NULL,
      PRIMARY KEY (PartType, PartNumber),
      CHECK (PartType IN ('S', 'A', 'F', 'O')),       --- the 4 subtypes
      FOREIGN KEY (LNumber) REFERENCES Landslide (LNumber) ON DELETE CASCADE,
      ...                                             --- other columns that are
                                                      --- common in all 4 tables
                   );

次に、わずかに変更された 4 つの (「サブタイプ」) テーブルがあります。

CREATE TABLE Scarp (
      PartType CHAR(1) NOT NULL, 
      PartNumber INT NOT NULL, 
      PRIMARY KEY (PartType, PartNumber),
      CHECK (PartType = 'S'), 
      FOREIGN KEY (PartType, PartNumber) 
          REFERENCES LandslidePart (PartType, PartNumber) 
          ON DELETE CASCADE,
      ...                           --- columns that are related to Scarp
                   );

CREATE TABLE Accumulation (
      PartType CHAR(1) NOT NULL, 
      PartNumber INT NOT NULL, 
      PRIMARY KEY (PartType, PartNumber),
      CHECK (PartType = 'A'), 
      FOREIGN KEY (PartType, PartNumber) 
          REFERENCES LandslidePart (PartType, PartNumber) 
          ON DELETE CASCADE,
      ...                           --- columns that are related to Accumulation 
                   );

 --- We define in a similar way the other 2 tables: "Front" and "Other"

これで、「スーパータイプ」 ( ) テーブルMaterialを参照し、4 つのテーブルのいずれも参照しないテーブルを定義できます。LandslidePart

CREATE TABLE Material (
     PartType CHAR(1) NOT NULL, 
     MatNumber INT NOT NULL,
     Rock,
     Distribution,
     ...
     PRIMARY KEY(PartType, MatNumber, Rock, Distribution, ...),
     CONSTRAINT material_matnumber_landslidepart_fkey 
     FOREIGN KEY (PartType, MatNumber) 
         REFERENCES LandslidePart (PartType, PartNumber) 
         ON DELETE CASCADE,
                      );
于 2013-03-01T08:16:38.393 に答える
0

外部キーの長さとデータ型を確認してください。

MATNUMBER VARCHAR(9) NOT NULL以下の,へのすべての参照MATERIAL

SCPNUM CHAR(7) NOT NULL, *should be* SCPNUM VARCHAR(9) NOT NULL,
ACCUNUM CHAR(8) NOT NULL *should be* ACCUNUM VARCHAR(9) NOT NULL
FRNUM CHAR(6) NOT NULL, *should be* FRNUM VarCHAR(9) NOT NULL,
于 2013-02-28T19:00:24.993 に答える