Py学习  »  DATABASE

mysql优化算法,保存历史更改的变体

Tony Soprano • 6 年前 • 1910 次点击  

我有一个主表,上面有实际的用户信息

CREATE TABLE user
(
  id                            bigint                              NOT NULL
    PRIMARY KEY,
  updated                       timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  username                      varchar(40)                         NULL,
  full_name                     varchar(255)                        NULL,
  biography                     varchar(512)                        NULL,
  profile_pic_id                varchar(40)                         NULL,
  profile_pic_url               varchar(255)                        NULL,
  hd_profile_pic_url            varchar(255)                        NULL,
  follower_count                int                                 NULL,
  following_count               int                                 NULL,
  media_count                   int                                 NULL,
  usertags_count                int                                 NULL,
  following_tag_count           int                                 NULL,
  external_url                  longtext                            NULL,
  reel_auto_archive             varchar(255)                        NULL,
  has_biography_translation     tinyint(1)                          NULL,
  has_anonymous_profile_picture tinyint(1)                          NULL,
  has_highlight_reels           tinyint(1)                          NULL,
  is_business                   tinyint(1)                          NULL,
  is_active                     tinyint(1)                          NULL,
  is_verified                   tinyint(1)                          NULL,
  is_private                    tinyint(1)                          NULL,
  is_blocked                    tinyint(1)                          NULL
)

保存历史记录的表也几乎相同:

CREATE TABLE user_history
(
  id                            int AUTO_INCREMENT
    PRIMARY KEY,
  user_id                  bigint                              NULL,
  added                         timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
  username                      varchar(40)                         NULL,
  full_name                     varchar(255)                        NULL,
  biography                     varchar(512)                        NULL,
  profile_pic_id                varchar(40)                         NULL,
  profile_pic_url               varchar(255)                        NULL,
  hd_profile_pic_url            varchar(255)                        NULL,
  follower_count                int                                 NULL,
  following_count               int                                 NULL,
  media_count                   int                                 NULL,
  usertags_count                int                                 NULL,
  following_tag_count           int                                 NULL,
  external_url                  longtext                            NULL,
  reel_auto_archive             varchar(255)                        NULL,
  has_biography_translation     tinyint(1)                          NULL,
  has_anonymous_profile_picture tinyint(1)                          NULL,
  has_highlight_reels           tinyint(1)                          NULL,
  is_business                   tinyint(1)                          NULL,
  is_active                     tinyint(1)                          NULL,
  is_verified                   tinyint(1)                          NULL,
  is_private                    tinyint(1)                          NULL,
  is_blocked                    tinyint(1)                          NULL,
  CONSTRAINT FK_F19A7E3C5AFE2D44
    FOREIGN KEY (user_id) REFERENCES user (id)
)
  COLLATE = utf8mb4_unicode_ci;

CREATE INDEX IDX_F19A7E3C5AFE2D44
  ON user_history (user_id);

拯救历史的跳跳虎:

CREATE TRIGGER user_update
  AFTER UPDATE
  ON user
  FOR EACH ROW
BEGIN
  INSERT INTO `user_history` (`user_id`, `username`, `full_name`, `biography`, `profile_pic_id`,
                                   `profile_pic_url`, `hd_profile_pic_url`, `follower_count`, `following_count`,
                                   `media_count`, `usertags_count`, `following_tag_count`, `external_url`,
                                   `reel_auto_archive`, `has_biography_translation`, `has_anonymous_profile_picture`,
                                   `has_highlight_reels`, `is_business`, `is_active`, `is_verified`, `is_private`,
                                   `is_blocked`, `added`)
  VALUES (NEW.id, NEW.username, NEW.full_name, NEW.biography, NEW.profile_pic_id, NEW.profile_pic_url,
          NEW.hd_profile_pic_url,
          NEW.follower_count, NEW.following_count, NEW.media_count, NEW.usertags_count, NEW.following_tag_count,
          NEW.external_url,
          NEW.reel_auto_archive, NEW.has_biography_translation, NEW.has_anonymous_profile_picture,
          NEW.has_highlight_reels,
          NEW.is_business, NEW.is_active, NEW.is_verified, NEW.is_private, NEW.is_blocked, now());
END;

所以我有几个问题:

  1. 有没有提高书写速度以保存历史的变体? 我尝试通过加载数据局部填充,而不是触发-没有速度改善。

  2. 有没有用较少的数据保存历史的变体? 例如,我想我可以运行一些外部脚本,检查用户历史数据并为相同的值设置null? 我尝试使用另一个触发器来保存-更大,它在写入之前比较每个值,并且只写入更改的值-但是执行时间很长。 或者有更好的方法来将数据差异(重用)保存到数据库吗?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/46827
文章 [ 1 ]  |  最新文章 6 年前
Rick James
Reply   •   1 楼
Rick James    6 年前
  • 将计数器移到平行表。把它们分开也会加快 UPDATE 是的。“update”的内部处理涉及在其他连接访问同一行时生成整行的副本。
  • 另外,不要在上面记录历史。我想大部分的“更新”都在这方面。
  • 把所有的 has_% is_% 旗子打成一个 SET TINYINT UNSIGNED (最多8人,或 SMALLINT UNSIGNED 最多16个)。
  • 没有 has 标志—只需使用 LEFT JOIN EXISTS 当你需要检查“has”时。
  • 制造 标志(可能还有其他列) NOT NULL 是的。一般来说,你应该有意识地决定 NULL 对业务逻辑有意义,而不是简单地让所有列 NULLable 是的。

(我的建议适用于mysql和mariadb的所有版本。)