比如说,一辆桌车与表electric_car,gas_car和hybrid_car有一对一的关系.如果汽车是电动汽车,它就不能再出现在gas_car或者hybrid_car等中.
这种设计有什么问题吗?在路上可能会出现一些问题?
解决方法
不同类型的汽车是在数据建模中反复出现的一般问题的实例.它在ER建模中称为“泛化/专业化”,在对象建模中称为“超类/子类”.
对象建模器使用对象模型中内置的继承功能来非常轻松地解决问题.子类只是扩展了超类.
关系建模者面临一个问题.如何设计表格以模仿从继承中获得的好处?
最简单的技术称为single table inheritance.有关所有类型汽车的数据被分组为一个单独的汽车表.有一个列car_type,它将所有单一类型的汽车组合在一起.没有汽车可以属于多种类型.如果一列与电动汽车无关,那么它将在与电动汽车相关的行中留下NULL.
这种简单的解决方案适用于较小和较简单的情况.存在大量的NULL会给存储开销增加一点点,并且会有一点点来检索开销.如果在可空列上进行布尔测试,开发人员可能必须学习SQL three-valued logic.起初这可能令人困惑,但人们已经习惯了.
还有另一种技术,称为类表继承.在这个设计中,除了组合的桌子,汽车之外,还有用于gas_car,electric_car和hybrid_car的单独表格.当您需要有关特定类型汽车的所有数据时,您可以使用适当的专用表加入汽车表.此设计中的NULL更少,但您可以进行更多连接.这种技术在更大和更复杂的情况下效果更好.
第三种技术称为共享主键.此技术通常与class table inheritance一起使用.子类的专用表具有作为其主键的car表中相应条目的主键的副本.可以将此id列声明为主键和外键.
这需要在添加新车时进行一些额外的编程,但它使连接变得简单,容易和快速.
超类和子类一直在现实世界中发生.别害怕.但要测试您的初始设计的性能.如果您的第一次尝试简单而有效,您将能够进行调整以加快速度.