Database design - Approach for storing points for users

前端 未结 4 1611
天命终不由人
天命终不由人 2021-01-03 09:40

Just looking for some suggestions on how to approach the database design for this.

On my site a user can get points for performing different activities. Currently th

4条回答
  •  抹茶落季
    2021-01-03 10:17

    Don't store the points at all. Just do queries on this view. That way it will be robust in the face of arbitrary changes.

    create view UserPoints
    as
    select
        created_by_id as user_id,
        'STORE' as action_type,
        store_id as action_id,
        (select points from action_points where action_desc='create store') as points
    from store
    union
    select
        user_id,
        'ANSWER' as action_type,
        question_id as action_id,
        (select points from action_points where action_desc='answer question') as points
    from answer
    union
    select
        referred_by_id as user_id,
        'REFERRAL' as action_type,
        referred_id as action_id,
        (select points from action_points where action_desc='referral') as points
    from referral
    

    Edited to add:

    This follows the normal database design principles. All database normalization can be summed up with this: don't repeat data.

    The inclusion of a points table essentially just repeats information that the rest of the database already contains. Therefore, it should be omitted. This is made clear when considering the lengths to which one must go to maintain the consistency of the data. Without worrying about the points, if a referral is attributed to Alice, but later it is determined that Bob should receive the credit, this will require a change to a single field in a single row of a single table. If a points table is included, then it must also be updated in some way. If points summaries are being stored, then may God have mercy on your database.

    Rather than storing the points, a view or stored procedure may be used instead, and then the points system is adjusted automatically when the data changes.

    I think a view is perferrable to a stored procedure in this case, because there are many ways in which the points data may need to be analyzed, and this provides the most flexibility, and it gives the optimizer the best chance at identifying the optimal path.

    You may select from the view by user_id or by action_type or sum the points column to get totals for a user or for all users. Look at the fun you can have, and it's practically free!

    select
        sum(up.points) as total_points,
        up.user_id,
        u.user_name
    from
        UserPoints up
        join user u on up.user_id = u.user_id
    group by
        user_id,
        user_name
    order by
        total_points desc
    

提交回复
热议问题