2012-03-15 92 views
0

我有一個數據庫被用來緩存實體。這些表是這樣的:LRU緩存的SQL/HQL DELETE語句?

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

所以一個人有零個或多個地址。這些表可以由使用Hibernate的Java應用程序訪問,也可以使用基於JDBC的SQL直接從相同的應用程序訪問。

我現在需要將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 ... – 2012-03-15 13:37:17