在关系数据库中表达 is-a 关系
我想知道是否有一种干净的方法来表示 is-a 关系,如本示例所示:
该数据库存储三种类型节目的录制时间:电影、游戏节目、戏剧。 从面向对象的意义上来说,它们中的每一个都是一个程序。 每个子类都有不同的属性。 以下是表格(fk 前缀表示外键):
电影
编号
姓名
fkDirector
gameShow
编号
姓名
fkHost
fkContestant
戏剧
编号
name
在 OO 术语中,记录表在某种意义上看起来像这样:
记录
编号
fk程序
开始时间
endTime
我能想到的在不违反正常形式的情况下执行此操作的唯一方法是拥有三个记录表,即 recordMovie、recordGameShow 和 recordDrama嗯>。
有没有一种方法可以将这些表合并为一个而不违反数据库规范化的原则?
以下是一些非工作示例来说明这个想法:
程序
编号
fk电影
fkGameShow
fkDrama
该表违反了第一范式,因为它将包含空值。 对于每一行,只有 3 个条目之一为非空。
程序
编号
fkSpecific ← fkMovie 或 fkGameShow 或 fkDrama
fkType ← 将指示要查看哪个表
这里我将无法强制执行引用完整性,因为 fkSpecific 可能指向三个表之一。
我只是想节省这里放置 3 张桌子而不是一张桌子的开销。 也许这根本不适用于 RDB。
I was wondering if there is a clean way to represent an is-a relationship as illustrated by this example:
This DB stores recording times for three types of programs: movies, game shows, drama. In an object oriented sense each of these is-a program. Each of these subclasses have different properties. Here are the tables (fk prefix indicates a foreign key):
movie
id
name
fkDirector
gameShow
id
name
fkHost
fkContestant
drama
id
name
In OO terms the record table would in sense look like this:
record
id
fkProgram
startTime
endTime
The only way I can think of doing this without violating the normal forms is to have three record tables namely recordMovie, recordGameShow, and recordDrama.
Is there a way to consolidate these tables into one without violating the principles of database normalization?
Here are some non-working examples to illustrate the idea:
program
id
fkMovie
fkGameShow
fkDrama
This table violates the first normal form because it will contain nulls. For each row only one of the 3 entries will be non null.
program
id
fkSpecific ← fkMovie OR fkGameShow OR fkDrama
fkType ← would indicate what table to look into
Here I will not be able to enforce referential integrity because the fkSpecific could potentially point to one of three tables.
I'm just trying to save the overhead of having 3 tables here instead of one. Maybe this simply isn't applicable to an RDB.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
为什么要将所有数据存储在一个表中? 它们显然是不同的实体。 您对主 Record 表的想法,以及辅助 recordMovie、recordGameShow 和 RecordDrama。
要强制辅助表和主表之间的“is-a”关系,您需要将 Record.id 声明为所有这些表中的外键,并为其添加约束以确保其唯一 - 这强制了一对一的关系,它将把这些表转换为主表的扩展。
您还需要在主记录表中添加一个新字段来指示它是什么类型的记录(电影、游戏节目、戏剧,还是其他内容?)。 这可以是对另一个表(RecordTypes?)的外键引用,也可以是字符串(在它可以接受的值上定义了约束)。
Why do you want to store all the data on a single table? They are clearly different entities. Your idea of a main Record table, with auxiliary recordMovie, recordGameShow, and RecordDrama.
To enforce the "is-a" relationship between the auxiliary tables and the main one, you need to do declare Record.id to be a foreign key in all these tables, and also add a constraint to it so it's unique - this enforces a one-to-one relationship which would convert these tables in extensions of the main one.
You'd also need to add a new field in the main Record table to indicate what kind of record it is (movie, game show, drama, something else?). This could be either a foreign key reference to yet another table (RecordTypes?) or a string (with a constraint defined over the values it can accept).
在谷歌上搜索“泛化专业化关系建模”。
“gen-spec”模型遵循与“is-a”关系相同的模式。
例如,汽车是一种专用车辆。 卡车是一种不同类型的专用车辆。 摩托车是第三类专用车辆。
你应该找到很多文章。
有趣的是,如果您只是在 google 上搜索“gen-spec”,最上面的链接之一就是 Smalltalk 中 gen-spec 建模的描述。
Do a google search on "generalization specialization relational modeling".
The "gen-spec" model follows the same pattern as the "is-a" relationship.
For example, a car is a specialized vehicle. A truck is a different kind of specialized vehicle. A motorcycle is a third kind of specialized vehicle.
You should find plenty of articles.
Interestingly, if you just do a google search on "gen-spec" one of the top links is to a description of gen-spec modeling in Smalltalk.
这些都是关于该主题的好文章:
http://www.ibm.com/developerworks/library/ws -映射到rdb/
http://www.agiledata.org/essays/mappingObjects.html
这就是我的最终会做的。 我的程序表将是:
程序
id
,然后我将 fkProgram 添加到每个子类(戏剧、游戏节目和电影)。 这样,程序表将成为子类之间的中间表。 我可以使用程序表的外键来引用任何子类的实例。 这将允许我拥有一个记录表并且不违反任何正常形式。
电影
编号
fk程序
姓名
fkDirector
记录
编号
fk程序
开始时间
结束时间
These are both good articles on the subject:
http://www.ibm.com/developerworks/library/ws-mapping-to-rdb/
http://www.agiledata.org/essays/mappingObjects.html
This what I will end up doing. My program table will simply be:
program
id
and then I will add fkProgram to each of the subclasses (drama, gameshow, and movie). This way the Program table will be an intermediate table between the subclasses. I can use a foreign key to the Program table to refer to an instance any of the sub-classes. This will allow me to have a single Record table and not violate any normal forms.
movie
id
fkProgram
name
fkDirector
record
id
fkProgram
startTime
endTime
我的第一个想法也是使用一个节目表来播放电影、节目和电视。 戏剧的。 然后添加一个 ProgramType 表并使用外键,就像父帖子一样。
可以添加其他列,例如 fkDirector、fkMovie。 然后添加一个约束,当ProgramType是电影时,fkDirector不能为空,或者当它是节目时,fkHost不能为空。
这样可以轻松查找开始日期和结束日期之间记录的所有电影/节目/...。 还要确保所有数据均已填写且参考文献均正确。
有人有更好的主意吗?
My first idea was also to use one Program table for movies, shows & drama's. Then add a ProgramType table and use a foreign key to it just like the parent post.
Other columns can be added such as fkDirector, fkMovie. Then add a constraint that when the ProgramType is a movie, fkDirector can not be null or when it's a show, fkHost can not be null.
This allows for easy lookup of all movies/shows/... recorded between start and enddate. Also makes sure all the data is filled in and the references are correct.
Anyone has a better idea?
这是许多人之前面临的一个非常标准的问题,并且您可能考虑的所有方法可能都已在某一时刻完成。
简单的 Google 搜索 对每种方法的优缺点进行了一些很好的解释。
This is a pretty standard problem faced by many people before, and all of the approaches you may consider have probably been done at one point.
A simple Google search comes up with some pretty good explanations of the pros and cons of each.
是的,那应该是一张表格,就像
程序类型的参考表一样,如果有的话
与该类型相关的其他数据位:
像这样。
Yes, that should be one table like
with a reference table for the type of program if there are
other bits of data associated with the type:
Like that.