根据我对您感兴趣的业务上下文的描述的解释,您正在处理超类型1型结构,其中(a)演员,导演和作家是(b)人员,其实体超类型和(c)的实体子类型。所述子类型不是互斥的。
这样,如果您有兴趣建立一个可以准确反映这种情况的关系数据库,并因此希望它能正常运行,那么您对以下几点的澄清对于前面的观点是非常重要的,因为它们在以下方面具有一定的意义。 (1)有关数据库的概念表示和(2)逻辑表示形式:
我将在以下各节中详细介绍所有这些方面以及其他一些关键因素。
商业规则
为了首先定义相应的概念架构(可以用作后续参考,以便您可以对其进行调整以确保它满足确切的信息要求),我制定了一些特别重要的业务规则:
- 一个人可以扮演一到两个或三个(即一对一)的角色2。换句话说,一个人可能是
- 一个人可以通过零或一个UserProfile登录。
- 一个演员提供一,二,或三网址3。
- 一个演员是一个分组种族。
- 一个种族群体零一或一对多的演员。
- 一个作家是基于在一个位置。
- 甲位置是零一个或更多的的基部作家。
信息库IDEF1X图表
然后,我创建了图1所示的IDEF1X 4图,该图将上面的所有公式以及其他相关的规则归为一组:
如图所示,Person超类型(i)有其自己的框,(ii)具有适用于所有子类型的属性或属性,并且(iii)给出了将其与每个子类型的框连接的线。
反过来,每个子类型(a)出现在其自己的专用框中,并且(b)仅保留其适用的属性。父类型PersonId的主键将5迁移到角色名称分别为6 ActorId,DirectorId和WriterId的子类型。
另外,我避免将Person与UserProfile实体类型耦合在一起,这允许将它们的所有上下文含义,关联或关系等分开。PersonId属性已迁移到角色名称为UserId的UserProfile。
您在问题正文中指出
并且所有演员必须为其其他任何在线演员个人资料至少包含一个网址;目前可以包含三个,但是这个数目可能会增加。
…因此,URL本身就是一种实体类型,并且根据此引用直接与Actor子类型相关联。
并且,在注释中,您可以指定
[…]演员将有头像(照片),而作家将没有[…]
…然后,在其他功能中,我将Headshot包含为Actor实体类型的属性。
至于种族 和地点实体类型,它们当然可能需要更复杂的组织(例如,演员可能以不同的比例属于一个,两个或多个不同的种族,作家可能基于需要记录的地方国家/地区,行政区域,县等),但您的业务环境需求似乎已通过此处建模的结构成功满足。
当然,您可以根据需要进行尽可能多的调整。
说明性的SQL-DDL逻辑设计
因此,基于上面显示和描述的IDEF1X图表,我编写了如下所示的逻辑DDL布局(我提供了注释作为注释,解释了我认为对于表,列和约束特别重要的某些特征。声明):
-- You should determine which are the most fitting
-- data types and sizes for all your table columns
-- depending on your business context characteristics.
-- Also, you should make accurate tests to define the
-- most convenient INDEX strategies based on the exact
-- data manipulation tendencies of your business needs.
-- As one would expect, you are free to utilize
-- your preferred (or required) naming conventions.
CREATE TABLE Person ( -- Represents the supertype.
PersonId INT NOT NULL,
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
BirthDate DATE NOT NULL,
GenderCode CHAR(3) NOT NULL,
TwitterProfile CHAR(30) NOT NULL,
PhoneNumber CHAR(30) NOT NULL,
EmailAddress CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Person_PK PRIMARY KEY (PersonId),
CONSTRAINT Person_AK1 UNIQUE ( -- Composite ALTERNATE KEY.
FirstName,
LastName,
GenderCode,
BirthDate
),
CONSTRAINT Person_AK2 UNIQUE (TwitterProfile), -- ALTERNATE KEY.
CONSTRAINT Person_AK3 UNIQUE (EmailAddress) -- ALTERNATE KEY.
);
CREATE TABLE Ethnicity ( -- Its rows will serve a “look-up” purpose.
EthnicityId INT NOT NULL,
Name CHAR(30) NOT NULL,
Description CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Ethnicity_PK PRIMARY KEY (EthnicityId),
CONSTRAINT Ethnicity_AK UNIQUE (Description)
);
CREATE TABLE Actor ( -- Stands for one of the subtypes.
ActorId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Headshot CHAR(30) NOT NULL, -- May, e.g., contain a URL indicating the path where the photo file is actually stored.
EthnicityId INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Actor_PK PRIMARY KEY (ActorId),
CONSTRAINT ActorToPerson_PK FOREIGN KEY (ActorId)
REFERENCES Person (PersonId),
CONSTRAINT ActorToEthnicity_PK FOREIGN KEY (EthnicityId)
REFERENCES Ethnicity (EthnicityId)
);
CREATE TABLE Director ( -- Denotes one of the subtypes
DirectorId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Bio CHAR(120) NOT NULL,
Etcetera CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Director_PK PRIMARY KEY (DirectorId),
CONSTRAINT DirectorToPerson_PK FOREIGN KEY (DirectorId)
REFERENCES Person (PersonId)
);
CREATE TABLE Country (
CountryCode CHAR(2) NOT NULL,
Name CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Country_PK PRIMARY KEY (CountryCode),
CONSTRAINT Country_AK UNIQUE (Name)
);
CREATE TABLE Location ( -- Its rows will serve a “look-up” purpose.
CountryCode CHAR(2) NOT NULL,
LocationCode CHAR(3) NOT NULL,
Name CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Location_PK PRIMARY KEY (CountryCode, LocationCode),
CONSTRAINT Location_AK UNIQUE (CountryCode, Name)
);
CREATE TABLE Writer ( -- Represents one of the subtypes.
WriterId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
CountryCode CHAR(2) NOT NULL,
LocationCode CHAR(3) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Writer_PK PRIMARY KEY (WriterId),
CONSTRAINT WriterToPerson_PK FOREIGN KEY (WriterId)
REFERENCES Person (PersonId),
CONSTRAINT WriterToLocation_PK FOREIGN KEY (CountryCode, LocationCode)
REFERENCES Location (CountryCode, LocationCode)
);
CREATE TABLE UserProfile (
UserId INT NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
UserName CHAR(30) NOT NULL,
Etcetera CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT UserProfile_PK PRIMARY KEY (UserId),
CONSTRAINT UserProfile_AK UNIQUE (UserName), -- ALTERNATE KEY.
CONSTRAINT UserProfileToPerson_PK FOREIGN KEY (UserId)
REFERENCES Person (PersonId)
);
CREATE TABLE URL (
ActorId INT NOT NULL,
Address CHAR(90) NOT NULL,
Etcetera CHAR(30) NOT NULL,
AddedDateTime DATETIME NOT NULL,
--
CONSTRAINT URL_PK PRIMARY KEY (ActorId, Address), -- Composite PRIMARY KEY.
CONSTRAINT URLtoActor_FK FOREIGN KEY (ActorId)
REFERENCES Actor (ActorId)
);
因此,(1)逻辑布局的每一个奇异方面所携带来自一个非常精确的含义(2)感兴趣的商业环境的奇异特性7与精神-in协议关系框架由埃德加·弗兰克·科德博士 - ,因为:
具有这样的布局绝对是有利的,因为您可以派生新表(例如,借助JOIN子句从多个表中收集列的SELECT操作),这些表也具有非常精确的含义(请参见本节)。标题为“视图”)。
值得一提的是,通过这种配置,(i)表示子类型实例的行由(ii)相同的PRIMARY KEY值标识,该值区分表示互补超型出现的行。因此,有更多的机会注意到
- (a)在(b)代表亚型的表上附加一个额外的列来保存系统生成的和系统分配的替代项8(c)完全多余。
通过这种逻辑设计,如果在业务上下文中将新的子类型定义为相关的,则必须声明一个新的基表,但是当其他类型的实体类型被认为具有重要意义时,也会发生这种情况,因此,其实很普通。
观看次数
为了“获取”例如与Actor,Director或Writer对应的所有信息,您可以声明一些视图(即派生表或可表达表),以便您可以直接从一个资源中进行选择,而不必编写每次都涉及JOIN;例如,使用下面声明的VIEW,您可以获得“完整”的Actor信息:
--
CREATE VIEW FullActor AS
SELECT P.FirstName,
P.Lastname,
P.BirthDate,
P.GenderCode,
P.TwitterProfile,
P.PhoneNumber,
P.EmailAddress,
A.Headshot,
E.Name AS Ethnicity
FROM Person P
JOIN Actor A
ON A.ActorId = P.PersonId
JOIN Ethnicity E
ON E.EthnicityId = A.EthnicityId;
--
当然,您可以采用类似的方法来检索“完整”的Director和Writer信息:
--
CREATE VIEW FullDirector AS
SELECT P.FirstName,
P.Lastname,
P.BirthDate,
P.GenderCode,
P.TwitterProfile,
P.PhoneNumber,
P.EmailAddress,
D.Bio,
D.Etcetera
FROM Person P
JOIN Director D
ON D.DirectorId = P.PersonId;
--
CREATE VIEW FullWriter AS
SELECT P.FirstName,
P.Lastname,
P.BirthDate,
P.GenderCode,
P.TwitterProfile,
P.PhoneNumber,
P.EmailAddress,
L.Name AS Location,
C.Name AS Country
FROM Person P
JOIN Writer W
ON W.WriterId = P.PersonId
JOIN Country C
ON C.CountryCode = W.CountryCode
JOIN Location L
ON L.LocationCode = W.LocationCode;
--
我已经发布了在MySQL 5.6上运行的此SQL Fiddle中讨论的所有DDL语句和DML视图,以便您可以“实际”查看和测试它们。
尾注
1在某些概念建模技术中,超类型-子类型关联称为超类-子类关系。
2尽管您提到事实上一个人可能会执行更多的角色,但是您所揭示的三个角色足以讨论暴露了几个重要影响的场景。
3但是,正如您指出的那样,将来Actor最终可能会提供一对多URL。
4 信息建模的集成定义(IDEF1X)是一种高度推荐的建模技术,由美国国家标准技术研究院(NIST)于1993年12月建立为标准。它基于(a)数据关系模型的唯一发起人,即EF Codd博士创作的早期理论著作;(b)由陈PP博士提出的关于实体关系的观点;以及(c)Robert G. Brown创建的逻辑数据库设计技术。
5 IDEF1X标准将密钥迁移定义为“将父代或通用[即,超类型]实体的主键放在其子代或类别实体[即,子类型]中作为外键的建模过程”。
6在IDEF1X中,角色名称是分配给FK属性的独特标签,目的是表达角色名称在其各自实体类型范围内的含义。
7当然,对于假设的概念属性(和逻辑列),Director.Etcetera和UserProfile.Etcetera只是占位符,我只是用来展示添加适用于相应概念实体类型的更多属性(和列)的可能性(和逻辑表)。
8例如,将具有AUTO_INCREMENT属性的附加列附加到在MySQL上“运行”的数据库表中。