This is a bit philosophical, however, here is the scenario and the related question. Suppose you sell premium accounts and at the same time offer time-limited free accounts. Users register and log in using their email address. Creating a free account does not require handing over any overly sensitive data (just the email). Free users have X days to evaluate your service then either upgrade to a premium account or see their free account expire.
The question is: how to best handle that "expired" database-wise?
You could:
1) keep the account in your global "user" table marking it is as expired
2) remove the account, possibly moving it to a user_history or expired_user table
Has anyone faced the same problem?
I'd suggest splitting the schema into two:
TABLE: users
user_id (PK)
email_address
password_hash
....
TABLE: user_status
user_status_id (PK)
user_id (FK)
status_date
status_value
The current status of a given account is the one with the latest status date. When the user signs up for a "free" account, you insert a record into user_status with status value "new_free_status"; when the account expires, you insert a record with status value "free_account_expired". You use the status to check whether a user can log in or not; if you want to allow people to sign up at least one month after their free account last expired, you check the user status record to see when their account was closed.
You can, of course, create another lookup table called "status", and join to a table with "account_type" - that way, your data becomes more self-describing.
The key thing in this design is that you want to separate the user profile from the current status, and keep track of that status over time. This allows you to answer questions like "how many people signed up for a paid account after having a trial?", "how long between signing up for a free account do people upgrade?", "how many users come back for another trial?" etc.