Add `actor` table and code to start using it
[lhc/web/wiklou.git] / maintenance / mssql / tables.sql
index 1d5abd0..5348c47 100644 (file)
@@ -54,6 +54,23 @@ CREATE INDEX /*i*/user_email ON /*_*/mwuser (user_email);
 -- Insert a dummy user to represent anons
 INSERT INTO /*_*/mwuser (user_name) VALUES ('##Anonymous##');
 
+--
+-- The "actor" table associates user names or IP addresses with integers for
+-- the benefit of other tables that need to refer to either logged-in or
+-- logged-out users. If something can only ever be done by logged-in users, it
+-- can refer to the user table directly.
+--
+CREATE TABLE /*_*/actor (
+  actor_id bigint unsigned NOT NULL CONSTRAINT PK_actor PRIMARY KEY IDENTITY(0,1),
+  actor_user int unsigned,
+  actor_name nvarchar(255) NOT NULL
+);
+CREATE UNIQUE INDEX /*i*/actor_user ON /*_*/actor (actor_user);
+CREATE UNIQUE INDEX /*i*/actor_name ON /*_*/actor (actor_name);
+
+-- Insert a dummy actor to represent no actor
+INSERT INTO /*_*/actor (actor_name) VALUES ('##Anonymous##');
+
 --
 -- User permissions have been broken out to a separate table;
 -- this allows sites with a shared user table to have different
@@ -117,6 +134,28 @@ CREATE TABLE /*_*/bot_passwords (
 );
 
 
+--
+-- Edits, blocks, and other actions typically have a textual comment describing
+-- the action. They are stored here to reduce the size of the main tables, and
+-- to allow for deduplication.
+--
+-- Deduplication is currently best-effort to avoid locking on inserts that
+-- would be required for strict deduplication. There MAY be multiple rows with
+-- the same comment_text and comment_data.
+--
+CREATE TABLE /*_*/comment (
+  comment_id bigint unsigned NOT NULL PRIMARY KEY IDENTITY(0,1),
+  comment_hash INT NOT NULL,
+  comment_text nvarchar(max) NOT NULL,
+  comment_data nvarchar(max)
+);
+-- Index used for deduplication.
+CREATE INDEX /*i*/comment_hash ON /*_*/comment (comment_hash);
+
+-- dummy row for FKs. Hash is intentionally wrong so CommentStore won't match it.
+INSERT INTO /*_*/comment (comment_hash, comment_text) VALUES (-1, '** dummy **');
+
+
 --
 -- Core of the wiki: each page has an entry here which identifies
 -- it by title and contains some essential metadata.
