Database Design Query Scheme for Unlimited Agents (for reference)

 

The following is a member information table, where WxId is the id of the WeChat official account (because the program I designed is to support multiple WeChat official accounts), UserId is the current member id, and the Pid in the figure below is the member’s last level user id

 

Let's take a look at the data:

According to the figure above, the Pid of the member with userid=1 is 0, indicating that the member is top-level and no one promotes it. The member with userid=2 has a pid of 1, which means that he is promoted by a member with userid of 1. Then look at the member with userid=7, his pid=2, indicating that he is promoted by the member with userid=2. To put it bluntly, the promotion relationship is:

userid(1)->userid(2)->userid(7)

userid(1)->userid(3)

userid(1)->userid(4)

userid(1)->userid(5)

userid(1)->userid(6)

Then we want to query all the first-level promotion members of a member (assuming his id is 1), the corresponding sql is: select * from t_user where Pid=1, there is no problem here, it is not difficult

Then go on, if you want to inquire about his second-level or third-level distribution members, it will be troublesome, and you need to use a sub-loop. The corresponding code is as follows:

public String gets(int pid){

  StringBuffer sb=new StringBuffer(sb);

  ArrayList list=(ArrayList)DaoFactory.getUserDAO().exe("select id,Pid from t_user where Pid="+pid);

  for (Iterator iter = list.iterator(); iter.hasNext(); ) {
        DataField df=(DataField)iter.next();

  sb.append("<li>"+df.getInt("id")+"</li>");

// recursive call

sb.append(gets(df.getInt("id")));

 

  }

}

As seen above, the main solution is to call recursively. Although the function can also be realized, but in the case of a relatively large number, it is easy to cause performance problems (here is only to find members, if the consumption and income statistics of members at each level need to be queried with the consumption table, the performance I don't know when the card will end).

Here comes the important point. Let’s redesign the table. Here we mainly solve it through database design. We know that the database storage quantity is not afraid of too much, so we think, it can be like this. Whenever a user promotes a member, we send a table (Temporarily called the user relationship table) Isn't it enough to write his level relationship. For example, a promotes b, then b promotes c, and c promotes d, so we will write a record to the database to record the three-level relationship above b.

Look at the data in the table

In the figure above, in addition to the original membership table, we have added a new membership relationship table: t_user_relations

As you can see here, the member with ChildId=2 is a first-level distribution user (FxLevel=1) with id 1 (Pid=1)

For the member with ChildId=7, there are two records in the database, one is: he is a first-level distribution user (FxLevel=1) with id 2 (Pid=2), and he is id 1 (Pid=1) Secondary distribution users (FxLevel=2), so it is not difficult to understand that if a member has three levels, there should be three records here. The simple understanding is that when a new user is added, the user information corresponding to all levels above the user is recorded in the user relationship table.

In this way, when we want to query all first-level members of a member, we can use sql:select * from t_user_relations where Pid=1 and FxLevel=1

All secondary members sql:select * from t_user_relations where Pid=1 and FxLevel=2

All third-level members sql:select * from t_user_relations where Pid=1 and FxLevel=3

When we need to count the total consumption of third-level members, it is very convenient to use sql:select sum(t_pay.Money) from t_user_relations,t_pay where t_user_relations.ChildId=t_pay.Userid and t_user_relations.Pid=1 and t_user_relations.FxLevel=3

Similarly, query the consumption of secondary members: select sum(t_pay.Money) from t_user_relations, t_pay where t_user_relations.ChildId=t_pay.Userid and t_user_relations.Pid=1 and t_user_relations.FxLevel=2

How to check the consumption of all sub-members? You can't write three sql, of course not. Isn’t it enough to use the condition FxLevel>0 :)

select sum(t_pay.Money) from t_user_relations,t_pay where t_user_relations.ChildId=t_pay.Userid and t_user_relations.Pid=1 and t_user_relations.FxLevel>0

 

Such a sql is solved. If you use the recursive approach you started with, the speed will be very, very bad as the amount of data grows.

You may also ask a question above, so if you know who a certain member is at the first level and whose second level is it,...? This needs to use the table designed by the first method. As you can see, we still need to use the above table design :)

select Pid from t_user where id=2

if(Pid!=0) indicates that it is not the top level, continue to check. Here you can use recursive query or do three queries (depending on whether the pid is 0, so some may only be one or two queries, up to 3 times), rest assured, this will not affect performance too much, and can be ignored.

Or put the id and pid data in the cache, redis is a good choice. You can try it out.

Finally, look at the effect of even development :)

Guess you like

Origin blog.csdn.net/qq_25062671/article/details/108653033