将外键约束添加到关联实体

时间:2015-03-26 20:26:24

标签: oracle foreign-keys many-to-many constraints composite-key

我有3张桌子:

1)SERVICE_REQUESTS(父母)

CREATE TABLE SERVICE_REQUESTS(
service_id           NUMBER (7)    NOT NULL,
serial_number        NUMBER (10)   NOT NULL,
service_date         DATE          NOT NULL,
service_description  VARCHAR(50)   NOT NULL,
hourly_rate          NUMBER(5,2)   NOT NULL,
customer_id          NUMBER  (5)   NOT NULL,
employee_id          NUMBER  (3)   NOT NULL,

CONSTRAINT service_request_pk PRIMARY KEY(service_id, serial_number));


2)SERVICE_PARTS(解决M:M关系的关联实体)

CREATE TABLE SERVICE_PARTS(
service_id           NUMBER  (7)   NOT NULL,
part_id              NUMBER (10)   NOT NULL,
quantity             NUMBER  (4)   NOT NULL,
unit_cost            NUMBER(7,2)   NOT NULL,

CONSTRAINT service_part_pk PRIMARY KEY(service_id, part_id));


3)PARTS(父母)

CREATE TABLE PARTS(
part_id              NUMBER (10)   NOT NULL,
part_description     VARCHAR(50)   NOT NULL,
cost                  NUMBER(7,2)   NOT NULL,
quantity_on_hand     NUMBER  (5)   NOT NULL,

CONSTRAINT part_pk PRIMARY KEY(part_id));


我使用以下语句从SERVICE_PARTSPARTS创建了一个外键约束:

ALTER TABLE service_parts
  ADD CONSTRAINT service_parts_part_id_fk
    FOREIGN KEY (part_id)
      REFERENCES parts(part_id);

现在我尝试使用以下语句从SERVICE_PARTSSERVICE_REQUESTS创建外键约束:

ALTER TABLE service_parts
  ADD CONSTRAINT service_parts_service_id_fk
    FOREIGN KEY (service_id)
      REFERENCES service_requests(service_id);

但是我收到以下错误:ORA-02270: no matching unique or primary key for this column-list。为什么它允许为part_id而不是service_id添加约束?

我已附上我的ER图表以进行视觉说明: enter image description here

2 个答案:

答案 0 :(得分:1)

如果service_requests表的主键是service_id, serial_number,则您的M:M映射表需要包含主键的两个元素。主键的定义意味着您可以拥有许多具有相同service_id但不同serial_number值的行。如果您的映射表不包含密钥的两个元素,那么您将无法确定service_requests中哪个特定行映射到service_parts中的任何特定行。< / p>

您的映射表定义需要

CREATE TABLE SERVICE_PARTS(
service_id           NUMBER  (7)   NOT NULL,
serial_number        NUMBER (10)   NOT NULL,
part_id              NUMBER (10)   NOT NULL,
quantity             NUMBER  (4)   NOT NULL,
unit_cost            NUMBER(7,2)   NOT NULL,

CONSTRAINT service_part_pk PRIMARY KEY(service_id, serial_number, part_id));

然后是你的外键

ALTER TABLE service_parts
  ADD CONSTRAINT service_parts_service_id_fk
    FOREIGN KEY (service_id, serial_number)
      REFERENCES service_requests(service_id, serial_number);

或者,如果我们认为您的映射表是正确的,这意味着service_idservice_requests的关键,那么service_requests的定义将是

CREATE TABLE SERVICE_REQUESTS(
service_id           NUMBER (7)    NOT NULL,
serial_number        NUMBER (10)   NOT NULL,
service_date         DATE          NOT NULL,
service_description  VARCHAR(50)   NOT NULL,
hourly_rate          NUMBER(5,2)   NOT NULL,
customer_id          NUMBER  (5)   NOT NULL,
employee_id          NUMBER  (3)   NOT NULL,

CONSTRAINT service_request_pk PRIMARY KEY(service_id));

然后您的映射表和外键定义将保持原样。

答案 1 :(得分:0)

SERVICE_REQUESTS中的主键:

CONSTRAINT service_request_pk PRIMARY KEY(service_id, serial_number)

此主键无法保证您的service_id值是唯一的。因此,您无法仅从另一个表中引用此字段,因为无法确定您将引用哪条记录。一个表中的主键和另一个表中的外键必须完全相同。