@@ -153,7 +192,7 @@ CREATE TABLE /*_*/revision (
    rev_id INT NOT NULL UNIQUE IDENTITY(0,1),
    rev_page INT NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
    rev_text_id INT  NOT NULL, -- FK added later
-   rev_comment NVARCHAR(255) NOT NULL,
+   rev_comment NVARCHAR(255) NOT NULL CONSTRAINT DF_rev_comment DEFAULT '',
    rev_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
    rev_user_text NVARCHAR(255) NOT NULL DEFAULT '',
    rev_timestamp varchar(14) NOT NULL default '',
@@ -177,6 +216,31 @@ INSERT INTO /*_*/revision (rev_page,rev_text_id,rev_comment,rev_user,rev_len) VA
 
 ALTER TABLE /*_*/page ADD CONSTRAINT FK_page_latest_page_id FOREIGN KEY (page_latest) REFERENCES /*_*/revision(rev_id);
 
+--
+-- Temporary tables to avoid blocking on an alter of revision.
+--
+-- On large wikis like the English Wikipedia, altering the revision table is a
+-- months-long process. This table is being created to avoid such an alter, and
+-- will be merged back into revision in the future.
+--
+CREATE TABLE /*_*/revision_comment_temp (
+  revcomment_rev INT NOT NULL CONSTRAINT FK_revcomment_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
+  revcomment_comment_id bigint unsigned NOT NULL CONSTRAINT FK_revcomment_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  CONSTRAINT PK_revision_comment_temp PRIMARY KEY (revcomment_rev, revcomment_comment_id)
+);
+CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
+
+CREATE TABLE /*_*/revision_actor_temp (
+  revactor_rev int unsigned NOT NULL CONSTRAINT FK_revactor_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
+  revactor_actor bigint unsigned NOT NULL,
+  revactor_timestamp varchar(14) NOT NULL CONSTRAINT DF_revactor_timestamp DEFAULT '',
+  revactor_page int unsigned NOT NULL,
+  CONSTRAINT PK_revision_actor_temp PRIMARY KEY (revactor_rev, revactor_actor)
+);
+CREATE UNIQUE INDEX /*i*/revactor_rev ON /*_*/revision_actor_temp (revactor_rev);
+CREATE INDEX /*i*/actor_timestamp ON /*_*/revision_actor_temp (revactor_actor,revactor_timestamp);
+CREATE INDEX /*i*/page_actor_timestamp ON /*_*/revision_actor_temp (revactor_page,revactor_actor,revactor_timestamp);
+
 --
 -- Holds TEXT of individual page revisions.
 --
@@ -207,9 +271,11 @@ CREATE TABLE /*_*/archive (
    ar_namespace SMALLINT NOT NULL DEFAULT 0,
    ar_title NVARCHAR(255) NOT NULL DEFAULT '',
    ar_text NVARCHAR(MAX) NOT NULL,
-   ar_comment NVARCHAR(255) NOT NULL,
+   ar_comment NVARCHAR(255) NOT NULL CONSTRAINT DF_ar_comment DEFAULT '',
+   ar_comment_id bigint unsigned NOT NULL CONSTRAINT DF_ar_comment_id DEFAULT 0 CONSTRAINT FK_ar_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
    ar_user INT CONSTRAINT ar_user__user_id__fk FOREIGN KEY REFERENCES /*_*/mwuser(user_id),
-   ar_user_text NVARCHAR(255) NOT NULL,
+   ar_user_text NVARCHAR(255) NOT NULL CONSTRAINT DF_ar_user_text DEFAULT '',
+   ar_actor bigint unsigned NOT NULL CONSTRAINT DF_ar_actor DEFAULT 0,
    ar_timestamp varchar(14) NOT NULL default '',
    ar_minor_edit BIT NOT NULL DEFAULT 0,
    ar_flags NVARCHAR(255) NOT NULL,
@@ -225,6 +291,7 @@ CREATE TABLE /*_*/archive (
 );
 CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp);
 CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp);
+CREATE INDEX /*i*/ar_actor_timestamp ON /*_*/archive (ar_actor,ar_timestamp);
 CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id);
 
 
@@ -563,11 +630,18 @@ CREATE TABLE /*_*/ipblocks (
   -- User ID who made the block.
   ipb_by int REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
 
+  -- Actor ID who made the block.
+  ipb_by_actor bigint unsigned NOT NULL CONSTRAINT DF_ipb_by_actor DEFAULT 0,
+
   -- User name of blocker
   ipb_by_text nvarchar(255) NOT NULL default '',
 
   -- Text comment made by blocker.
-  ipb_reason nvarchar(255) NOT NULL,
+  ipb_reason nvarchar(255) NOT NULL CONSTRAINT DF_ipb_reason DEFAULT '',
+
+  -- Key to comment_id. Text comment made by blocker.
+  -- ("DEFAULT 0" is temporary, signaling that ipb_reason should be used)
+  ipb_reason_id bigint unsigned NOT NULL CONSTRAINT DF_ipb_reason_id DEFAULT 0 CONSTRAINT FK_ipb_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
 
   -- Creation (or refresh) date in standard YMDHMS form.
   -- IP blocks expire automatically.
@@ -664,11 +738,12 @@ CREATE TABLE /*_*/image (
 
   -- Description field as entered by the uploader.
   -- This is displayed in image upload history and logs.
-  img_description nvarchar(255) NOT NULL,
+  img_description nvarchar(255) NOT NULL CONSTRAINT DF_img_description DEFAULT '',
 
   -- user_id and user_name of uploader.
   img_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
-  img_user_text nvarchar(255) NOT NULL,
+  img_user_text nvarchar(255) NOT NULL CONSTRAINT DF_img_user_text DEFAULT '',
+  img_actor bigint unsigned NOT NULL CONSTRAINT DF_img_actor DEFAULT 0,
 
   -- Time of the upload.
   img_timestamp nvarchar(14) NOT NULL default '',
@@ -681,6 +756,7 @@ CREATE TABLE /*_*/image (
 );
 
 CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);
+CREATE INDEX /*i*/img_actor_timestamp ON /*_*/image (img_actor, img_timestamp);
 -- Used by Special:ListFiles for sort-by-size
 CREATE INDEX /*i*/img_size ON /*_*/image (img_size);
 -- Used by Special:Newimages and Special:ListFiles
@@ -690,6 +766,20 @@ CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1);
 -- Used to get media of one type
 CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);
 
