Sql recursion without recursion

前端 未结 6 1367
故里飘歌
故里飘歌 2020-12-16 23:18

I have four tables

create table entities{
integer id;
string name;
}

create table users{
integer id;//fk to entities
string email;
}

create table groups{
i         


        
6条回答
  •  醉梦人生
    2020-12-16 23:51

    I don't think there is a need for recursion here as the solution posted by barry-brown seems adequate. If you need a group to be able to be a member of a group, then the tree traversal method offered by Dems works well. Inserts, deletes and updates are pretty straightforward with this scheme, and retrieving the entire hierarchy is accomplished with a single select.

    I would suggest including a parent_id field in your group_members table (assuming that is the point at which your recursive relationship occurs). In a navigation editor I've created a nodes table like so:

    tbl_nodes     
    ----------
    node_id   
    parent_id 
    left      
    right
    level
    
    ...
    

    My editor creates hierarchically-related objects from a C# node class

        class node {
          public int NodeID { get; set; } 
          public Node Parent { get; set; }
          public int Left { get; set; }
          public int Right { get; set; }
          public Dictionary Nodes { get; set; } 
          public int Level {
             get { 
                return (Parent!=null) ? Parent.Level+1 : 1;
             }
          }
    }
    

    The Nodes property contains a list of child nodes. When the business layer loads the hierarchy, it rectifies the parent/child relationships. When the nav editor saves, I recursively set the left and right property values, then save to the database. That lets me get the data out in the correct order meaning I can set parent/child references during retrieval instead of having to make a second pass. Also means that anything else that needs to display the hierarchy ( say, a report) can easily get the node list out in the correct order.

    Without a parent_id field, you can retrieve a breadcrumb trail to the current node with

    select n1.* 
    from nodes n1, nodes n2
    where d1.lft <= d2.lft and d1.rgt >= d2.rgt
    and d2.id = @id
    order by lft;
    

    where @id is the id of the node you're interested in.

    Pretty obvious stuff, really, but it applies to items such as nested group membership that might not be obvious, and as others have said eliminates the need to slow recursive SQL.

提交回复
热议问题