查询具有类似子类的关系的表

时间:2014-07-20 18:38:39

标签: java android sqlite

在我的应用程序的数据库中,目前有3个表:

  • 父表 - (总目标)
  • ChildA
  • ChildB

如果我要用OOP说话,ChildA和ChildB都是"子类"父表格,但它们不相似。

表之间的关系:

  • 父表中的一行有一个整数,用于定义该行是与类型A(ChildA)还是类型B(ChildB)相关。
  • 在ChildA和ChildB中都有对父表(id)中相关行的引用。只有1个与父项相关的父行,也可能有1个与父项相关的子项(一对一的r / s)。
  • 在所有表中没有任何一对具有相同名称的列。

我尝试做的是基本上检索Parent表中的所有行,然后根据每行的type列从ChildA或ChildB中检索其他相关信息。

如果我首先检索所有父行,然后使用循环遍历行并且每行查询n次,这将非常容易,但这可能是非常低效的,我想。

我想知道是否有更好的方法,甚至可能在一个查询中。

我知道我可以使用INNER JOIN或其他内容,但我不确定它是如何在这种情况下工作的,我需要将第二个表与第三个表连接起来(以及列的位置)数量和内容都不同。)

所以问题是,最有效的预处理方法是什么?

编辑:
我看到这个问题被标记为另一个问题的副本,但是,我不问如何设计我的数据库,但是如何查询它。
我使用的是Table-Per-Type设计,并希望从不同类型的所有中获取所有行(目前为2个)。
我想知道如何在我希望从单一类型中获取所有行的情况下这样做,但不是在这种情况下,这就是为什么我要询问是否以及如何使用单个查询(例如,具有类似于JOIN的机制)。我知道我可以通过查询两次来实现它,但我想学习一种更有效的方法。

3 个答案:

答案 0 :(得分:3)

我可以想到两种不同的方法(有它们的优点和缺点:)

1)拥有与子类型一样多的查询并一次检索子类型。在示例中,您将有两个查询:

select * from ChildA where id in (select childId from Parent where childType='A')
select * from ChildB where id in (select childId from Parent where childType='B')

这将以相对合理的性能为您提供应用程序和数据库之间尽可能低的数据传输。您将“浪费”数据库为过滤Parent表所做的努力(数据库必须执行两次)

2)您有一个查询,它将ChildA和ChildB检索为同一结果集的一部分,如下所示:

select ChildA.*, ChildB.* from Parent
    left outer join ChildA on Parent.ChildId=ChildA.id
    left outer join ChildB on Parent.ChildId=ChildB.id

上述查询仅在子项具有唯一ID时有效(即,如果存在ID为5的ChildA,则不存在ID为5的ChildB)。如果不是这种情况,您需要稍微“丑陋”的查询:

select ChildA.*, ChildB.* from Parent, ChildA, ChildB
    where (Parent.ChildType='A' and Parent.ChildId=ChildA.id) or
          (Parent.ChildType='B' and Parent.ChildId=ChildB.id)

这将为您提供一个结果集,其中包含ChildA和ChildB中具有许多NULL值的所有列(对于每个ChildA记录,所有ChildB列都将为NULL)。这样,您只有一个查询(在第一种方法中可能比多个查询执行得更快),但您需要发送更多数据。

答案 1 :(得分:0)

您可以为此创建一个联接:

select * from (a outer join b on a.key = b.fg_key) outer join c on a.key = c.fg_key

我不是100%确定开口支架的位置,但我记得在

之前使用它

但是随着子类型数量的增加,正确维护它会变得越来越复杂,所有列名必须在查询中别名。执行两步加载是最简单的,首先加载类型1的所有项目,然后加载类型2.这将使代码更清晰,更易于维护。

效率方面我不希望这比单个查询慢得多。我建议在第一个版本中使用多个查询变体,并在性能成为问题时进行优化。

答案 2 :(得分:0)

基本上我们应该尝试在我们的程序中处理这种要求 我们不应该试图从数据库中实现。

但是我尝试了下面的查询,其中我们从子表之一输出,而在其他子表中只输出null;



select parent.id, parent.description, (select name from car where id = parent.id) as child1, (select Name from bike where id = parent.id) as child2 from vehicle parent;




希望这会对你有所帮助。