+--
+-- Temporary table to avoid blocking on an alter of image.
+--
+-- On large wikis like Wikimedia Commons, altering the image table is a
+-- months-long process. This table is being created to avoid such an alter, and
+-- will be merged back into image in the future.
+--
+CREATE TABLE /*_*/image_comment_temp (
+  imgcomment_name nvarchar(255) NOT NULL CONSTRAINT FK_imgcomment_name FOREIGN KEY REFERENCES /*_*/image(imgcomment_name) ON DELETE CASCADE,
+  imgcomment_description_id bigint unsigned NOT NULL CONSTRAINT FK_imgcomment_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  CONSTRAINT PK_image_comment_temp PRIMARY KEY (imgcomment_name, imgcomment_description_id)
+);
+CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
+
 
 --
 -- Previous revisions of uploaded files.
@@ -710,9 +800,11 @@ CREATE TABLE /*_*/oldimage (
   oi_width int NOT NULL default 0,
   oi_height int NOT NULL default 0,
   oi_bits int NOT NULL default 0,
-  oi_description nvarchar(255) NOT NULL,
+  oi_description nvarchar(255) NOT NULL CONSTRAINT DF_oi_description DEFAULT '',
+  oi_description_id bigint unsigned NOT NULL CONSTRAINT DF_oi_description_id DEFAULT 0 CONSTRAINT FK_oi_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   oi_user int REFERENCES /*_*/mwuser(user_id),
-  oi_user_text nvarchar(255) NOT NULL,
+  oi_user_text nvarchar(255) NOT NULL CONSTRAINT DF_oi_user_text DEFAULT '',
+  oi_actor bigint unsigned NOT NULL CONSTRAINT DF_oi_actor DEFAULT 0,
   oi_timestamp varchar(14) NOT NULL default '',
 
   oi_metadata varbinary(max) NOT NULL,
@@ -727,6 +819,7 @@ CREATE TABLE /*_*/oldimage (
 );
 
 CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp);
+CREATE INDEX /*i*/oi_actor_timestamp ON /*_*/oldimage (oi_actor,oi_timestamp);
 CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp);
 CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1);
 
@@ -759,7 +852,8 @@ CREATE TABLE /*_*/filearchive (
   -- Deletion information, if this file is deleted.
   fa_deleted_user int,
   fa_deleted_timestamp varchar(14) default '',
-  fa_deleted_reason nvarchar(max),
+  fa_deleted_reason nvarchar(max) CONSTRAINT DF_fa_deleted_reason DEFAULT '',
+  fa_deleted_reason_id bigint unsigned NOT NULL CONSTRAINT DF_fa_deleted_reason_id DEFAULT 0 CONSTRAINT FK_fa_deleted_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
 
   -- Duped fields from image
   fa_size int default 0,
@@ -770,9 +864,11 @@ CREATE TABLE /*_*/filearchive (
   fa_media_type varchar(16) default null,
   fa_major_mime varchar(16) not null default 'unknown',
   fa_minor_mime nvarchar(100) default 'unknown',
-  fa_description nvarchar(255),
+  fa_description nvarchar(255) CONSTRAINT DF_fa_description DEFAULT '',
+  fa_description_id bigint unsigned NOT NULL CONSTRAINT DF_fa_description DEFAULT 0 CONSTRAINT FK_fa_description FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   fa_user int default 0 REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
-  fa_user_text nvarchar(255),
+  fa_user_text nvarchar(255) CONSTRAINT DF_fa_user_text DEFAULT '',
+  fa_actor bigint unsigned NOT NULL CONSTRAINT DF_fa_actor DEFAULT 0,
   fa_timestamp varchar(14) default '',
 
   -- Visibility of deleted revisions, bitfield
@@ -793,6 +889,7 @@ CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_sto
 CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
 -- sort by uploader
 CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);
+CREATE INDEX /*i*/fa_actor_timestamp ON /*_*/filearchive (fa_actor,fa_timestamp);
 -- find file by sha1, 10 bytes will be enough for hashes to be indexed
 CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1);
 
