@Martyr2,
I have had a chance to re-read what you posted above and ponder things.
On the first part of your solution, I agree. But on the second part, while I can see what you are saying, I think there is a better way to model things.
Below are my thoughts…
Note:
a.) I have tweaked the naming convention of the tables.
b.) Below each table is some sample data.
c.) For simplicity, I used “natural keys” for the the sample data. (In practice, IDs would be used.)
MEMBER
- id (pk)
- name
Bob
John
Amy
Larry
OFFER
- id (pk)
- member_id (fk)
- membership_plan_id (fk)
- offer_price
- start_date
- end_date
Amy, Platinum, $50, 2/15/19, 2/15/20
Larry, Platinum, $60, 3/3/19, 3/3/20
MEMBERSHIP_PLAN
- id (pk)
- name
- unit_price (aka current price)
- status (current)
Silver, $30
Gold, $40
Platinum, $60
MEMBERSHIP_PLAN_DETAILS
- id (pk)
- membership_plan_id (fk)
- plan_feature_id (fk)
- start_date
- end_date
Platinum, News, 2/1/19, -
Platinum, Articles, 2/1/19, -
Platinum, Interviews, 2/1/19, -
Platinum, Archives, 2/1/19, -
Platinum, Podcasts, 3/1/19, -
PLAN_FEATURE
- id (pk)
- name
- status (current)
News
Articles
Interviews
Archives
Podcasts
Here are two additional optional tables…
PLAN_PRICE_HISTORY
- id (pk)
- membership_plan_id (fk)
- price
- effective_date
- end_date
Platinum, $50, 2/1/19, 2/28/19
Platinum, $60, 3/1/19, -
PLAN_FEATURE_HISTORY
- id (pk)
- plan_feature_id (fk)
- effective_date
- end_date
News, 1/1/19, -
Articles, 1/1/19, -
Interviews, 1/1/19, -
Archives, 1/1/19, -
Podcasts, 3/1/19, -
Here are the relationships visually…
MEMBER -||----|<- OFFER
OFFER ->|----||- MEMBERSHIP_PLAN
MEMBERSHIP_PLAN -||----|<- MEMBERSHIP_PLAN_DETAILS
MEMBERSHIP_PLAN_DETAILS ->|----||- PLAN_FEATURE
MEMBERSHIP_PLAN -||----|<- PLAN_PRICE_HISTORY
PLAN_FEATURE -||----|<- PLAN_FEATURE_HISTORY
Above, you suggested joining my MEMBER,MEMBERSHIP_PLAN, PLAN_FEATURE together via my OFFER table.
While that would work, I would argue that approach is more of a hinderance than a help, and it doesn’t accurately model real life.
By taking this approach, you would end up with results like this…
Amy, Platinum, $50, 2/15/19, News
Amy, Platinum, $50, 2/15/19, Articles
Amy, Platinum, $50, 2/15/19, Interviews
Amy, Platinum, $50, 2/15/19, Archives
Amy, Platinum, $50, 2/15/19, Podcasts
While this does accurately show that Amy paid $50 on 2/15/19 and which Features she got when signing up, it creates redundant data in the offer_price and start_date.
Using my approach, which is more streamlined, you could run a query on MEMBERSHIP_PLAN, MEMBERSHIP_PLAN_DETAILS, PLAN_FEATURE for a given date to determine which features Amy had when she signed up, as well as how the Features may have changed during her subscription.
MEMBERSHIP_PLAN_DETAILS is really a function of MEMBERSHIP_PLAN and PLAN_FEATURE and has nothing to do with the MEMBER.
Yes, a Member signs up for certain Features, and those Features can change during the subscription, but I would argue my approach is better, more accurate, and just flexible if not slightly more so.
But in fairness, each of our approaches has pros and cons.
What do you think?
(BTW, this has turned out to be A LOT more involved than what I had wanted, but it is a good mental exercise nonetheless!!) :wink: