Redshift tables: content, engagement & events

These are your fact tables — the ones that actually move. Content and the five engagement tables (views, likes, comments, shares, follows) drive most Fuse dashboards, and the events model sits underneath every attendance and waitlist report. Expand any table to see what it holds and every field available through the connector.

How these tables fit together

From

To

Join

contents

chapters

contents.chapter_id = chapters.id

chapters

topics

chapters.topic_id = topics.id

chapter_items

contents / chapters

join table, ordered by weight

contents

videos

contents.composite_id filtered by composite_type

views

anything

viewable_id filtered by viewable_type

likes

anything

likable_id filtered by type

shares

anything

shareable_id filtered by shareable_type

comments / follows

contents

content_id = contents.id

events

event_occurrences

event_occurrences.event_id = events.id

participation_requests

event_occurrences

participation_requests.occurrence_id = event_occurrences.id

participation_approvals

participation_requests

participation_request_id = participation_requests.id

Engagement is spread across five tables, not one. There is no single "engagement" fact table. Universal Analytics builds its engagement metrics by summing across views, likes, comments, shares and follows. The simplest way to reproduce that is to union the five into one fact table with an added column naming the engagement type — you then get a single date axis, a single user join, and an engagement-type filter for free. There is a ready-made SQL statement for this on Using the connector with your BI tool.

Content, topics & structure

contents — every item of content in your instance

Manages and delivers a wide range of educational resources, supporting learning, engagement and content management. It defines individual pieces of content — articles, videos, documents, courses and other resources — that users can access.

Fuse uses it to: deliver learning materials and resources; organise content by type, topic or audience; support search, filtering and recommendations; let admins create, edit and manage content; and track usage, completion and engagement.

For reporting: composite_id + composite_type is the polymorphic link to the underlying asset (a video, a file, an article) — filter by composite_type before joining to videos. required_view_percentage is what determines whether a view counts as a completion. The signature_* columns cover digital signature configuration, but signature completion data itself is not exposed through Universal Analytics.

Field

Role

id

Primary key

company_id

Tenant key

name

Title

description

Attribute

user_id

Foreign key → users.id (creator)

author_name

Display attribute

chapter_id

Foreign key → chapters.id

composite_id

Polymorphic ID — the underlying asset

composite_type

Polymorphic type — filter on this first

thumbnail_id

Asset reference

total_view_count

Denormalised counter

likes_count

Denormalised counter

likes_count_boost

Manual adjustment to like count

comments_count

Denormalised counter

shares_count

Denormalised counter

follows_count

Denormalised counter

required_view_percentage

Completion threshold

visibility_state

Publication status

version_date

Content versioning

metadata

Serialised attributes

name_language

Localisation

description_language

Localisation

display_transcription

Display flag

video_chapters_title

Display attribute

download_allowed_for

Permission setting

comments_disabled

Permission flag

signature_enabled

Digital signature setting

signature_title

Digital signature setting

signature_confirmation

Digital signature setting

signature_update_message

Digital signature setting

signature_notifications_enabled

Digital signature setting

notify_signers

Digital signature setting

signers_notification_message

Digital signature setting

everyone_can_sign

Digital signature setting

panda_encoding_screenshot

Encoding internal

created_at

Timestamp — publication date

updated_at

Timestamp

topics — how content is categorised

Organises and categorises information, making it easier for users to find relevant content and take part in discussions on specific subjects. A topic can be associated with content, questions, communities and other entities.

Fuse uses it to: categorise and organise content, discussions and learning materials; let users filter, search and browse by topic; help admins curate topics for engagement and relevance; and support reporting on topic usage and popularity.

Topic completion is not sticky. Unlike learning plans, if new content is added to a topic after a user has completed it, that completion stops being reported and the user's progress drops below 100%. Expect completion rates to fall when content is published, and consider tracking updated_at alongside completion trends so you can explain the dips.

Field

Role

id

Primary key

company_id

Tenant key

name

Title

description

Attribute

user_id

Foreign key → users.id (owner)

state

Publication status — reserved word, quote it in SQL

total_view_count

Denormalised counter

shares_count

Denormalised counter

questions_count

Denormalised counter

enabled_assessments

Feature flag

enabled_panel_types

Display configuration

visual_completion_source

Completion configuration

custom_html

Customisation

custom_html_top

Customisation

settings

Serialised settings

avatar_id

Asset reference

name_language

Localisation

description_language

Localisation

created_at

Timestamp

updated_at

Timestamp

chapters — sections within a topic

Organises course content into structured sections, supporting effective learning, navigation and progress tracking. It defines the segments of a larger course or module, breaking content into manageable parts.

Fuse uses it to: structure courses into chapters for easier navigation; display chapter content as users progress; support progress tracking, completion status and analytics at chapter level; and let admins create, edit and organise chapters.

For reporting: ancestry encodes the chapter hierarchy as a path string — parse it if you need parent/child chapter levels. weight controls display order.

Field

Role

id

Primary key

company_id

Tenant key

topic_id

Foreign key → topics.id

name

Title

ancestry

Hierarchy path — parse for parent/child

weight

Display sequence

questions_count

Denormalised counter

color

Display attribute

settings

Serialised settings

name_language

Localisation

created_at

Timestamp

updated_at

Timestamp

chapter_items — which content sits in which chapter

The source spreadsheet merged this table with comments into a single row. Description added here for clarity. The join table placing items of content inside a chapter, with an explicit ordering.

For reporting: use this to build a content-to-chapter-to-topic hierarchy, and to count how many items a topic contains — which is the denominator behind topic progress percentages. weight gives you the intended sequence, useful for drop-off analysis across a structured pathway.

Field

Role

id

Primary key

chapter_id

Foreign key → chapters.id

content_id

Foreign key → contents.id

weight

Display sequence

questions_count

Denormalised counter

company_id

Tenant key

created_at

Timestamp

updated_at

Timestamp

chapter_links — relationships between chapters

Organises and connects chapters within courses, supporting structured learning paths, navigation and prerequisite management. It defines relationships between chapters — sequencing, prerequisites or navigation links.

Fuse uses it to: control the flow and navigation between chapters; enforce prerequisites or recommended learning paths; display related chapters or suggest next steps; and let admins organise chapter relationships.

Field

Role

id

Primary key

chapter_id

Foreign key → chapters.id

title

Link label

href

Link target

status

Link status — reserved word, quote it in SQL

company_id

Tenant key

created_at

Timestamp

updated_at

Timestamp

featured_contents — what is promoted, and where

Highlights specific content for different audiences, supporting flexible and targeted promotion. It is a join table linking a "featureable" item — usually content, but also topics or events — to a "target" such as a company or community, where that item should be promoted.

Fuse uses it to: display a curated list of featured content for a company or community; manage the order featured items appear in via position; support admin interfaces for selecting and organising featured items; and enable dynamic, context-specific promotion.

For reporting: this is the table that lets you answer "does featuring content actually drive views?". Join featured periods against views by content and date to measure lift. Note it is doubly polymorphic — both the target and the featured item need their *_type filtered before joining.

Field

Role

id

Primary key

target_id

Polymorphic ID — where it is featured

target_type

Polymorphic type — company, community

featureable_id

Polymorphic ID — what is featured

featureable_type

Polymorphic type — content, topic, event

position

Display sequence — reserved word, quote it in SQL

company_id

Tenant key

created_at

Timestamp — when featuring began

updated_at

Timestamp

Video & media

videos — video assets and their encoding state

Manages and delivers video content, supporting learning, engagement and multimedia experiences. It defines each video resource, including metadata, file location and associations with other content.

Fuse uses it to: deliver video for training, learning or communication; organise videos into courses, learning plans or communities; track engagement such as views and completion; and let admins and users upload, manage and search videos.

For reporting: duration is essential for any watch-rate calculation — pair it with video_view_progresses.value to work out what proportion of a video was actually watched. state tells you whether a video has finished encoding; unencoded videos will show no view data.

Field

Role

id

Primary key

company_id

Tenant key

type

Video type — reserved word, quote it in SQL

