На мой взгляд, лучше организовать схему хранения так.
В таблице с клиентами есть поле abonement_expiration, в котором хранится дата истечения абонемента. При регистрации туда пишется дата регистрации и проверка абонемента проводится сравнением с текущей датой. Кроме того, здесь же содержится ссылка на реферера.
CLIENT (
id_client,
name,
email,
abonement_expiration,
referer )
Таблица со списком заказов. Нужна в первую очередь для бухгалтерии, история заказов и всё такое.
ORDER (
id_order,
id_abonament,
id_client,
amount,
status,
date_order)
Покупка абонемента оформляется транзакцией, которая состоит из (лень писать код :-)
- занесения заказа в таблицу с заказами,
- извлечения текущей даты истечения из таблицы с клиентами,
- подсчёта новой даты с учётом стоимости абонемента,
- занесения новой даты истечения в таблицу с клиентами.
Операции 2-4 можно оформит одним запросом, но всё четыре в любом случае должны быть одной транзакцией.
Итого мы решили задачу истории, удобной проверки оплаченности абонемента, возможность дать клиенту бонус за регистрацию, и обошлись всего двумя таблицами.
Организация реферальной программы - дело не хитрое. Дополнительное поле в таблице с пользователями позволяет без труда найти реферера и рефералов. Идея с куками, которую предложил
Максим Кудрявцев - отличное решение, лучше не придумаешь.