2012-03-15 2 views
0

У меня есть база данных, используемая для кэширования сущностей. Таблицы выглядят так:Оператор SQL/HQL DELETE для кеша LRU?

| Persons    | Addresses 
-----------------  -------------- 
PK| id   <--| PK| id 
    | last_accessed |--- FK| persons_id 
    | [some]     | [more] 
    | [other]    | [address] 
    | [data]     | [stuff] 

Таким образом, у человека есть ноль или более адресов. Доступ к этим таблицам осуществляется приложением Java с использованием Hibernate, а также непосредственно из одного приложения с использованием SQL поверх JDBC.

Теперь мне нужно обрезать размер стола Persons до фиксированного значения - скажем, 50 000 записей. Мне нужно удалить самые старые записи (на основе last_accessed).

есть запрос ANSI-SQL или HQL, который может сделать это легко? Чистое решение ANSI-SQL было бы идеальным, поскольку:

  • Мы стараемся оставаться агностиком базы данных;
  • мы хотим, чтобы избежать необходимости загружать объекты в памяти приложения, чтобы получить Hibernate каскадное удаление работать ...

ответ

1

Это чистый ANSI SQL:

DELETE FROM addresses 
WHERE persons_id IN ( 
    SELECT id 
    FROM ( 
     SELECT id, 
      row_number() over (order by last_accessed desc) as rn 
     FROM persons 
    ) t 
    WHERE rn <= 50000 
); 

DELETE FROM persons 
WHERE id IN ( 
    SELECT id 
    FROM ( 
     SELECT id, 
      row_number() over (order by last_accessed desc) as rn 
     FROM persons 
    ) t 
    WHERE rn <= 50000 
); 

Другой альтернативой было бы определить FK с «ON DELETE CASCADE», а затем просто удалите строки из таблицы persons. Это избавит вас от лишнего SQL для удаления адресов в первую очередь.

+0

aha! Я не знал, что ROW_NUMBER является частью стандарта ANSI SQL. TIL ... –