state

Encoding status — reserved word, quote it in SQL

duration

Length — key for watch-rate

asset_uid

File reference

asset_size

File size

encodings

Encoding formats

encoding_job_id

Encoding internal

encoding_screenshot

Encoding internal

screenshot_uid

Thumbnail reference

capture_id

Source reference

copied

Duplication flag

transcription_id

Transcription reference

transcription_completed_at

Timestamp

preview_path

Asset reference

created_at

Timestamp

updated_at

Timestamp

video_view_progresses — how far through a video each user got

Monitors and reports user engagement with video content, supporting personalised learning, compliance and analytics. It records user progress for individual videos so the application can resume playback, monitor engagement and report completion.

Fuse uses it to: resume videos where users left off; track and report video completion for learning plans, compliance or analytics; support engagement features such as badges or certificates; and let admins monitor which videos are watched and by whom.

One row per user per video, updated in place — this holds the latest position, not a history of viewing sessions. You cannot reconstruct a per-session watch history from this table. Divide value by videos.duration for a completion percentage, and compare against contents.required_view_percentage to decide whether it counts as complete.

Field

Role

id

Primary key

user_id

Foreign key → users.id

video_id

Foreign key → videos.id

value

Progress position — reserved word, quote it in SQL

company_id

Tenant key

created_at

Timestamp — first viewed

updated_at

Timestamp — last viewed

subtitles_files — captions and transcripts

Provides accessible and multilingual media experiences by managing subtitle files for video and audio content. It tracks the files providing subtitles or captions, supporting accessibility and multilingual delivery.

Fuse uses it to: display subtitles or captions during playback; support accessibility for hearing-impaired users; enable multilingual support; and let admins upload, manage and approve subtitle files.

For reporting: counting distinct label values per content item gives you subtitle-language coverage — a useful accessibility and localisation KPI.

Field

Role

id

Primary key

content_id

Foreign key → contents.id

label

Language label

file_uid

File reference

transcript

Transcript text

updated_by

Foreign key → users.id

company_id

Tenant key

created_at

Timestamp

updated_at

Timestamp

Engagement

views — every view of anything

Monitors and analyses user interactions with content, supporting engagement tracking, analytics and personalised experiences. It records each instance of a user viewing something — a course, article, video or profile.

Fuse uses it to: analyse user engagement and content popularity; generate activity feeds, recommendations and personalised dashboards; support reporting for admins and content creators; and trigger notifications or achievements based on views.

This is by far the largest table in the connector. Plan your refresh strategy around it: constrain by date range, select only the columns you need, and use whatever incremental or partitioned loading your tool offers, keyed on created_at. If you are querying live rather than extracting, never scan it unfiltered.

For reporting: filter viewable_type before joining to any dimension. request_type distinguishes how the view was made, which is useful for separating genuine consumption from incidental page loads.

Field

Role

id

Primary key

user_id

Foreign key → users.id

viewable_id

Polymorphic ID — what was viewed

viewable_type

Polymorphic type — filter on this first

request_type

How the view was made

company_id

Tenant key

created_at

Timestamp — the view date (UTC)

updated_at

Timestamp

likes — user approval of content

Supports social engagement by tracking user approval of content, helping drive interaction and feedback across the platform. It records each instance of a user liking something, enabling popularity metrics, feedback and engagement tracking.

Fuse uses it to: display like counts and engagement on content, posts and comments; let users see what they have liked; support sorting, filtering and recommending popular items; and drive notifications and activity feeds.

Two naming quirks here. The ID column is spelled likable_id, not likeable_id. And the polymorphic type is held in a column simply called type — there is no likable_type. Filter on type before joining, and remember it is a reserved word in SQL.

Field

Role

id

Primary key

user_id

Foreign key → users.id

likable_id

Polymorphic ID — what was liked

type

Polymorphic type — filter on this first

company_id

Tenant key

created_at

Timestamp — the like date

updated_at

Timestamp

comments — discussion beneath content

