Aperture was utterly paranoid about data-loss.
There was the SQLite database that was run on its own thread, and regularly synced to disk, the hard-sync that waited until the data had flushed through to the disk platters.
In addition to that there was a whole structure of plist files, one per image, that meant the database could be reconstructed from all these individual files, so if something had somehow corrupted the SQLite database, it could be rebuilt. There was an option to do that in the menu or settings, I forget which. The plists were write-once, so they couldn't be corrupted by the app after they'd been written-and-verified on ingest.
Finally, there were archives you could make which would back up the database (and plist files) to another location. This wasn't automated (like Time Machine is) but you could set it running overnight and come back to a verified-and-known-good restore-point.
If there was a catastrophic data loss, it's (IMHO much) more likely there was a disk failure than anything in the application itself causing problems - and unless you only ever had one instance of your data, and further that the disk problem was across both the platter-area that stored plists and well as database, it ought to have been recoverable.
Source: I wrote the database code for Aperture. I tested it with various databases holding up to 1M photos on a nightly basis, with scripts that randomly corrupted parts of the database, did a rebuild, and compared the rebuilt with a known-good db. We regarded the database as a cache, and the plists as "truth"
I'm not saying it was impossible that it was a bug in Aperture - it was a very big program, but we ran a lot of tests on that thing, we were very aware that people are highly attached to their photos, and we also knew that when you have millions of users, even a 1-in-a-million corner-case problem can be a really big issue - no-one wanted to read "Aperture lost all my photos", ever.