Лучший способ сохранить историю пользователей - PullRequest
0 голосов
/ 10 августа 2011

Я создаю систему бронирования номеров. Ради этого вопроса у меня есть две таблицы: user и group. Они связаны в Doctrine2 через отношение многие ко многим (поэтому технически у меня есть 3 таблицы).

Каждую неделю каждой группе разрешается бронировать десять часов. Любой, кто является членом группы, может бронировать от имени этой группы. Я хочу иметь возможность вести историю бронирования как пользователей, так и групп. Таким образом, мы можем сказать

"2 weeks ago, the "white lions" booked nine and a half hours, but the week before, they only booked 3", 

и мы также можем сказать

"Dave has made 75% of the bookings for the white lions in the past two weeks"

В идеале я тоже хочу иметь возможность создавать графики с этой историей.

Каков наилучший способ сделать это? Я думал, что для group я бы поместил массив недель, отсортированный по номеру недели ISO и году, в качестве ключей массива, и каждый ключ дал бы значение, сколько часов группы забронировали на этой неделе. То же самое можно сказать и о user. Но при этом создается столбец длинного текста (массив сериализуется) в таблицах user и group, которые будут извлекаться много и в целом использоваться очень мало.

Я использую MySQL.

Что ты думаешь?

РЕДАКТИРОВАТЬ: Я написал агрегатную функцию, и я просто хочу убедиться, что это то, о чем мы говорим:

function getGroupHoursPerWeek( Group $group , $sometime_during_week = null ) {
global $em;
if( !is_null( $sometime_during_week )) {
    $year = date("o", $sometime_during_week );
    $week_number = date("W", $sometime_during_week );
} else {
    $year = date("o");
    $week_number = date("W");
}
$week_start = strtotime( $year . "W" . $week_number );
$one_week_seconds = 3600 * 24 * 7;
$week_end = $week_start + $one_week_seconds;
$total_time = 0;

$query = $em->createQuery("SELECT e.start_time, e.end_time FROM SSMURBS\Entry e 
                            JOIN e.group g 
                            WHERE g.id = {$group->id} 
                            AND e.start_time > $week_start 
                            AND e.end_time < $week_end
                            AND e.status != " . ENTRY_STATUS_REJECTED );
$entry_times = $query->getScalarResult();

foreach( $entry_times as $entry_time ) {
    $total_time += ( $entry_time["end_time"] - $entry_time["start_time"] );
}
return $total_time / 3600;
}

1 Ответ

4 голосов
/ 10 августа 2011

Зачем иметь дело с сериализованным массивом?

Похоже, вам нужно больше сущностей, чем просто пользователей и групп.

Я бы сделал что-то вроде:

  • Пользователи
  • Группы
  • Номера
  • Бронирование

У бронирования будут ассоциации со всеми тремя другими объектами, а также дата, время и продолжительность или что-то еще. Неясно, могут ли ваши пользователи принадлежать к нескольким группам (или менять группы) - если они могут, то для каждого бронирования потребуется набор как пользователя, так и группы. Если нет, вы можете обойтись только с пользователем, так как это скажет вам, какая группа участвует.

Тогда у вас есть все данные, необходимые для создания любых отчетов, которые вы хотите.

...