@@ -865,7 +962,8 @@ CREATE TABLE /*_*/recentchanges (
 
   -- As in revision
   rc_user int NOT NULL default 0 CONSTRAINT rc_user__user_id__fk FOREIGN KEY REFERENCES /*_*/mwuser(user_id),
-  rc_user_text nvarchar(255) NOT NULL,
+  rc_user_text nvarchar(255) NOT NULL CONSTRAINT DF_rc_user_text DEFAULT '',
+  rc_actor bigint unsigned NOT NULL CONSTRAINT DF_rc_actor DEFAULT 0,
 
   -- When pages are renamed, their RC entries do _not_ change.
   rc_namespace int NOT NULL default 0,
@@ -873,6 +971,7 @@ CREATE TABLE /*_*/recentchanges (
 
   -- as in revision...
   rc_comment nvarchar(255) NOT NULL default '',
+  rc_comment_id bigint unsigned NOT NULL CONSTRAINT DF_rc_comment_id DEFAULT 0 CONSTRAINT FK_rc_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   rc_minor bit NOT NULL default 0,
 
   -- Edits by user accounts with the 'bot' rights key are
@@ -936,6 +1035,8 @@ CREATE INDEX /*i*/new_name_timestamp ON /*_*/recentchanges (rc_new,rc_namespace,
 CREATE INDEX /*i*/rc_ip ON /*_*/recentchanges (rc_ip);
 CREATE INDEX /*i*/rc_ns_usertext ON /*_*/recentchanges (rc_namespace, rc_user_text);
 CREATE INDEX /*i*/rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp);
+CREATE INDEX /*i*/rc_ns_actor ON /*_*/recentchanges (rc_namespace, rc_actor);
+CREATE INDEX /*i*/rc_actor ON /*_*/recentchanges (rc_actor, rc_timestamp);
 CREATE INDEX /*i*/rc_name_type_patrolled_timestamp ON /*_*/recentchanges (rc_namespace, rc_type, rc_patrolled, rc_timestamp);
 
 
@@ -1067,6 +1168,9 @@ CREATE TABLE /*_*/logging (
   -- Name of the user who performed this action
   log_user_text nvarchar(255) NOT NULL default '',
 
+  -- The actor who performed this action
+  log_actor bigint unsigned NOT NULL CONSTRAINT DF_log_actor DEFAULT 0,
+
   -- Key to the page affected. Where a user is the target,
   -- this will point to the user page.
   log_namespace int NOT NULL default 0,
@@ -1076,6 +1180,10 @@ CREATE TABLE /*_*/logging (
   -- Freeform text. Interpreted as edit history comments.
   log_comment nvarchar(255) NOT NULL default '',
 
+  -- Key to comment_id. Comment summarizing the change.
+  -- ("DEFAULT 0" is temporary, signaling that log_comment should be used)
+  log_comment_id bigint unsigned NOT NULL CONSTRAINT DF_log_comment_id DEFAULT 0 CONSTRAINT FK_log_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+
   -- miscellaneous parameters:
   -- LF separated list (old system) or serialized PHP array (new system)
   log_params nvarchar(max) NOT NULL,
@@ -1093,6 +1201,8 @@ CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp);
 CREATE INDEX /*i*/type_action ON /*_*/logging (log_type, log_action, log_timestamp);
 CREATE INDEX /*i*/log_user_text_type_time ON /*_*/logging (log_user_text, log_type, log_timestamp);
 CREATE INDEX /*i*/log_user_text_time ON /*_*/logging (log_user_text, log_timestamp);
+CREATE INDEX /*i*/actor_time ON /*_*/logging (log_actor, log_timestamp);
+CREATE INDEX /*i*/log_actor_type_time ON /*_*/logging (log_actor, log_type, log_timestamp);
 
 INSERT INTO /*_*/logging (log_user,log_page,log_params) VALUES(0,0,'');
 
@@ -1236,7 +1346,8 @@ CREATE TABLE /*_*/protected_titles (
   pt_namespace int NOT NULL,
   pt_title nvarchar(255) NOT NULL,
   pt_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
-  pt_reason nvarchar(255),
+  pt_reason nvarchar(255) CONSTRAINT DF_pt_reason DEFAULT '',
+  pt_reason_id bigint unsigned NOT NULL CONSTRAINT DF_pt_reason_id DEFAULT 0 CONSTRAINT FK_pt_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   pt_timestamp varchar(14) NOT NULL,
   pt_expiry varchar(14) NOT NULL,
   pt_create_perm nvarchar(60) NOT NULL