The source spreadsheet merged this table with chapter_items. The description below is the comment-related half. Supports user interaction and feedback on content and chapter items, fostering engagement and collaborative learning. It tracks user-generated comments, supporting discussion, collaboration and review.

Fuse uses it to: display comments and discussions; support feedback, peer review and collaborative learning; let admins and moderators manage and moderate comments; and enable notifications and activity feeds from new comments.

For reporting: ancestry encodes threaded replies — a null ancestry means a top-level comment, so you can separate original comments from replies. anonymous flags comments posted anonymously where the community allows it; these still carry a user_id, so be careful not to expose it in any report. Filter deleted_at is null for live comments.

Field

Role

id

Primary key

content_id

Foreign key → contents.id

user_id

Foreign key → users.id

context_community_id

Foreign key → communities.id

body

Comment text

parsed_body

Rendered comment text

body_language

Localisation

ancestry

Threading path — null means top level

anonymous

Privacy flag

likes_count

Denormalised counter

deleted_at

Soft delete

company_id

Tenant key

created_at

Timestamp

updated_at

Timestamp

shares — content passed on to others

Lets users distribute content and resources, supporting collaboration, engagement and dissemination. It records sharing actions — when a user shares a course, article, event or other entity with another user, group or external recipient.

Fuse uses it to: enable users to share content for collaboration, learning or engagement; track and report sharing activity for analytics and notifications; support permissions and access control for shared items; and let admins monitor sharing across the platform.

For reporting: shared_from_id + shared_from_type capture the origin of the share, which lets you trace a chain of resharing and identify your genuine internal amplifiers. notifications_sent tells you whether the share actually reached anyone.

Field

Role

id

Primary key

user_id

Foreign key → users.id (sharer)

shareable_id

Polymorphic ID — what was shared

shareable_type

Polymorphic type — filter on this first

shared_from_id

Polymorphic ID — where the share originated

shared_from_type

Polymorphic type

note

Message attached to the share

notifications_sent

Delivery flag

company_id

Tenant key

created_at

Timestamp

updated_at

Timestamp

follows — what users are subscribed to

Supports social and personalised features by tracking who or what users are interested in, driving engagement and connectivity. It records who is following whom or what, enabling activity feeds, notifications and personalised recommendations.

Fuse uses it to: notify users about new activity from people or content they follow; build personalised feeds and recommendations; support social features; and let users manage what they follow.

Watch out: the field list exposed through the connector shows content_id rather than the polymorphic followable_id / followable_type pair described elsewhere. Treat this table as content follows for reporting purposes. Filter deleted_at is null to exclude unfollows — an unfollow soft-deletes the row rather than removing it, so deleted_at is actually a useful unfollow-date field for churn analysis.

Field

Role

id

Primary key

user_id

Foreign key → users.id

content_id

Foreign key → contents.id

deleted_at

Soft delete — effectively the unfollow date

company_id

Tenant key

created_at

Timestamp — follow date

updated_at

Timestamp

gamification_activities — points, scores and contribution

Manages and displays user participation in gamified features, supporting engagement, motivation and recognition. It records activities contributing to a user's progress in gamified elements — earning points, badges, completing challenges or reaching milestones.

Fuse uses it to: update user profiles with achievements, badges and points; display progress, leaderboards and rewards; trigger notifications or unlock new gamification features; and analyse engagement and participation.

This is the single richest table for engagement analysis. Unlike the other engagement tables, it is pre-aggregated per user per day (created_on) and splits activity into contribution, engagement and consumption scores, plus roughly twenty individual activity counters. If you want a fast engagement dashboard without unioning five fact tables, start here. Bear in mind the scores are weighted by Fuse's gamification rules, so they will not tie exactly to raw counts in views or likes. Filter deleted_at is null. Note also that users.hidden_from_leaderboard excludes some users from leaderboard displays.

Field

Role

id

Primary key

user_id

Foreign key → users.id

created_on

The activity date — group by this

total_score

Composite score

contribution_score

Score component — creating

engagement_score

Score component — interacting

consumption_score

Score component — viewing

uploading_videos

Activity counter — contribution

uploading_files

Activity counter — contribution

sharing_links

