I've got a table named stats

player_id team_id match_date  goal assist`

        1       8  2010-01-01    1      1

        1       8  2010-01-01    2

        1       9  2010-01-01          5


I must know whenever a player achieve a milestone (eg 100 goals, 100 assists, 500 goals...)
I must know also whenever a team achieve a milestone.
I wish to know which player or team achieve 100 goals first, second, third...

I figured to make use of triggers with tables to amass the totals.
Table player_accumulator (and team_accumulator) table could be

player_id total_goals total_assists

        1           3             6

team_id   total_goals total_assists

      8             3             1

      9                          5

Every time a row is placed in stats table, a trigger will place/update player_accumulator and team_accumulator tables.
This trigger may also verify if player or team has arrived at a milestone in milestone table that contains amounts






A table player_milestone would consists of milestone arrived at by player:

player_id  stat    milestone          date

        1  goal          100    2013-04-02

        1  assist        100    2012-11-19

There's an easy method to implements a "milestone" ?
There's an simplest way without triggers ?

I am using PostgreSQL

I'd just count all goals and assists of the player which scores, and team, which scores.

Such as this on client side (in pseudocode):

function insert_stat(player_id, team_id, match_date, goals, assists)
  if (goals>0) {
    player_goals_before = query('select count(goal) from stats where player_id=?',player_id);
    team_goals_before = query('select count(goal) from stats where team_id=?',team_id);
  if (assists>0) {
    player_assists_before = query('select count(assist) from stats where player_id=?',player_id);
    team_assists_before = query('select count(assist) from stats where team_id=?',team_id);
  query("insert into stats (player_id, team_id, match_date, goal, assist)\n"
    +"values (?, ?, ?, ?, ?)", player_id, team_id, match_date, goal, assist);

  if (goals>0) {
    if ( has_milestone(player_goals_before+goals) and !has_milestone(player_goals_before) ) {
      alert("player " + player_id + " reached milestone!")
    if ( has_milestone(team_goals_before+goals) and !has_milestone(team_goals_before) ) {
      alert("team " + team_id + " reached milestone!")
  // etc

Don't maintain milestone table, because this helps make the database denormalized. I believe this can be a premature optimisation. Only if the above mentioned is actually not quick enough (for instance when stats may have a lot more than couple of 1000's of rows per player_id or team_id) you'll be able to think about maintaining milestone table.