Ultimately if you want to allow more than one website per user, you're going to want an array layer in there: a hash of arrays of hashes. (You could replace the array layer with something functionally equivalent, like another hash layer, or Set::Object, but I see little point in doing that.)
If you can't hold it all in memory, you're going to have to rethink your technique. Might it be possible to sort (or split) the file per-user, and then process the data one user at a time?
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'