Java / MySQL - 在ResultSet上执行选择

时间:2011-04-15 10:54:39

标签: java mysql resultset subquery

所以我对MySQL进行了大量选择并获得了大量数据 - 这是按索引排序的 例如:

select * from nodes where config_id = 1;  

给出(仅显示相关性)

| definition_id (PK) | position | parent | 
-------------------------------------------
   90                      1         0 << "root"
   08                      2         0
   34                      3         0
   22                      4         0
   17                      1         7  << another defn_id
   38                      2         7
   23                      3         7
   07                      1         90

如果这没有意义,想象一下定义一棵树,其中90,8,34和22是根的孩子 然后,7是90岁的孩子,17,38,23是7岁的孩子(根的孙子)。

为了处理这个,我们找到所有父节点为0的节点,添加它们,然后查看所有这些节点,看看它们是否有任何子节点(通过从父节点抓取它们,或者看不到任何值并对其进行处理作为一片叶子)。如果他们有孩子,请将其添加,然后递归继续,直到构建树为止 这不是最有效的数据存储,但其中一个要求是移动子节点和所有子节点的“单行更改”。我宁愿定义一个字符串0.1.6等,但这就是事情的方式。

所以这在测试中运行得相当好,但是当我们每天需要做100,000次这样的事情时(没有缓存 - 没有任何意义,都有些不同) - 我们需要尽可能少地点击数据库(即一)。你说,简单就是抓住整个过程和过程。但是,它们并非全部有序 - 正如您在上面看到的那样,90低于7.是的,这些例子是纵容的,但它说明了我们需要某种秩序的问题。

基本上,简而言之,问题是,它们是一种在ResultSet上进行子选择的简单(并且最好是便宜)方式 - 即将父== 7的所有结果都抓到另一个ResultSet中并对其进行处理吗?

永恒的爱和欣赏,以换取思想/评论。

4 个答案:

答案 0 :(得分:3)

我不知道在ResultSet上进行子选择的方法。如果你想保留一个查询,你可以在内存中管理它,如下所示:

// class to represent your rows
class Row {
    int definitionId;
    int position;
    int parent;
}

// map of parents to list of their rows
Map<Integer, List<Row>> parentMap = new HashMap<Integer, List<Row>>();

// iterate over all results, build row objects and populate the map
while (rs.next()) {
    Row row = new Row();
    row.definitionId = rs.getInt("definition_id");
    row.position = rs.getInt("position");
    row.parent = rs.getInt("parent");

    // find the list of rows for the parent, create it if it doesn't exist
    List<Row> rows = parentMap.get(row.parent);
    if (rows == null) {
        rows = new ArrayList<Row>();
        parentMap.put(row.parent, rows);
    }

    // add row to the list for its parent
    rows.add(row);
}

// find all rows for parent == 7
for (Row row : parentMap.get(7)) {
    // process row
}

答案 1 :(得分:1)

我们的工作非常相似。我们的优势在于我们正在使用oracle,因此“以...开头连接”语法是一种祝福。但是,我们只使用它加载到内存数据结构中,该结构支持树类型函数,如get_children,get siblings,get parent等。

我更倾向于使用db来加载一些支持这些类型函数的对象。我对java不好,所以我不确定实现,但希望这能让你开始。

答案 2 :(得分:0)

您可以在DBMS级别上执行此操作,例如在MySQL http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/上查看。

WhiteFang34的答案很好,因为mySQL不支持分层查询(你可以在ORACLE中找到它:start ... connect by)。可能将来会实现,但现在我们只能使用变通方法(例如在链接上)。基本思想是在运行DBMS的机器上使用内存,以及由供应商实现递归查询(具有优化,强大的算法,支持等)。

其他解决方法是编写存储过程。

答案 3 :(得分:0)

你可以先做一个临时表选择

http://dev.mysql.com/doc/refman/5.1/en/create-table.html

然后在临时表上进行辅助选择。临时表是“每个连接”,因此这可能适用于您,也可能不适合您。