2012-03-15 89 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