Activity counter — contribution

asking_questions

Activity counter — contribution

publishing_articles

Activity counter — contribution

viewing_content

Activity counter — consumption

making_comments

Activity counter — engagement

liking_content

Activity counter — engagement

liking_comments

Activity counter — engagement

sharing_content

Activity counter — engagement

joining_communities

Activity counter — engagement

completing_topics

Activity counter — learning

completing_learning_plans

Activity counter — learning

completing_individual_scorm

Activity counter — learning

content_views

Received counter — views on their content

content_shares

Received counter

content_likes

Received counter

content_comments

Received counter

comment_likes

Received counter

deleted_at

Soft delete

company_id

Tenant key

created_at

Timestamp

updated_at

Timestamp

usage_logs — platform activity log

Monitors, analyses and reports on user activity, supporting platform optimisation, security and compliance. It tracks events such as logins, page views, content access and other actions for auditing, analytics and troubleshooting.

Fuse uses it to: analyse engagement and application usage patterns; support auditing, compliance and security monitoring; troubleshoot by reviewing user actions and system events; and generate activity reports for administrators.

Incomplete field list. Only user_id and created_at are documented in the source, but the table holds considerably more than this in practice — action type, target references and session metadata. Check what your connector actually exposes before designing anything around it. With just these two columns you can still derive daily active users and login recency, which is how Universal Analytics uses it for its Active Users and Number of Days Active metrics.

Field

Role

user_id

Foreign key → users.id

created_at

Timestamp — the activity date (UTC)

Events

Read this before building any event report. Fuse separates the event (the reusable definition) from the occurrence (a specific date and time). Attendance, capacity and cost all sit at occurrence level, not event level. Almost every mistake in event reporting comes from aggregating at the wrong one. The chain is: eventsevent_occurrencesparticipation_requestsparticipation_approvals.

events — the event definition

Manages and displays scheduled activities, supporting user engagement and collaboration around time-based occurrences. It tracks the individual events that users or groups can attend, organise or interact with.

Fuse uses it to: display upcoming or past events; let users RSVP, register or participate; support notifications, reminders and calendar integrations; and let admins or organisers create, edit and manage events.

For reporting: this is a dimension, not a fact. Count rows here for "how many events exist"; go to event_occurrences for anything about when they ran or who came. learning_plan_id links an event into a learning plan, which is how attendance can contribute to plan completion.

Field

Role

id

Primary key

company_id

Tenant key

name

Title

description

Attribute

community_id

Foreign key → communities.id

owner_id

Foreign key → users.id (organiser)

learning_plan_id

Foreign key → learning_plans.id

asset_id

Asset reference

price

Cost attribute

visibility_state

Publication status

settings

Serialised settings

created_at

Timestamp

updated_at

Timestamp

event_occurrences — each individual session

Manages and displays individual sessions of events, supporting recurring schedules, attendance tracking and user engagement. It stores each occurrence of an event — a specific date and time when a recurring event takes place.

Fuse uses it to: display all upcoming or past sessions to users; manage registration, attendance and notifications per occurrence; support recurring events so users sign up for specific sessions; and let organisers edit, cancel or reschedule individual occurrences.

This is the grain for all event metrics. spaces_number is the capacity denominator behind every subscription and attendance percentage in Universal Analytics, and it can be null for uncapped events. Use your tool's safe-division function so those occurrences do not produce errors or infinite values. waitlist_entries_count and withdrawal_entries_count give you oversubscription and drop-out without additional joins. Note also that starts_at is UTC while time_zone records the session's local zone — use both if you are reporting on when sessions actually run.

Field

Role

id

Primary key

event_id

Foreign key → events.id

company_id

Tenant key

starts_at

Timestamp — session start (UTC)

ends_at

Timestamp — session end (UTC)

time_zone

The session's local time zone

location

Where it runs

spaces_number

Capacity — may be null for uncapped

training_duration

Learning time attribute

visibility_state

Publication status

host_id

Foreign key → users.id

host_name

Host display name

host_email

Host contact

host_avatar_id

Asset reference

external_host

External host flag

