如何处理关系数据库中的继承

How to handle inheritance in a relational database

我在理解继承如何与关系数据库一起工作时遇到了一些困难。

假设我有以下 类:

public class Train {
    private int id;
    private String callsign;
    private List<Component> components = new ArrayList<Component>();

    public Train(){}

    public Train(String callsign){
        this.callsign = callsign;
    }
    ... getters & setters ...  
}

public abstract class Component {
    private int id;

    private String callsign;


    private Train train;

    public Component() {
    }

    public Component(String callsign) {
        this.callsign = callsign;
    }

    ... getters & setters ...  

}

public class Wagon extends Component{
    private int numOfSeats;

    public Wagon(String callsign, int numOfSeats) {
        super(callsign);
        this.numOfSeats = numOfSeats;
    }

    public Wagon() {
    }
    ... getters & setters ...  
}

火车由组件(列表)组成,并且有多个子组件类(本例中只有货车)。

为了坚持这一点,我认为 Table Per Type Inheritance 结构是合适的,但这正是我 运行 遇到问题的地方。

我的数据库结构:

CREATE TABLE `Train` (
  `id` int(11) NOT NULL,
  `callsign` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UK_callsign_train` (`callsign`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `Component` (
  `id` int(11) NOT NULL,
  `callsign` varchar(255) NOT NULL,
  `train_FK` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UK_callsign_comp` (`callsign`),
  KEY `FK_comp_train` (`train_FK`),
  CONSTRAINT `FK_comp_train` FOREIGN KEY (`train_FK`) REFERENCES `Train` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `Wagon` (
  `numOfSeats` int(11) NOT NULL,
  `id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  CONSTRAINT `FK_wagon_comp` FOREIGN KEY (`id`) REFERENCES `Component` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

所以现在我想创建一个 DAO 方法,returns 一个包含所有组件的 Train 对象。我可以通过它的 ID 查询火车并使用 train_fk 在组件 table 中查找相应的组件,但这就是问题开始的地方。 Component table 仅包含我需要的部分数据(对于 Wagon obj,其余信息位于 Wagon table 中)。

在这种情况下,很明显我需要查询 Wagon table 以获取其余信息,但如果我有更多类型怎么办。我如何知道要查询什么 table 以及要解析到什么对象?

我知道这在当前结构下是不可能的,但通常如何做到这一点?在关系数据库中处理此类继承的标准解决方案是什么?

提前致谢!

PS:我试图在不使用 JPA、Hibernate 或任何其他框架的情况下执行此操作,只是 JDBC ;)

我建议在组件 table 上添加一列来指示子类型。

然后当您使用组件和所有子类型加入训练时,您可以在 Java 端确定您必须实例化什么类型。

第二个选项可以是 select 中的 case 语句:

select *,
       case 
         when w.id is not null then 'wagon' 
       end as type 
from train t 
  join component c on c.train_FK = t.id
  left outer join Wagon w on w.id = c.id