所以我在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和工作?
用永恒的爱和感激来交换思想/评论。
我不知道在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
}
我们在工作中做的事情非常相似。我们的优势是我们使用的是oracle,所以"从…开始"通过语法连接是一种祝福。但是,我们只使用它来加载到内存中的数据结构中,该数据结构支持树类型函数,如get_children, get sibling, get parent等。
我更倾向于使用db来加载一些支持这些类型函数的对象。我不擅长java,所以我不确定实现,但希望这能让你开始。
你可以在DBMS级别上做,看这里以MySQL为例http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/。
WhiteFang34的回答很好,因为mySQL不支持分层查询(你可以在ORACLE: start ... connect by
中找到它)。可能将来会实现,但现在我们只能使用变通方法(例如链接)。基本思想是在运行DBMS的机器上使用内存,并且在供应商实现递归查询的机器上使用内存(具有优化,强大的算法,支持等)。
您可以在临时表中执行第一次选择
http://dev.mysql.com/doc/refman/5.1/en/create-table.html,然后在临时表上执行二级选择。临时表是"每个连接"的,所以这可能适用于您,也可能不适用。