一个属性引用,两个不同表中的属性

时间:2016-04-08 22:36:54

标签: oracle

我有4张桌子

customer: CustomerID - primary key, name

Magazine: name - primary key, cost, noofissues

Newspaper: name - primary key, cost, noofissues

subscription: custID - references CustomerID of Customer, name, startdate, enddate

在上文中,我可以引用name表格中的subscription引用name引用Magazinename引用Newspaper吗? / p>

我创建了表格CustomerNewspaperMagazine。我只需要创建Subscription

2 个答案:

答案 0 :(得分:1)

如果您询问是否可以在引用subscription表或newspaper表的magazine上创建外键约束,则答案为否,您不能。外键必须只引用一个主键。

由于magazinenewspaper具有相同的属性集,因此简单的选项是将它们合并到一个periodical表中,并附加periodical_type列以指示是否这是杂志还是报纸。然后,您可以创建periodical表的外键。

虽然在这个特定示例中可能没有意义,但您可以在subscription中为magazine_namenewspaper_name添加单独的列,并在这些列上创建单独的外键约束使用check约束确保其中一个值非NULL。如果两个不同的父表具有完全不同的属性,那么这可能是有意义的。

与您的问题无关,但作为一般建议,我不会使用name作为主键。除了相当长,名称往往会随着时间的推移而改变,名称不一定是唯一的。我会为密钥使用不同的属性,可能是从序列生成的合成主键。

答案 1 :(得分:1)

你能做这样的事吗?

CREATE TABLE subscription (
  custID     INT
             CONSTRAINT subscription__custid__fk REFERENCES Customer( CustomerId ),
  name       VARCHAR2(50)
             CONSTRAINT subscription__mag_name__fk REFERENCES Magazine( Name )
             CONSTRAINT subscription__news_name__fk REFERENCES Newspaper( Name ),
  startdate  DATE
             CONSTRAINT subscription__startdate__nn NOT NULL,
  enddate    DATE
);

是的,你可以和同一列上有两个外键指向不同的表,但是如果列中的值是非空的,那么它将在杂志表和两个表中都有一个匹配的名称报纸桌 - 这可能不是你想要的。

你能否拥有一个外键,要求该值可以独占于该表或该表中(但不能同时存在于两个表中)?否。

但是你可以重新考虑你的数据库因此你将报纸和杂志表合并到一个表中(然后你可以轻松地参考);像这样:

CREATE TABLE customer (
  CustomerID INT
             CONSTRAINT customer__CustomerId__pk PRIMARY KEY,
  name       VARCHAR2(50)
             CONSTRAINT customer__name__nn NOT NULL
);

CREATE TABLE Publications (
  id         INT
             CONSTRAINT publications__id__pk PRIMARY KEY,
  name       VARCHAR2(50)
             CONSTRAINT publications__name__nn NOT NULL,
  cost       NUMBER(6,2)
             CONSTRAINT publications__cost__chk CHECK ( cost >= 0 ),
  noofissues INT,
  type       CHAR(1),
             CONSTRAINT publications__type__chk CHECK ( type IN ( 'M', 'N' ) )
);

CREATE TABLE subscription (
  custID     INT
             CONSTRAINT subscription__custid__fk REFERENCES Customer( CustomerId ),
  pubID      INT
             CONSTRAINT subscription__pubid__fk REFERENCES Publications( Id ),
  startdate  DATE
             CONSTRAINT subscription__startdate__nn NOT NULL,
  enddate    DATE
);