我的 table A 是否应该有来自 table B 主键和 via verse 的外键?

Should my table A have a Foreign Key from table B Primary Key and via verse?

我想知道我的以下代码,它是否能够工作,因为我的飞机主键是 Serial_No 并且外键取自我的预定 table,Scheduled_No.通过 Scheduled 的 PRIMARY KEY 将是 Scheduled_No 并且 FOREIGN KEY 取自我的飞机 table、Serial_No.

我尝试为我的 Scheduled table 插入值,但它给出了一个错误,无法从我的 Serial_No.

的父键中获取数据

我应该在预定 table 中删除 Serial_No 作为我的 FOREIGN KEY 还是有任何其他方法可以做到这一点?

/* CREATE TABLE FOR AIRPLANE */

CREATE TABLE AIRPLANE (
    Serial_No Varchar2(10) NOT NULL,
    Scheduled_No Varchar2(10) NOT NULL,
    Flight_No Varchar2(6) NOT NULL,
    Model_No Number(3) NOT NULL,
    Capacity Number(3) NOT NULL,
    Maintenance_Date DATE NULL,
    PRIMARY KEY (Serial_No)
    );



 /* CREATE TABLE FOR SCHEDULED */
 
 CREATE TABLE SCHEDULED (
    Scheduled_No Varchar2(10) NOT NULL,
    Serial_No Varchar2(10) NOT NULL,
    Route_No Varchar2(10) NOT NULL,
    Job_No Varchar2(10) NOT NULL,
    Flight_Fly_On DATE NOT NULL,
    PRIMARY KEY (Scheduled_No),
    FOREIGN KEY (Serial_No) REFERENCES AIRPLANE (Serial_No)
    );

/* ADDING FK FOR Scheduled_No FROM SCHEDULED */

ALTER TABLE AIRPLANE 
ADD FOREIGN KEY (Scheduled_No) REFERENCES SCHEDULED (Scheduled_No);

你可以的;修改外键约束(在 airplane 上),使其 可延迟 (即检查提交时是否一切正常,而不是插入)。

像这样:

SQL> CREATE TABLE AIRPLANE
  2  (
  3     Serial_No          VARCHAR2 (10) NOT NULL,
  4     Scheduled_No       VARCHAR2 (10) NOT NULL,
  5     Flight_No          VARCHAR2 (6) NOT NULL,
  6     Model_No           NUMBER (3) NOT NULL,
  7     Capacity           NUMBER (3) NOT NULL,
  8     Maintenance_Date   DATE NULL,
  9     PRIMARY KEY (Serial_No)
 10  );

Table created.

SQL> CREATE TABLE SCHEDULED
  2  (
  3     Scheduled_No    VARCHAR2 (10) NOT NULL,
  4     Serial_No       VARCHAR2 (10) NOT NULL,
  5     Route_No        VARCHAR2 (10) NOT NULL,
  6     Job_No          VARCHAR2 (10) NOT NULL,
  7     Flight_Fly_On   DATE NOT NULL,
  8     PRIMARY KEY (Scheduled_No),
  9     FOREIGN KEY (Serial_No) REFERENCES AIRPLANE (Serial_No)
 10  );

Table created.

注意这条命令:

SQL> ALTER TABLE AIRPLANE
  2     ADD CONSTRAINT fk_air_sch FOREIGN KEY (Scheduled_No)
  3            REFERENCES SCHEDULED (Scheduled_No)
  4            INITIALLY DEFERRED DEFERRABLE;

Table altered.

测试:insert into airplane现在有效,尽管其父scheduled_no行/值尚不存在:

SQL> INSERT INTO airplane (serial_no,
  2                        scheduled_no,
  3                        flight_no,
  4                        model_no,
  5                        capacity,
  6                        maintenance_date)
  7       VALUES ('1',
  8               '100',
  9               'abc',
 10               5,
 11               100,
 12               SYSDATE);

1 row created.

scheduled table 中插入一行。外键必须匹配。

SQL> INSERT INTO scheduled (scheduled_no,
  2                         serial_no,
  3                         route_no,
  4                         job_no,
  5                         flight_fly_on)
  6       VALUES ('100',
  7               '1',
  8               'xyz',
  9               'job',
 10               SYSDATE);

1 row created.

同样成功;现在,提交:

SQL> COMMIT;

Commit complete.

SQL>

您有循环引用。


你应该弄清楚你的 table 指的是什么:

  • AIRPLANE表示具有容量、唯一标识符(即尾部数字)并且是特定品牌和型号的物理对象。
  • 一个SCHEDULE表示物理对象在某个时间点做了什么。 IE。在特定日期,它将飞行特定航线。

在这种情况下,AIRPLANE 有一个 Scheduled_No 是没有意义的,因为可以有多个时间点,而且飞机在不同时间可以有不同的时间表,所以你希望每架飞机与其时刻表之间存在 one-to-many 关系。

AIRPLANE table 中不应有 Scheduled_No 列,并且由于不应有列,因此不应有外键约束。您只希望 Serial_No 的约束朝另一个方向返回。删除该列和相应的约束将解决您的循环引用约束问题。

/* CREATE TABLE FOR AIRPLANE */
CREATE TABLE AIRPLANE (
    Serial_No        Varchar2(10) NOT NULL,
    Flight_No        Varchar2(6) NOT NULL,
    Model_No         Number(3) NOT NULL,
    Capacity         Number(3) NOT NULL,
    Maintenance_Date DATE NULL,
    PRIMARY KEY (Serial_No)
);

/* CREATE TABLE FOR SCHEDULED */
 
CREATE TABLE SCHEDULED (
    Scheduled_No  Varchar2(10) NOT NULL,
    Serial_No     Varchar2(10) NOT NULL,
    Route_No      Varchar2(10) NOT NULL,
    Job_No        Varchar2(10) NOT NULL,
    Flight_Fly_On DATE NOT NULL,
    PRIMARY KEY (Scheduled_No),
    FOREIGN KEY (Serial_No) REFERENCES AIRPLANE (Serial_No)
);