From 0830af49a777dd9ffaf6d245480ab2bb4504aa8c Mon Sep 17 00:00:00 2001 From: evazion Date: Tue, 13 Sep 2022 20:33:53 -0500 Subject: [PATCH] db: add user_actions view. Add a user_actions view. This view unions together a bunch of tables to produce an event log of every action taken by a user. Also add a bunch of indexes to make queries on this table efficient. Even though the view is an enormous query combining together about 30 different tables, queries are very efficient as long as every table has `created_at` and `(user_id, created)` indexes. --- .../20220913191309_create_user_actions.rb | 67 ++ db/structure.sql | 725 ++++++++++++++++-- db/views/user_actions_v01.sql | 105 +++ 3 files changed, 849 insertions(+), 48 deletions(-) create mode 100644 db/migrate/20220913191309_create_user_actions.rb create mode 100644 db/views/user_actions_v01.sql diff --git a/db/migrate/20220913191309_create_user_actions.rb b/db/migrate/20220913191309_create_user_actions.rb new file mode 100644 index 000000000..3a14039db --- /dev/null +++ b/db/migrate/20220913191309_create_user_actions.rb @@ -0,0 +1,67 @@ +class CreateUserActions < ActiveRecord::Migration[7.0] + disable_ddl_transaction! + + def change + create_view :user_actions + + add_index :bans, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :bulk_update_requests, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :dmails, :created_at, algorithm: :concurrently, where: "owner_id = from_id", name: "index_sent_dmails_on_created_at", if_not_exists: true + add_index :favorite_groups, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :forum_posts, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :forum_post_votes, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :forum_topics, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :moderation_reports, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :post_approvals, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :post_disapprovals, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :post_flags, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :post_replacements, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :saved_searches, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :tag_aliases, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :tag_implications, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :tag_versions, :created_at, algorithm: :concurrently, where: "updater_id IS NOT NULL", name: "index_tag_versions_on_created_at_where_updater_id_is_not_null", if_not_exists: true + add_index :users, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :user_events, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :user_feedback, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :uploads, :created_at, algorithm: :concurrently, if_not_exists: true + add_index :user_upgrades, :created_at, algorithm: :concurrently, where: "status IN (20, 30)", name: "index_completed_user_upgrades_on_created_at", if_not_exists: true + add_index :user_name_change_requests, :created_at, algorithm: :concurrently, if_not_exists: true + + add_index :artist_versions, [:updater_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :artist_commentary_versions, [:updater_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :bans, [:user_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :bulk_update_requests, [:user_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :comments, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :comment_votes, [:user_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :dmails, [:owner_id, :created_at], algorithm: :concurrently, where: "owner_id = from_id", name: "index_sent_dmails_on_owner_id_and_created_at", if_not_exists: true + add_index :favorite_groups, [:created_at, :id, :is_public, :creator_id], algorithm: :concurrently, name: "index_favorite_groups_on_created_at_id_is_public_creator_id", if_not_exists: true + add_index :forum_posts, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :forum_post_votes, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :forum_topics, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :mod_actions, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :moderation_reports, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :note_versions, [:updater_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :posts, [:uploader_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :post_appeals, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :post_approvals, [:user_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :post_disapprovals, [:user_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :post_flags, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :post_replacements, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :post_votes, [:user_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :saved_searches, [:user_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :tag_aliases, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :tag_implications, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :tag_versions, [:updater_id, :created_at], algorithm: :concurrently, where: "updater_id IS NOT NULL", name: "index_tag_versions_on_updater_id_and_created_at", if_not_exists: true + add_index :uploads, [:uploader_id, :created_at, :id], algorithm: :concurrently, if_not_exists: true + add_index :users, [:id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :user_events, [:user_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :user_feedback, [:user_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :user_feedback, [:creator_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :user_upgrades, [:purchaser_id, :created_at], algorithm: :concurrently, where: "status IN (20, 30)", name: "index_completed_user_upgrades_on_updater_id_and_created_at", if_not_exists: true + add_index :user_name_change_requests, [:user_id, :created_at], algorithm: :concurrently, if_not_exists: true + add_index :wiki_page_versions, [:updater_id, :created_at], algorithm: :concurrently, if_not_exists: true + + add_index :forum_posts, [:topic_id, :id], algorithm: :concurrently, if_not_exists: true + add_index :users, :bit_prefs, where: "get_bit(bit_prefs::bit(31), 24) = 1", algorithm: :concurrently, name: "index_users_on_enable_private_favorites", if_not_exists: true # users.enable_private_favorites = true + end +end diff --git a/db/structure.sql b/db/structure.sql index 2892a231e..4947a658d 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2080,6 +2080,296 @@ CREATE TABLE public.user_events ( ); +-- +-- Name: user_feedback; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.user_feedback ( + user_id integer NOT NULL, + creator_id integer NOT NULL, + created_at timestamp without time zone NOT NULL, + body text NOT NULL, + category character varying NOT NULL, + id integer NOT NULL, + updated_at timestamp without time zone NOT NULL, + is_deleted boolean DEFAULT false NOT NULL +); + + +-- +-- Name: user_name_change_requests; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.user_name_change_requests ( + id integer NOT NULL, + user_id integer NOT NULL, + original_name character varying NOT NULL, + desired_name character varying NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: user_upgrades; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.user_upgrades ( + id integer NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + recipient_id integer NOT NULL, + purchaser_id integer NOT NULL, + upgrade_type integer NOT NULL, + status integer NOT NULL, + transaction_id character varying, + payment_processor integer DEFAULT 0 NOT NULL +); + + +-- +-- Name: user_actions; Type: VIEW; Schema: public; Owner: - +-- + +CREATE VIEW public.user_actions AS + SELECT 'ArtistVersion'::character varying AS model_type, + artist_versions.id AS model_id, + artist_versions.updater_id AS user_id, + 'create'::character varying AS event_type, + artist_versions.created_at AS event_at + FROM public.artist_versions +UNION ALL + SELECT 'ArtistCommentaryVersion'::character varying AS model_type, + artist_commentary_versions.id AS model_id, + artist_commentary_versions.updater_id AS user_id, + 'create'::character varying AS event_type, + artist_commentary_versions.created_at AS event_at + FROM public.artist_commentary_versions +UNION ALL + SELECT 'Ban'::character varying AS model_type, + bans.id AS model_id, + bans.user_id, + 'subject'::character varying AS event_type, + bans.created_at AS event_at + FROM public.bans +UNION ALL + SELECT 'BulkUpdateRequest'::character varying AS model_type, + bulk_update_requests.id AS model_id, + bulk_update_requests.user_id, + 'create'::character varying AS event_type, + bulk_update_requests.created_at AS event_at + FROM public.bulk_update_requests +UNION ALL + SELECT 'Comment'::character varying AS model_type, + comments.id AS model_id, + comments.creator_id AS user_id, + 'create'::character varying AS event_type, + comments.created_at AS event_at + FROM public.comments +UNION ALL + SELECT 'CommentVote'::character varying AS model_type, + comment_votes.id AS model_id, + comment_votes.user_id, + 'create'::character varying AS event_type, + comment_votes.created_at AS event_at + FROM public.comment_votes +UNION ALL +( SELECT 'Dmail'::character varying AS model_type, + dmails.id AS model_id, + dmails.from_id AS user_id, + 'create'::character varying AS event_type, + dmails.created_at AS event_at + FROM public.dmails + WHERE (dmails.from_id <> dmails.owner_id) + ORDER BY dmails.created_at DESC) +UNION ALL + SELECT 'FavoriteGroup'::character varying AS model_type, + favorite_groups.id AS model_id, + favorite_groups.creator_id AS user_id, + 'create'::character varying AS event_type, + favorite_groups.created_at AS event_at + FROM public.favorite_groups +UNION ALL + SELECT 'ForumPost'::character varying AS model_type, + forum_posts.id AS model_id, + forum_posts.creator_id AS user_id, + 'create'::character varying AS event_type, + forum_posts.created_at AS event_at + FROM public.forum_posts +UNION ALL + SELECT 'ForumPostVote'::character varying AS model_type, + forum_post_votes.id AS model_id, + forum_post_votes.creator_id AS user_id, + 'create'::character varying AS event_type, + forum_post_votes.created_at AS event_at + FROM public.forum_post_votes +UNION ALL + SELECT 'ForumTopic'::character varying AS model_type, + forum_topics.id AS model_id, + forum_topics.creator_id AS user_id, + 'create'::character varying AS event_type, + forum_topics.created_at AS event_at + FROM public.forum_topics +UNION ALL + SELECT 'ModAction'::character varying AS model_type, + mod_actions.id AS model_id, + mod_actions.creator_id AS user_id, + 'create'::character varying AS event_type, + mod_actions.created_at AS event_at + FROM public.mod_actions +UNION ALL + SELECT 'ModerationReport'::character varying AS model_type, + moderation_reports.id AS model_id, + moderation_reports.creator_id AS user_id, + 'create'::character varying AS event_type, + moderation_reports.created_at AS event_at + FROM public.moderation_reports +UNION ALL + SELECT 'NoteVersion'::character varying AS model_type, + note_versions.id AS model_id, + note_versions.updater_id AS user_id, + 'create'::character varying AS event_type, + note_versions.created_at AS event_at + FROM public.note_versions +UNION ALL + SELECT 'Post'::character varying AS model_type, + posts.id AS model_id, + posts.uploader_id AS user_id, + 'create'::character varying AS event_type, + posts.created_at AS event_at + FROM public.posts +UNION ALL + SELECT 'PostAppeal'::character varying AS model_type, + post_appeals.id AS model_id, + post_appeals.creator_id AS user_id, + 'create'::character varying AS event_type, + post_appeals.created_at AS event_at + FROM public.post_appeals +UNION ALL + SELECT 'PostApproval'::character varying AS model_type, + post_approvals.id AS model_id, + post_approvals.user_id, + 'create'::character varying AS event_type, + post_approvals.created_at AS event_at + FROM public.post_approvals +UNION ALL + SELECT 'PostDisapproval'::character varying AS model_type, + post_disapprovals.id AS model_id, + post_disapprovals.user_id, + 'create'::character varying AS event_type, + post_disapprovals.created_at AS event_at + FROM public.post_disapprovals +UNION ALL + SELECT 'PostFlag'::character varying AS model_type, + post_flags.id AS model_id, + post_flags.creator_id AS user_id, + 'create'::character varying AS event_type, + post_flags.created_at AS event_at + FROM public.post_flags +UNION ALL + SELECT 'PostReplacement'::character varying AS model_type, + post_replacements.id AS model_id, + post_replacements.creator_id AS user_id, + 'create'::character varying AS event_type, + post_replacements.created_at AS event_at + FROM public.post_replacements +UNION ALL + SELECT 'PostVote'::character varying AS model_type, + post_votes.id AS model_id, + post_votes.user_id, + 'create'::character varying AS event_type, + post_votes.created_at AS event_at + FROM public.post_votes +UNION ALL + SELECT 'SavedSearch'::character varying AS model_type, + saved_searches.id AS model_id, + saved_searches.user_id, + 'create'::character varying AS event_type, + saved_searches.created_at AS event_at + FROM public.saved_searches +UNION ALL + SELECT 'TagAlias'::character varying AS model_type, + tag_aliases.id AS model_id, + tag_aliases.creator_id AS user_id, + 'create'::character varying AS event_type, + tag_aliases.created_at AS event_at + FROM public.tag_aliases +UNION ALL + SELECT 'TagImplication'::character varying AS model_type, + tag_implications.id AS model_id, + tag_implications.creator_id AS user_id, + 'create'::character varying AS event_type, + tag_implications.created_at AS event_at + FROM public.tag_implications +UNION ALL +( SELECT 'TagVersion'::character varying AS model_type, + tag_versions.id AS model_id, + tag_versions.updater_id AS user_id, + 'create'::character varying AS event_type, + tag_versions.created_at AS event_at + FROM public.tag_versions + WHERE (tag_versions.updater_id IS NOT NULL) + ORDER BY tag_versions.created_at DESC) +UNION ALL + SELECT 'Upload'::character varying AS model_type, + uploads.id AS model_id, + uploads.uploader_id AS user_id, + 'create'::character varying AS event_type, + uploads.created_at AS event_at + FROM public.uploads +UNION ALL + SELECT 'User'::character varying AS model_type, + users.id AS model_id, + users.id AS user_id, + 'create'::character varying AS event_type, + users.created_at AS event_at + FROM public.users +UNION ALL + SELECT 'UserEvent'::character varying AS model_type, + user_events.id AS model_id, + user_events.user_id, + 'create'::character varying AS event_type, + user_events.created_at AS event_at + FROM public.user_events +UNION ALL + SELECT 'UserFeedback'::character varying AS model_type, + user_feedback.id AS model_id, + user_feedback.creator_id AS user_id, + 'create'::character varying AS event_type, + user_feedback.created_at AS event_at + FROM public.user_feedback +UNION ALL + SELECT 'UserFeedback'::character varying AS model_type, + user_feedback.id AS model_id, + user_feedback.user_id, + 'subject'::character varying AS event_type, + user_feedback.created_at AS event_at + FROM public.user_feedback +UNION ALL +( SELECT 'UserUpgrade'::character varying AS model_type, + user_upgrades.id AS model_id, + user_upgrades.purchaser_id AS user_id, + 'create'::character varying AS event_type, + user_upgrades.created_at AS event_at + FROM public.user_upgrades + WHERE (user_upgrades.status = ANY (ARRAY[20, 30])) + ORDER BY user_upgrades.created_at DESC) +UNION ALL + SELECT 'UserNameChangeRequest'::character varying AS model_type, + user_name_change_requests.id AS model_id, + user_name_change_requests.user_id, + 'create'::character varying AS event_type, + user_name_change_requests.created_at AS event_at + FROM public.user_name_change_requests +UNION ALL + SELECT 'WikiPageVersion'::character varying AS model_type, + wiki_page_versions.id AS model_id, + wiki_page_versions.updater_id AS user_id, + 'create'::character varying AS event_type, + wiki_page_versions.created_at AS event_at + FROM public.wiki_page_versions; + + -- -- Name: user_events_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- @@ -2099,22 +2389,6 @@ CREATE SEQUENCE public.user_events_id_seq ALTER SEQUENCE public.user_events_id_seq OWNED BY public.user_events.id; --- --- Name: user_feedback; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.user_feedback ( - id integer NOT NULL, - user_id integer NOT NULL, - creator_id integer NOT NULL, - category character varying NOT NULL, - body text NOT NULL, - created_at timestamp without time zone NOT NULL, - updated_at timestamp without time zone NOT NULL, - is_deleted boolean DEFAULT false NOT NULL -); - - -- -- Name: user_feedback_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- @@ -2135,20 +2409,6 @@ CREATE SEQUENCE public.user_feedback_id_seq ALTER SEQUENCE public.user_feedback_id_seq OWNED BY public.user_feedback.id; --- --- Name: user_name_change_requests; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.user_name_change_requests ( - id integer NOT NULL, - user_id integer NOT NULL, - original_name character varying NOT NULL, - desired_name character varying NOT NULL, - created_at timestamp without time zone NOT NULL, - updated_at timestamp without time zone NOT NULL -); - - -- -- Name: user_name_change_requests_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- @@ -2202,23 +2462,6 @@ CREATE SEQUENCE public.user_sessions_id_seq ALTER SEQUENCE public.user_sessions_id_seq OWNED BY public.user_sessions.id; --- --- Name: user_upgrades; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.user_upgrades ( - id integer NOT NULL, - created_at timestamp(6) without time zone NOT NULL, - updated_at timestamp(6) without time zone NOT NULL, - recipient_id integer NOT NULL, - purchaser_id integer NOT NULL, - upgrade_type integer NOT NULL, - status integer NOT NULL, - transaction_id character varying, - payment_processor integer DEFAULT 0 NOT NULL -); - - -- -- Name: user_upgrades_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- @@ -3242,6 +3485,13 @@ CREATE INDEX index_artist_commentary_versions_on_created_at ON public.artist_com CREATE INDEX index_artist_commentary_versions_on_post_id ON public.artist_commentary_versions USING btree (post_id); +-- +-- Name: index_artist_commentary_versions_on_updater_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_artist_commentary_versions_on_updater_id_and_created_at ON public.artist_commentary_versions USING btree (updater_id, created_at); + + -- -- Name: index_artist_commentary_versions_on_updater_id_and_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -3326,6 +3576,13 @@ CREATE INDEX index_artist_versions_on_name ON public.artist_versions USING btree CREATE INDEX index_artist_versions_on_updater_id ON public.artist_versions USING btree (updater_id); +-- +-- Name: index_artist_versions_on_updater_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_artist_versions_on_updater_id_and_created_at ON public.artist_versions USING btree (updater_id, created_at); + + -- -- Name: index_artist_versions_on_updater_ip_addr; Type: INDEX; Schema: public; Owner: - -- @@ -3396,6 +3653,13 @@ CREATE INDEX index_artists_on_other_names ON public.artists USING gin (other_nam CREATE INDEX index_bans_on_banner_id ON public.bans USING btree (banner_id); +-- +-- Name: index_bans_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_bans_on_created_at ON public.bans USING btree (created_at); + + -- -- Name: index_bans_on_duration; Type: INDEX; Schema: public; Owner: - -- @@ -3410,6 +3674,20 @@ CREATE INDEX index_bans_on_duration ON public.bans USING btree (duration); CREATE INDEX index_bans_on_user_id ON public.bans USING btree (user_id); +-- +-- Name: index_bans_on_user_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_bans_on_user_id_and_created_at ON public.bans USING btree (user_id, created_at); + + +-- +-- Name: index_bulk_update_requests_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_bulk_update_requests_on_created_at ON public.bulk_update_requests USING btree (created_at); + + -- -- Name: index_bulk_update_requests_on_forum_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -3424,6 +3702,13 @@ CREATE INDEX index_bulk_update_requests_on_forum_post_id ON public.bulk_update_r CREATE INDEX index_bulk_update_requests_on_tags ON public.bulk_update_requests USING gin (tags); +-- +-- Name: index_bulk_update_requests_on_user_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_bulk_update_requests_on_user_id_and_created_at ON public.bulk_update_requests USING btree (user_id, created_at); + + -- -- Name: index_comment_votes_on_comment_id; Type: INDEX; Schema: public; Owner: - -- @@ -3459,6 +3744,13 @@ CREATE INDEX index_comment_votes_on_user_id ON public.comment_votes USING btree CREATE UNIQUE INDEX index_comment_votes_on_user_id_and_comment_id ON public.comment_votes USING btree (user_id, comment_id) WHERE (is_deleted = false); +-- +-- Name: index_comment_votes_on_user_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_comment_votes_on_user_id_and_created_at ON public.comment_votes USING btree (user_id, created_at); + + -- -- Name: index_comments_on_body_tsvector; Type: INDEX; Schema: public; Owner: - -- @@ -3473,6 +3765,13 @@ CREATE INDEX index_comments_on_body_tsvector ON public.comments USING gin (to_ts CREATE INDEX index_comments_on_created_at ON public.comments USING btree (created_at); +-- +-- Name: index_comments_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_comments_on_creator_id_and_created_at ON public.comments USING btree (creator_id, created_at); + + -- -- Name: index_comments_on_creator_id_and_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -3494,6 +3793,20 @@ CREATE INDEX index_comments_on_creator_ip_addr ON public.comments USING btree (c CREATE INDEX index_comments_on_post_id ON public.comments USING btree (post_id); +-- +-- Name: index_completed_user_upgrades_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_completed_user_upgrades_on_created_at ON public.user_upgrades USING btree (created_at) WHERE (status = ANY (ARRAY[20, 30])); + + +-- +-- Name: index_completed_user_upgrades_on_updater_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_completed_user_upgrades_on_updater_id_and_created_at ON public.user_upgrades USING btree (purchaser_id, created_at) WHERE (status = ANY (ARRAY[20, 30])); + + -- -- Name: index_dmails_on_created_at; Type: INDEX; Schema: public; Owner: - -- @@ -3599,6 +3912,20 @@ CREATE INDEX index_email_addresses_on_normalized_address_trgm ON public.email_ad CREATE UNIQUE INDEX index_email_addresses_on_user_id ON public.email_addresses USING btree (user_id); +-- +-- Name: index_favorite_groups_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_favorite_groups_on_created_at ON public.favorite_groups USING btree (created_at); + + +-- +-- Name: index_favorite_groups_on_created_at_id_is_public_creator_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_favorite_groups_on_created_at_id_is_public_creator_id ON public.favorite_groups USING btree (created_at, id, is_public, creator_id); + + -- -- Name: index_favorite_groups_on_creator_id; Type: INDEX; Schema: public; Owner: - -- @@ -3648,6 +3975,20 @@ CREATE INDEX index_favorites_on_user_id_and_id ON public.favorites USING btree ( CREATE UNIQUE INDEX index_favorites_on_user_id_and_post_id ON public.favorites USING btree (user_id, post_id); +-- +-- Name: index_forum_post_votes_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_forum_post_votes_on_created_at ON public.forum_post_votes USING btree (created_at); + + +-- +-- Name: index_forum_post_votes_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_forum_post_votes_on_creator_id_and_created_at ON public.forum_post_votes USING btree (creator_id, created_at); + + -- -- Name: index_forum_post_votes_on_forum_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -3669,6 +4010,13 @@ CREATE UNIQUE INDEX index_forum_post_votes_on_forum_post_id_and_creator_id ON pu CREATE INDEX index_forum_posts_on_body_tsvector ON public.forum_posts USING gin (to_tsvector('english'::regconfig, body)); +-- +-- Name: index_forum_posts_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_forum_posts_on_created_at ON public.forum_posts USING btree (created_at); + + -- -- Name: index_forum_posts_on_creator_id; Type: INDEX; Schema: public; Owner: - -- @@ -3676,6 +4024,13 @@ CREATE INDEX index_forum_posts_on_body_tsvector ON public.forum_posts USING gin CREATE INDEX index_forum_posts_on_creator_id ON public.forum_posts USING btree (creator_id); +-- +-- Name: index_forum_posts_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_forum_posts_on_creator_id_and_created_at ON public.forum_posts USING btree (creator_id, created_at); + + -- -- Name: index_forum_posts_on_topic_id; Type: INDEX; Schema: public; Owner: - -- @@ -3683,6 +4038,13 @@ CREATE INDEX index_forum_posts_on_creator_id ON public.forum_posts USING btree ( CREATE INDEX index_forum_posts_on_topic_id ON public.forum_posts USING btree (topic_id); +-- +-- Name: index_forum_posts_on_topic_id_and_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_forum_posts_on_topic_id_and_id ON public.forum_posts USING btree (topic_id, id); + + -- -- Name: index_forum_posts_on_updated_at; Type: INDEX; Schema: public; Owner: - -- @@ -3711,6 +4073,13 @@ CREATE INDEX index_forum_topic_visits_on_last_read_at ON public.forum_topic_visi CREATE INDEX index_forum_topic_visits_on_user_id ON public.forum_topic_visits USING btree (user_id); +-- +-- Name: index_forum_topics_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_forum_topics_on_created_at ON public.forum_topics USING btree (created_at); + + -- -- Name: index_forum_topics_on_creator_id; Type: INDEX; Schema: public; Owner: - -- @@ -3718,6 +4087,13 @@ CREATE INDEX index_forum_topic_visits_on_user_id ON public.forum_topic_visits US CREATE INDEX index_forum_topics_on_creator_id ON public.forum_topics USING btree (creator_id); +-- +-- Name: index_forum_topics_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_forum_topics_on_creator_id_and_created_at ON public.forum_topics USING btree (creator_id, created_at); + + -- -- Name: index_forum_topics_on_is_sticky_and_updated_at; Type: INDEX; Schema: public; Owner: - -- @@ -4033,6 +4409,20 @@ CREATE INDEX index_mod_actions_on_created_at ON public.mod_actions USING btree ( CREATE INDEX index_mod_actions_on_creator_id ON public.mod_actions USING btree (creator_id); +-- +-- Name: index_mod_actions_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_mod_actions_on_creator_id_and_created_at ON public.mod_actions USING btree (creator_id, created_at); + + +-- +-- Name: index_moderation_reports_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_moderation_reports_on_created_at ON public.moderation_reports USING btree (created_at); + + -- -- Name: index_moderation_reports_on_creator_id; Type: INDEX; Schema: public; Owner: - -- @@ -4040,6 +4430,13 @@ CREATE INDEX index_mod_actions_on_creator_id ON public.mod_actions USING btree ( CREATE INDEX index_moderation_reports_on_creator_id ON public.moderation_reports USING btree (creator_id); +-- +-- Name: index_moderation_reports_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_moderation_reports_on_creator_id_and_created_at ON public.moderation_reports USING btree (creator_id, created_at); + + -- -- Name: index_moderation_reports_on_model_type_and_model_id; Type: INDEX; Schema: public; Owner: - -- @@ -4082,6 +4479,13 @@ CREATE INDEX index_note_versions_on_note_id ON public.note_versions USING btree CREATE INDEX index_note_versions_on_post_id ON public.note_versions USING btree (post_id); +-- +-- Name: index_note_versions_on_updater_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_note_versions_on_updater_id_and_created_at ON public.note_versions USING btree (updater_id, created_at); + + -- -- Name: index_note_versions_on_updater_id_and_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -4243,6 +4647,13 @@ CREATE INDEX index_post_appeals_on_created_at ON public.post_appeals USING btree CREATE INDEX index_post_appeals_on_creator_id ON public.post_appeals USING btree (creator_id); +-- +-- Name: index_post_appeals_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_post_appeals_on_creator_id_and_created_at ON public.post_appeals USING btree (creator_id, created_at); + + -- -- Name: index_post_appeals_on_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -4264,6 +4675,13 @@ CREATE INDEX index_post_appeals_on_reason_tsvector ON public.post_appeals USING CREATE INDEX index_post_appeals_on_status ON public.post_appeals USING btree (status); +-- +-- Name: index_post_approvals_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_post_approvals_on_created_at ON public.post_approvals USING btree (created_at); + + -- -- Name: index_post_approvals_on_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -4278,6 +4696,20 @@ CREATE INDEX index_post_approvals_on_post_id ON public.post_approvals USING btre CREATE INDEX index_post_approvals_on_user_id ON public.post_approvals USING btree (user_id); +-- +-- Name: index_post_approvals_on_user_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_post_approvals_on_user_id_and_created_at ON public.post_approvals USING btree (user_id, created_at); + + +-- +-- Name: index_post_disapprovals_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_post_disapprovals_on_created_at ON public.post_disapprovals USING btree (created_at); + + -- -- Name: index_post_disapprovals_on_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -4292,6 +4724,13 @@ CREATE INDEX index_post_disapprovals_on_post_id ON public.post_disapprovals USIN CREATE INDEX index_post_disapprovals_on_user_id ON public.post_disapprovals USING btree (user_id); +-- +-- Name: index_post_disapprovals_on_user_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_post_disapprovals_on_user_id_and_created_at ON public.post_disapprovals USING btree (user_id, created_at); + + -- -- Name: index_post_disapprovals_on_user_id_and_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -4299,6 +4738,13 @@ CREATE INDEX index_post_disapprovals_on_user_id ON public.post_disapprovals USIN CREATE UNIQUE INDEX index_post_disapprovals_on_user_id_and_post_id ON public.post_disapprovals USING btree (user_id, post_id); +-- +-- Name: index_post_flags_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_post_flags_on_created_at ON public.post_flags USING btree (created_at); + + -- -- Name: index_post_flags_on_creator_id; Type: INDEX; Schema: public; Owner: - -- @@ -4306,6 +4752,13 @@ CREATE UNIQUE INDEX index_post_disapprovals_on_user_id_and_post_id ON public.pos CREATE INDEX index_post_flags_on_creator_id ON public.post_flags USING btree (creator_id); +-- +-- Name: index_post_flags_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_post_flags_on_creator_id_and_created_at ON public.post_flags USING btree (creator_id, created_at); + + -- -- Name: index_post_flags_on_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -4327,6 +4780,13 @@ CREATE INDEX index_post_flags_on_reason_tsvector ON public.post_flags USING gin CREATE INDEX index_post_flags_on_status ON public.post_flags USING btree (status); +-- +-- Name: index_post_replacements_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_post_replacements_on_created_at ON public.post_replacements USING btree (created_at); + + -- -- Name: index_post_replacements_on_creator_id; Type: INDEX; Schema: public; Owner: - -- @@ -4334,6 +4794,13 @@ CREATE INDEX index_post_flags_on_status ON public.post_flags USING btree (status CREATE INDEX index_post_replacements_on_creator_id ON public.post_replacements USING btree (creator_id); +-- +-- Name: index_post_replacements_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_post_replacements_on_creator_id_and_created_at ON public.post_replacements USING btree (creator_id, created_at); + + -- -- Name: index_post_replacements_on_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -4439,6 +4906,13 @@ CREATE INDEX index_post_votes_on_post_id ON public.post_votes USING btree (post_ CREATE INDEX index_post_votes_on_user_id ON public.post_votes USING btree (user_id); +-- +-- Name: index_post_votes_on_user_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_post_votes_on_user_id_and_created_at ON public.post_votes USING btree (user_id, created_at); + + -- -- Name: index_post_votes_on_user_id_and_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -4573,6 +5047,13 @@ ALTER INDEX public.index_posts_on_string_to_array_tag_string ALTER COLUMN 1 SET CREATE INDEX index_posts_on_uploader_id ON public.posts USING btree (uploader_id) WHERE (uploader_id IS NOT NULL); +-- +-- Name: index_posts_on_uploader_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_posts_on_uploader_id_and_created_at ON public.posts USING btree (uploader_id, created_at); + + -- -- Name: index_posts_on_uploader_ip_addr; Type: INDEX; Schema: public; Owner: - -- @@ -4587,6 +5068,13 @@ CREATE INDEX index_posts_on_uploader_ip_addr ON public.posts USING btree (upload CREATE UNIQUE INDEX index_rate_limits_on_key_and_action ON public.rate_limits USING btree (key, action); +-- +-- Name: index_saved_searches_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_saved_searches_on_created_at ON public.saved_searches USING btree (created_at); + + -- -- Name: index_saved_searches_on_labels; Type: INDEX; Schema: public; Owner: - -- @@ -4608,6 +5096,27 @@ CREATE INDEX index_saved_searches_on_query ON public.saved_searches USING btree CREATE INDEX index_saved_searches_on_user_id ON public.saved_searches USING btree (user_id); +-- +-- Name: index_saved_searches_on_user_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_saved_searches_on_user_id_and_created_at ON public.saved_searches USING btree (user_id, created_at); + + +-- +-- Name: index_sent_dmails_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_sent_dmails_on_created_at ON public.dmails USING btree (created_at) WHERE (owner_id = from_id); + + +-- +-- Name: index_sent_dmails_on_owner_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_sent_dmails_on_owner_id_and_created_at ON public.dmails USING btree (owner_id, created_at) WHERE (owner_id = from_id); + + -- -- Name: index_tag_aliases_on_antecedent_name; Type: INDEX; Schema: public; Owner: - -- @@ -4629,6 +5138,20 @@ CREATE INDEX index_tag_aliases_on_antecedent_name_pattern ON public.tag_aliases CREATE INDEX index_tag_aliases_on_consequent_name ON public.tag_aliases USING btree (consequent_name); +-- +-- Name: index_tag_aliases_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_tag_aliases_on_created_at ON public.tag_aliases USING btree (created_at); + + +-- +-- Name: index_tag_aliases_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_tag_aliases_on_creator_id_and_created_at ON public.tag_aliases USING btree (creator_id, created_at); + + -- -- Name: index_tag_aliases_on_forum_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -4650,6 +5173,20 @@ CREATE INDEX index_tag_implications_on_antecedent_name ON public.tag_implication CREATE INDEX index_tag_implications_on_consequent_name ON public.tag_implications USING btree (consequent_name); +-- +-- Name: index_tag_implications_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_tag_implications_on_created_at ON public.tag_implications USING btree (created_at); + + +-- +-- Name: index_tag_implications_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_tag_implications_on_creator_id_and_created_at ON public.tag_implications USING btree (creator_id, created_at); + + -- -- Name: index_tag_implications_on_forum_post_id; Type: INDEX; Schema: public; Owner: - -- @@ -4664,6 +5201,13 @@ CREATE INDEX index_tag_implications_on_forum_post_id ON public.tag_implications CREATE INDEX index_tag_versions_on_category ON public.tag_versions USING btree (category); +-- +-- Name: index_tag_versions_on_created_at_where_updater_id_is_not_null; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_tag_versions_on_created_at_where_updater_id_is_not_null ON public.tag_versions USING btree (created_at) WHERE (updater_id IS NOT NULL); + + -- -- Name: index_tag_versions_on_is_deprecated; Type: INDEX; Schema: public; Owner: - -- @@ -4713,6 +5257,13 @@ CREATE UNIQUE INDEX index_tag_versions_on_tag_id_and_previous_version_id ON publ CREATE INDEX index_tag_versions_on_updater_id ON public.tag_versions USING btree (updater_id); +-- +-- Name: index_tag_versions_on_updater_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_tag_versions_on_updater_id_and_created_at ON public.tag_versions USING btree (updater_id, created_at) WHERE (updater_id IS NOT NULL); + + -- -- Name: index_tag_versions_on_version; Type: INDEX; Schema: public; Owner: - -- @@ -4832,6 +5383,13 @@ CREATE INDEX index_upload_media_assets_on_status ON public.upload_media_assets U CREATE INDEX index_upload_media_assets_on_upload_id ON public.upload_media_assets USING btree (upload_id); +-- +-- Name: index_uploads_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_uploads_on_created_at ON public.uploads USING btree (created_at); + + -- -- Name: index_uploads_on_error; Type: INDEX; Schema: public; Owner: - -- @@ -4867,6 +5425,13 @@ CREATE INDEX index_uploads_on_source ON public.uploads USING btree (source); CREATE INDEX index_uploads_on_uploader_id ON public.uploads USING btree (uploader_id); +-- +-- Name: index_uploads_on_uploader_id_and_created_at_and_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_uploads_on_uploader_id_and_created_at_and_id ON public.uploads USING btree (uploader_id, created_at, id); + + -- -- Name: index_uploads_on_uploader_ip_addr; Type: INDEX; Schema: public; Owner: - -- @@ -4902,6 +5467,13 @@ CREATE INDEX index_user_events_on_updated_at ON public.user_events USING btree ( CREATE INDEX index_user_events_on_user_id ON public.user_events USING btree (user_id); +-- +-- Name: index_user_events_on_user_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_user_events_on_user_id_and_created_at ON public.user_events USING btree (user_id, created_at); + + -- -- Name: index_user_events_on_user_session_id; Type: INDEX; Schema: public; Owner: - -- @@ -4923,6 +5495,13 @@ CREATE INDEX index_user_feedback_on_created_at ON public.user_feedback USING btr CREATE INDEX index_user_feedback_on_creator_id ON public.user_feedback USING btree (creator_id); +-- +-- Name: index_user_feedback_on_creator_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_user_feedback_on_creator_id_and_created_at ON public.user_feedback USING btree (creator_id, created_at); + + -- -- Name: index_user_feedback_on_user_id; Type: INDEX; Schema: public; Owner: - -- @@ -4930,6 +5509,20 @@ CREATE INDEX index_user_feedback_on_creator_id ON public.user_feedback USING btr CREATE INDEX index_user_feedback_on_user_id ON public.user_feedback USING btree (user_id); +-- +-- Name: index_user_feedback_on_user_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_user_feedback_on_user_id_and_created_at ON public.user_feedback USING btree (user_id, created_at); + + +-- +-- Name: index_user_name_change_requests_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_user_name_change_requests_on_created_at ON public.user_name_change_requests USING btree (created_at); + + -- -- Name: index_user_name_change_requests_on_original_name; Type: INDEX; Schema: public; Owner: - -- @@ -4944,6 +5537,13 @@ CREATE INDEX index_user_name_change_requests_on_original_name ON public.user_nam CREATE INDEX index_user_name_change_requests_on_user_id ON public.user_name_change_requests USING btree (user_id); +-- +-- Name: index_user_name_change_requests_on_user_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_user_name_change_requests_on_user_id_and_created_at ON public.user_name_change_requests USING btree (user_id, created_at); + + -- -- Name: index_user_sessions_on_created_at; Type: INDEX; Schema: public; Owner: - -- @@ -4972,6 +5572,13 @@ CREATE INDEX index_user_sessions_on_session_id ON public.user_sessions USING btr CREATE INDEX index_user_sessions_on_updated_at ON public.user_sessions USING btree (updated_at); +-- +-- Name: index_user_upgrades_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_user_upgrades_on_created_at ON public.user_upgrades USING btree (created_at); + + -- -- Name: index_user_upgrades_on_payment_processor; Type: INDEX; Schema: public; Owner: - -- @@ -5021,6 +5628,20 @@ CREATE INDEX index_user_upgrades_on_upgrade_type ON public.user_upgrades USING b CREATE INDEX index_users_on_created_at ON public.users USING btree (created_at); +-- +-- Name: index_users_on_enable_private_favorites; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_users_on_enable_private_favorites ON public.users USING btree (bit_prefs) WHERE (get_bit((bit_prefs)::bit(31), 24) = 1); + + +-- +-- Name: index_users_on_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_users_on_id_and_created_at ON public.users USING btree (id, created_at); + + -- -- Name: index_users_on_inviter_id; Type: INDEX; Schema: public; Owner: - -- @@ -5063,6 +5684,13 @@ CREATE INDEX index_wiki_page_versions_on_created_at ON public.wiki_page_versions CREATE INDEX index_wiki_page_versions_on_updater_id ON public.wiki_page_versions USING btree (updater_id); +-- +-- Name: index_wiki_page_versions_on_updater_id_and_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_wiki_page_versions_on_updater_id_and_created_at ON public.wiki_page_versions USING btree (updater_id, created_at); + + -- -- Name: index_wiki_page_versions_on_updater_ip_addr; Type: INDEX; Schema: public; Owner: - -- @@ -6126,6 +6754,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20220829184824'), ('20220909205433'), ('20220909211649'), -('20220913191300'); +('20220913191300'), +('20220913191309'); diff --git a/db/views/user_actions_v01.sql b/db/views/user_actions_v01.sql new file mode 100644 index 000000000..8cc205a3e --- /dev/null +++ b/db/views/user_actions_v01.sql @@ -0,0 +1,105 @@ + SELECT 'ArtistVersion'::character varying AS model_type, id AS model_id, updater_id AS user_id, 'create'::character varying AS event_type, created_at AS event_at + FROM artist_versions +UNION ALL + SELECT 'ArtistCommentaryVersion', id, updater_id, 'create', created_at + FROM artist_commentary_versions +UNION ALL + SELECT 'Ban', id, user_id, 'subject', created_at + FROM bans +UNION ALL + SELECT 'BulkUpdateRequest', id, user_id, 'create', created_at + FROM bulk_update_requests +UNION ALL + SELECT 'Comment', id, creator_id, 'create', created_at + FROM comments +UNION ALL + SELECT 'CommentVote', id, user_id, 'create', created_at + FROM comment_votes +UNION ALL ( + SELECT 'Dmail', id, from_id, 'create', created_at + FROM dmails + WHERE from_id != owner_id + ORDER BY created_at DESC +) +UNION ALL + SELECT 'FavoriteGroup', id, creator_id, 'create', created_at + FROM favorite_groups +UNION ALL + SELECT 'ForumPost', id, creator_id, 'create', created_at + FROM forum_posts +UNION ALL + SELECT 'ForumPostVote', id, creator_id, 'create', created_at + FROM forum_post_votes +UNION ALL + SELECT 'ForumTopic', id, creator_id, 'create', created_at + FROM forum_topics +UNION ALL + SELECT 'ModAction', id, creator_id, 'create', created_at + FROM mod_actions +UNION ALL + SELECT 'ModerationReport', id, creator_id, 'create', created_at + FROM moderation_reports +UNION ALL + SELECT 'NoteVersion', id, updater_id, 'create', created_at + FROM note_versions +UNION ALL + SELECT 'Post', id, uploader_id, 'create', created_at + FROM posts +UNION ALL + SELECT 'PostAppeal', id, creator_id, 'create', created_at + FROM post_appeals +UNION ALL + SELECT 'PostApproval', id, user_id, 'create', created_at + FROM post_approvals +UNION ALL + SELECT 'PostDisapproval', id, user_id, 'create', created_at + FROM post_disapprovals +UNION ALL + SELECT 'PostFlag', id, creator_id, 'create', created_at + FROM post_flags +UNION ALL + SELECT 'PostReplacement', id, creator_id, 'create', created_at + FROM post_replacements +UNION ALL + SELECT 'PostVote', id, user_id, 'create', created_at + FROM post_votes +UNION ALL + SELECT 'SavedSearch', id, user_id, 'create', created_at + FROM saved_searches +UNION ALL + SELECT 'TagAlias', id, creator_id, 'create', created_at + FROM tag_aliases +UNION ALL + SELECT 'TagImplication', id, creator_id, 'create', created_at + FROM tag_implications +UNION ALL ( + SELECT 'TagVersion', id, updater_id, 'create', created_at + FROM tag_versions + WHERE updater_id IS NOT NULL + ORDER BY created_at DESC +) UNION ALL + SELECT 'Upload', id, uploader_id, 'create', created_at + FROM uploads +UNION ALL + SELECT 'User', id, id, 'create', created_at + FROM users +UNION ALL + SELECT 'UserEvent', id, user_id, 'create', created_at + FROM user_events +UNION ALL + SELECT 'UserFeedback', id, creator_id, 'create', created_at + FROM user_feedback +UNION ALL + SELECT 'UserFeedback', id, user_id, 'subject', created_at + FROM user_feedback +UNION ALL ( + SELECT 'UserUpgrade', id, purchaser_id, 'create', created_at + FROM user_upgrades + WHERE status IN (20, 30) + ORDER BY created_at DESC +) UNION ALL + SELECT 'UserNameChangeRequest', id, user_id, 'create', created_at + FROM user_name_change_requests +UNION ALL + SELECT 'WikiPageVersion', id, updater_id, 'create', created_at + FROM wiki_page_versions