简体   繁体   中英

Update record or keep a log?

I'm dealing with user subscriptions.

A user creates a recurring subscription. Many things can happen to that subscription, such as it is renewed, or it's canceled, or the latest billing was unsuccessful, or the user has paused or restarted with subscription.

Do you suggest:

  1. Having one subscriptions record for each user, which has fields for all possible values such as started date, expires date, is active, failed billing date, canceled date, paused date, restarted date?
  2. Or having one subscriptions record, with a secondary table subscription_events ? A row in this secondary table could record "subscription X has been renewed". Then I would query the most recent event for a subscription to figure out its current status.
  3. Or a better approach?

Don't go for 1. It's not flexible enough for new events. You don't want a design where you need to alter the table every time a new event comes along. You would also need columns for each event date and it just starts getting ugly when you want to know the order of things. Also what happens when a user can have multiple subscriptions?

2 is about right. To normalize it a bit, I would imagine you have a USER table and a SERVICE table with a SUBSCRIPTION mapping the two together. Then there would be an EVENT table with the known possible events and a SUBSCRIPTION_EVENT_MAP mapping SUBSCRIPTION to EVENT with a time stamp.

It comes down to the intention of the design . Here are some out of many---many---approaches to take:

You could use a history table:

-- stores info re:reason for the last update of a subscription
CREATE TABLE subscription_history (
      subscription_id INT
    , change_date DATETIME
    , change_reason VARCHAR(255)
)

Or a history table in conjunction with a lookup:

-- stores info re:reason for the last update of a subscription
--     but links to a change_reason table for reason id lookups
CREATE TABLE subscription_history_L (
      subscription_id INT
    , change_date DATETIME
    , change_reason_id INT
)

-- lookup table containing change reasons
CREATE TABLE change_reason (
      change_reason_id INT
    , change_reason VARCHAR(255)
)

Or an audit table v1:

-- contains all columns in your subscription table plus audit fields
CREATE TABLE subscription_audit (
      subscription_audit_id INT
    -- All the fields from your `subscriptions` table
    , audit_date DATETIME
    , audit_reason VARCHAR(255)
    , audit_by VARCHAR(255) -- example
    -- etc etc whatever other information that is pertinent to the change
)

Or an audit table v2:

-- this could also act like a history table, so you can change the table name/purpose
CREATE TABLE subscription_audit (
      subscription_id INT
    , modified_column VARCHAR(255)
    , value_old VARCHAR(255)
    , value_new VARCHAR(255)
    , modified_date DATETIME
) -- Drawback here is that you'll have one audit record per column
  -- , and you may have to add extra columns for other data types
  -- , or convert your values to varchar or something else.. which isn't 
  --   a really good idea! I just want to present this in case you can
  --   develop the idea you find interesting further

I dunno your RDBMS, but this is nearly general SQl (which I think I can better use as a method to explain than words and words)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM