子类型/子类实体的继承参数

时间:2016-10-01 03:15:30

标签: sql ms-access inheritance database-design

这是一个复杂的问题,我希望得到一个简单的答案。

桥接实体是否可以从其父类实体继承了PK / FK属性的子类型实体继承PK? Conference EDRD Example我已经制作了一个场景来证明我的意思。

因此,在此示例中,有一个父实体可以捕获有关会议的信息。 CONFERENCE有两种可能的子类型:INDIVIDUAL和BUSINESS,它们有自己的“特殊”属性,并且没有显示为不必要。

有两个桥接实体,用于捕获参加会议的个人或企业的详细信息。您将看到标记为“A”的桥接实体具有直接连接到CONFERENCE实体的桥接实体。我的理解是CONFERENCE_BUSINESS中的PK / FK属性 ConferenceNumber 是可以接受的。

我不确定,并希望其他人知道答案,是标签“B”下面的桥接实体是否可以从子类型实体INDIVIDUAL继承PK / FK属性 ConferenceNumber ,还是应该与CONFERENCE有直接关系,比如标有“A”的桥接实体?

更好的例子是当您将书籍和电影作为子类型并且希望捕获有关作者和演员的详细信息时。由于可能有多个作者为一本书或书籍和多个演员的电影或几部电影,我想使用子类型鉴别器捕获这种数据。我想知道是否有人知道(并且可以引用合法来源来表明)样本Book and Movie Rental ERD中的桥接实体:DVD_ACTOR和BOOK_AUTHOR是否可以从我创建的子类型继承PK / FK?

Book and Movie rental ERD example

干杯。

1 个答案:

答案 0 :(得分:0)

我取得了很大成功的一种方法是:

  • 使用( type_name, identifier )
  • 的复合键
  • 在整个数据模型中使用此复合键
  • 通过在type_name属性
  • 上设置约束来约束子类型表中的子类型

在现实生活中,公司和个人被称为legal persons,这是该模型的便捷超级类型。然而,公司很可能对一个人具有不同的标识符(例如,公司注册到不同的官僚机构,而不是负责向个人发布社会安全号码的人),因此我们需要使用人工标识符。然后我们可以将真实生活标识符推送到子类型表。

需要考虑的问题但超出了本答案的范围:

  • 某些键仅为外键定义
  • 所有表都有多个密钥:哪个(如果有)应该提升为主键? (提示:它可能只是为了外键的目的而定义的键!)
  • 定义复合键时必须说明列名称的顺序:此顺序是否重要?

以下SQL DDL需要ANSI-92查询模式,但可以使用Access GUI工具重新创建。请注意,我使用LocationCountryCode作为所有类型会议共有的属性,而SloganOrganizerPaysExpenses分别针对公司和个别子类型:

CREATE TABLE LegalPersons
( PersonNumber INT NOT NULL UNIQUE,
  PersonType CHAR(10) NOT NULL,
     CHECK ( PersonType IN ( 'Individual', 'Company' ) ),
  UNIQUE ( PersonType, PersonNumber ) );


CREATE TABLE Individuals
( PersonNumber INT NOT NULL UNIQUE,
  PersonType CHAR(10) NOT NULL, 
     CHECK ( PersonType = 'Individual' ),
  UNIQUE ( PersonType, PersonNumber ),
  FOREIGN KEY ( PersonType, PersonNumber )
     REFERENCES LegalPersons ( PersonType, PersonNumber ),
  LastName VARCHAR( 35 ) NOT NULL,
  FirstName VARCHAR( 35 ) NOT NULL );


CREATE TABLE Companies
( PersonNumber INT NOT NULL UNIQUE,
  PersonType CHAR( 10 ) NOT NULL, 
     CHECK ( PersonType = 'Company' ),
  UNIQUE ( PersonType, PersonNumber ),
  FOREIGN KEY ( PersonType, PersonNumber )
     REFERENCES LegalPersons ( PersonType, PersonNumber ),
  CompanyRegisteredNumber CHAR( 8 ) NOT NULL UNIQUE );


CREATE TABLE Conferences
( ConferenceNumber CHAR( 10 ) NOT NULL UNIQUE,
  PersonNumber INT NOT NULL,
  PersonType CHAR(10) NOT NULL,
  FOREIGN KEY ( PersonType, PersonNumber )
     REFERENCES LegalPersons ( PersonType, PersonNumber ), 
  UNIQUE ( PersonType, ConferenceNumber ),
  LocationCountryCode CHAR( 3 ) NOT NULL );


CREATE TABLE BusinessConferences
( ConferenceNumber CHAR( 10 ) NOT NULL UNIQUE,
  PersonType CHAR( 10 ) NOT NULL,
     CHECK ( PersonType = 'Company' ),
  FOREIGN KEY ( PersonType, ConferenceNumber )
     REFERENCES Conferences  ( PersonType, ConferenceNumber ),
  Slogan VARCHAR( 100 ) NOT NULL );


CREATE TABLE IndividualConferences
( ConferenceNumber CHAR( 10 ) NOT NULL UNIQUE,
  PersonType CHAR( 10 ) NOT NULL,
     CHECK ( PersonType = 'Individual' ),
  FOREIGN KEY ( PersonType, ConferenceNumber )
     REFERENCES Conferences  ( PersonType, ConferenceNumber ),
  OrganizerPaysExpenses CHAR( 1 ) DEFAULT 'Y' NOT NULL,
     CHECK ( OrganizerPaysExpenses IN ( 'Y', 'N' ) ) );