creator_approval_required

Approval workflow flag

manager_approval_required

Approval workflow flag

specified_approval_required

Approval workflow flag

specified_approver_id

Foreign key → users.id

waitlist_entries_count

Denormalised counter — oversubscription

withdrawal_entries_count

Denormalised counter — drop-outs

shares_count

Denormalised counter

days_before_notify

Reminder setting

advertisement_code

Promotion attribute

details

Serialised attributes

created_at

Timestamp

updated_at

Timestamp

participation_requests — who applied to attend

Organises and controls user participation, supporting approval workflows and tracking participation history. It connects users to the occurrences they have asked to take part in.

Fuse uses it to: invite users to participate; track which users have requested or been invited; manage and display the status of participation requests; and support workflows for accepting, declining or completing participation.

This is your event fact table. Applied, approved and attended all derive from here and from participation_approvals. status holds the request state, completed indicates attendance, and pass_status covers whether the associated training was passed. prerequisite_learning_completed tells you whether the user met the entry requirements — useful for explaining rejections. Join to event_occurrences on occurrence_id, then up to events.

Field

Role

id

Primary key

participant_id

Foreign key → users.id

occurrence_id

Foreign key → event_occurrences.id

company_id

Tenant key

status

Request state — reserved word, quote it in SQL

type

Request category — reserved word, quote it in SQL

completed

Attendance indicator

pass_status

Training outcome

training_duration

Learning time attribute

prerequisite_learning_completed

Eligibility flag

scorm_course_id

Foreign key → scorm_courses.id

created_at

Timestamp — application date

updated_at

Timestamp

participation_approvals — who was approved, and by whom

Tracks approvals for event occurrences. Use participation_requests to get the occurrence_id for the event and trace back to the event itself.

Fuse uses it to: manage and track participation requests needing approval; enforce access control for activities requiring vetting; let admins or organisers review, approve or reject requests; and display approval status to users.

For reporting: approver_role tells you whether the creator, the manager or a specified approver handled it — this is how you measure approval bottlenecks by route. The gap between participation_requests.created_at and participation_approvals.updated_at gives you approval turnaround time. declined_subject and declined_message hold rejection reasons.

Field

Role

id

Primary key

participation_request_id

Foreign key → participation_requests.id

approver_id

Foreign key → users.id

approver_role

Approval route — creator, manager, specified

status

Pending, approved or rejected — reserved word, quote it in SQL

type

Approval category — reserved word, quote it in SQL

declined_subject

Rejection reason

declined_message

Rejection detail

company_id

Tenant key

created_at

Timestamp

updated_at

Timestamp — decision date

event_prerequisite_items — what must be done before attending

Manages and enforces event requirements, ensuring users meet the necessary conditions before participating. It links events to their prerequisites — required training, completed assessments or other conditions.

Fuse uses it to: enforce that users complete certain actions before registering or attending; display prerequisite requirements on event pages; check eligibility during registration; and support reporting on prerequisite completion and event readiness.

For reporting: combine with participation_requests.prerequisite_learning_completed to quantify how much prerequisite friction is suppressing event attendance.

Field

Role

id

Primary key

event_id

Foreign key → events.id

linkable_id

Polymorphic ID — the prerequisite

linkable_type

Polymorphic type — filter on this first

company_id

Tenant key

created_at

Timestamp

updated_at

Timestamp

event_knowledge_items — resources attached to an event

Connects events with relevant knowledge resources, supporting event preparation, learning and participant engagement. It is a join table linking events to knowledge items, indicating which resources are associated with or required for an event.

Fuse uses it to: display related resources or materials on event pages; ensure participants can access necessary information before, during or after an event; support preparation, follow-up and learning objectives; and let organisers attach relevant items to events.

For reporting: useful for testing whether events with supporting material see better attendance or better post-event assessment scores than those without.

Field

Role

id

Primary key

event_id

Foreign key → events.id

linkable_id

Polymorphic ID — the resource

linkable_type

Polymorphic type — filter on this first

company_id

Tenant key

created_at

Timestamp

updated_at

Timestamp