views:

58

answers:

3

I'm storing linked lists of data in records that look like this:

CREATE TABLE IF NOT EXISTS `data_nodes` (
  `record_id` int(11) NOT NULL,
  `prev_node` int(11) NOT NULL,
  `data` varchar(200) NOT NULL,
  PRIMARY KEY  (`record_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

where prev_node is the record_id of the previous item in the list, or 0 if we're at the first item in the list.

A typical list might look something like :

record_id     prev_node     data
---------     ---------     ----
1             0             first item
12            1             second item
27            12            third item

I'm using Ruby's mysql module, and what I'd like to do is: given the record number of the last item in a list, load the entire list in a single query. (e.g. given the record id 27, return a result set that contains "first item", "second item", "third item")

Can this be done?

Thanks.

A: 

It looks like this would require recursion. I don't know if MySQL yet implements recursion in SQL, and if it does, it probably wouldn't be very performant. I'm not sure if storing the data like this is the best solution.

Thom Smith
MySQL doesn't allow recursion calls. Unfortunately.
St.Woland
+1  A: 

It's possible for tree of any fixed height N, but you won't be able to do this operation, if tree height becomes N+1.

In other words, if you know how many levels of parent/child nodes there are, you may build a query as explained here (search for Retrieving a Single Path): http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

You may use nested set model and RoR plugin acts_as_nested_set to get the results you want.

If you need help on the article, let know.

St.Woland
Thanks. In my case, N can be anything, but if I store it in each node, I should be able to load a list in two queries. One to load the last node and get N, and then another dynamically created query to get the rest. I'll give this a try, but will leave the question unanswered for now in the hope of getting a single query solution.
Freeman Ng
Nested Set was my instinctual answer too.
Toby Hede
Sorry, should have specified that I'm going to be seeing almost as many inserts as reads, so I don't think nested sets will be practical, as it looks more suited to rare insertions and frequent reads.
Freeman Ng
A: 

You would need a recursive SQL query, e.g. START WITH ... CONNECT BY in Oracle. Unfortunately, MySQL does not support such a construct in a single query. Stored functions can't do recursion either.

sibidiba