You can often go further than that with some database trickery.
We once needed to cache a list of objects that was unacceptably slow serialize the JSON for. We needed to cache them in memcache, but also needed reliable cache invalidation without having to instrument every ingestion point with the logic. Here's what we ended up doing.
1. Every record gets an int field titled "index" or similar.
2. Every time a record is inserted or updated, index is changed to the next value from a sequence
3. The cache key for memcache includes the number of records and the maximum index from all the records returned (including any intermediate objects if joins are involved)
4. Infinite TTL for all cache keys, but the entire cache is LRU guaranteeing that stale records are eventually removed.
This setup works because any conceivable operation done would change the cache key. If new records are inserted or deleted, count and index change. If a record is updated, then the max index changes. Even deleting and adding a new record will change the index, meaning that no matter what happens you'll get a new key and the system will continue to cache appropriately.
We once needed to cache a list of objects that was unacceptably slow serialize the JSON for. We needed to cache them in memcache, but also needed reliable cache invalidation without having to instrument every ingestion point with the logic. Here's what we ended up doing.
1. Every record gets an int field titled "index" or similar.
2. Every time a record is inserted or updated, index is changed to the next value from a sequence
3. The cache key for memcache includes the number of records and the maximum index from all the records returned (including any intermediate objects if joins are involved)
4. Infinite TTL for all cache keys, but the entire cache is LRU guaranteeing that stale records are eventually removed.
This setup works because any conceivable operation done would change the cache key. If new records are inserted or deleted, count and index change. If a record is updated, then the max index changes. Even deleting and adding a new record will change the index, meaning that no matter what happens you'll get a new key and the system will continue to cache appropriately.