Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it better to track events in separate models or one event model?

I realize this question is general, but I think people with a lot of experience in event tracking will have good insight.

I have a website where I want to track file downloads by user. Two methods come to mind:

1) Create a model called AssetDownload and populate that with the data.
2) Create a model called Event or Activity and have that be a general model for tracking events.

I see the following pros and cons:

Method 1:

  • Pro - Better readability because model represents the event exactly
  • Pro - Will not need to refactor out into separate events if events become too different
  • Pro - Will not need to search event table on an extra parameter all the time ("event type")
  • Con - Potentially lots of tables
  • Con - Maybe not very DRY, although they could inherit from a general Event model that is not associated with a table, or I could implement an "acts as trackable" gem

Method 2:

  • Pro - Only one table for everything
  • Pro - DRY by default
  • Con - Table will potentially become very wide with columns that are only useful for a small subset of events
  • Con - May need to refactor out specific events in the future

I am tempted to go with method 1 because it's sort of a minimum viable product thought process. Just make what I need, I'll eventually add 5 models, 1 for each event type. If I add 20 models then I can refactor using a Single Table Inheritance scheme. But at least at that point, I will know what I am refactoring, whereas designing for the future involves some guesswork right now.

However, I am successfully using Method 2 on another website right now. Just want to see what other people are doing.

Update

I want to mention that the events I am logging will need to be accessed quite often. I will be providing a dashboard where users can view file downloads by user and by date. Please consider this if your answer involves using an Audit log model

like image 900
Tony Avatar asked Dec 06 '25 07:12

Tony


2 Answers

Method 2 is the right way of doing it. It's the way I've always done it, except I call it an Audit log and make it very generic and use it for lots of things.

Don't make the table wide instead have multiple entries if you need to make more than one type of entry.

Pseudo DDL - the types may vary.

CREATE TABLE Audit
   Type           # FK identifying the entry type
   DateTime       # entry time
   RequesterID    # FK identifying the user/process initiating the request
   Object         # Filename etc.
   ObjectClass    # FK defining type of the object 
   AccessType     # FK defining the type of access (download etc.)
   AccessOverride # FK set if accessed via impersonation
   Status         # FK result of operation - success / fail
 ;

NOTE: Originally this was loosely based on the VMS Audit log model.

like image 107
Richard Harrison Avatar answered Dec 09 '25 00:12

Richard Harrison


There is a 3rd option:

event_header: 
  id
  date
  time
  type
  code
  ... 

event_type_data: 
  PK(id)
  FK(event_id)
  special_field1
  special_field2 

Your download query knows that the event type is say 4, so do a join on the event_data table

select ev.*, evd.* from event_header ev, event_type_data evd where evd.event_id = ev.id and ev.type = 4 

Overcomplication? Perhaps. Slower? Probably. Confusing for future developers? Yes. Viable? Certainly.

Me, I'd probably go with method 2 and have a text field for special data in a JSON or XML format, or simply "key:value,key:value"

like image 35
Chris K Avatar answered Dec 09 '25 00:12

Chris K



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!