Как быстро выбрать данные из Oracle - PullRequest
1 голос
/ 27 июля 2010

у меня есть следующая таблица Oracle:

GAMES    
    id_game int
    id_user int
    dt_game DATE

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

На самом деле я выбираю количество игр, сыгранных сегодня, таким образом:

select count(1) as num from GAMES 
where id_user=ID_USER and
to_char(dt_game,'DD/MM/YYYY')=to_char(sysdate,'DD/MM/YYYY')

Мне это не очень нравится: есть ли лучший способ сделать это?

Заранее спасибо с.

Ответы [ 4 ]

6 голосов
/ 27 июля 2010

Преобразования даты немного бессмысленны и не позволяют использовать какой-либо индекс в этом столбце; Вы можете упростить этот бит с помощью dt_game > trunc(sysdate).

4 голосов
/ 27 июля 2010

Существует проблема (связанная с параллелизмом) с проверкой таблицы и подсчетом строк перед вставкой новой строки.

Допустим, пользователь в данный момент сыграл в 9 игр, и вы хотите ограничить количество строк до10 ..

если вы откроете две разные сессии, то обе они увидят текущее незафиксированное значение 9 игр и, следовательно, обе игры будут разрешены. К моменту завершения транзакции пользователь получитсыграл 11 игр ... что противоречит правилу, которое вы пытаетесь применить.

2 голосов
/ 28 июля 2010

Вы можете использовать уникальное ограничение, чтобы гарантировать, что фиксированное максимальное количество записей может быть вставлено для определенного дня. Например, если N = 5:

CREATE TABLE GAMES (
  id_game         NUMBER NOT NULL,
  id_user         NUMBER NOT NULL,
  dt_game         DATE   NOT NULL,
  user_game_count NUMBER NOT NULL,
  CONSTRAINT max_games_per_day
  CHECK (user_game_count BETWEEN 1 AND 5),
  CONSTRAINT dt_game_notime
  CHECK (dt_game = TRUNC(dt_game)),
  CONSTRAINT games_unique
  UNIQUE (id_user, dt_game, user_game_count),
);

Ограничение max_games_per_day означает, что оно может принимать только одно из 5 различных значений. Ограничение dt_game_notime означает, что мы не будем получать различные значения времени. Наконец, уникальное ограничение гарантирует, что для любой конкретной даты и пользователя они могут вставить только до 5 строк.

1 голос
/ 27 июля 2010

В Oracle вы можете создать индекс на основе функции для id_user, to_char (dt_game, 'DD / MM / YYYY') для повышения производительности поиска.

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