Java / MySQL - 在结果集上进行选择

发布于 2024-11-01 04:16:11 字数 1200 浏览 5 评论 0原文

因此,我在 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 中并进行处理?

永恒的爱和欣赏来换取想法/评论。

So I've done a massive select on MySQL and got back a lot of data - which is ordered by index.
For example:

select * from nodes where config_id = 1;  

Gives (only relevancies shown)

| 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

If this makes no sense, imagine defining a tree, where 90, 8, 34 and 22 are children of the root.
7 is then a child of 90, and 17, 38, 23 are children of 7 (grandchildren of the root).

In order to process this, we find all the nodes with the parent 0, add them in, then look at all those nodes, see if they have any children (by grabbing their from parent, or seeing no values and treating it as a leaf). If they have children, add them on, and continue recursively until the tree is built.
This isn't the most efficient data store, but one of the requirements is "a single line change" to move a sub-set of nodes and all children. I'd have rather defined a string 0.1.6 etc, but thats the way things are.

So this works fairly well in testing, but when we need to do this 100,000 times a day (without caching - no point, all slightly different) - we need to do this with as few hits to the database as possible (i.e. ONE). Easy, you say, just grab the whole lot and process. But, they're not all order - as you can see above, 90 is below 7. Yes, that examples connived, but it illustrates the problem that we need some sort of order.

Basically, in a nutshell, the question is, is their an easy (and preferably cheap) way of doing a sub-select on the ResultSet - i.e. grab all results where parent == 7 into another ResultSet and work on that?

Eternal love and appreciation in exchange for thoughts/comments.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

剩余の解释 2024-11-08 04:16:11

我不知道如何在 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
}

I'm not aware of a way to do a sub-select on a ResultSet. If you want to keep to one query you could manage it all in memory with something like this:

// 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
}
风渺 2024-11-08 04:16:11

我们在我的工作中做的事情非常相似。我们的优势在于我们使用的是 Oracle,因此“start with...connect by”语法是一件幸事。然而,我们只使用它来加载到内存数据结构中,该结构支持树类型函数,如 get_children、获取兄弟姐妹、获取父母等。

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

We do something very similar at my job. We have the advantage that we are using oracle, so the "start with...connect by" syntax is a blessing. However, we only use that to load into an in memory data structure which supports tree type functions like get_children, get siblings, get parents, etc.

I would look more toward using the db to load some object that supports those types of functions. I'm not good with java so i'm not sure of the implementation, but hopefully this gets you started.

梦亿 2024-11-08 04:16:11

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

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

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

You can do it on DBMS level, look here for example on MySQL http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/.

WhiteFang34's answer is good, because mySQL doesn't support hierarchical queries (you can find it in ORACLE: start ... connect by). May be it will be implemented in future, but now we can use only workarounds (such as on link). Basic idea is to use memory on machine where DBMS runs and where recursive query implemented by vendor (with optimization, strong algorithms, support, etc.).

Additional workaround is writing stored procedure.

拿命拼未来 2024-11-08 04:16:11

您可以对临时表进行第一次选择

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

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

You could do your first select into a temporary table

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

and then do your secondary selects on the temporary table. Temporary tables are "per-connection" so this may or may not work for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文