老專案重構手記之使用者系統

CrazyCodes發表於2019-02-16

受邀來一起重構公司的老專案

概述

重構首先要注意幾個點

  • 重構後功能的可擴充套件性
  • 業務互相依賴的複雜度
  • 脫離本身的業務進行重構
  • 重構後的程式碼可讀性與可維護性
  • 效能的提升

以上幾點是重構注意的地方也是重構的目的

分析

本次重構的專案運營了三年之久,使用者及業務量也上不來。至於重構的真正原因不清楚。

  • 使用者註冊量:107470
  • 日PV:1000+

非常的慘淡

  1. 關於使用者ID與其他業務繫結僅僅是單純的儲存使用者ID進行繫結,類似與評論,購買等。這樣在重新設計使用者表的時候無需考慮其他表的業務是否有衝突或者依賴。
  2. 前期設計上貌似介面及資料表欄位設定問題,出現了資料重複的問題。
  3. 功能重新寫好後,在資料遷移方便,當然沒法人工操作,php指令碼去遷移也不現實,考慮使用資料佇列等等方式進行資料遷移
  4. 功能程式碼絕筆是另起爐灶寫,在原程式上寫複雜度有提升了一倍。

原資料表結構

部分欄位

欄位名 型別 是否為空 預設值 註釋
MemberId bigint(20) Y 自增編碼
MemberPhone varchar(255) N 手機號碼
LoginTime int(11) Y NULL 登入時間
QuitTime int(11) Y NULL 退出時間
LoginState tinyint(2) Y NULL 登入狀態
MemberState tinyint(2) N 0 賬號狀態
MemberExpert tinyint(2) N 0
MemberRegTime int(11) Y NULL 註冊時間
DeviceToken varchar(255) Y NULL 裝置標示
WxToken char(32) Y NULL 微信標示

問題點有以下幾個

  1. 資料欄位設計時不應使用駝峰命名,應使用小寫,單獨分割用_ ,例如 member_tel , 索引的設定也存在一些問題
  2. 欄位儘量避免DEFAULT NULL
  3. 根據需求分表,現在所有的第三方授權都放到一個表裡了

選型

前期重構要求速度要快。所以只能選擇世界上最好的語言。

  • 語言:PHP
  • 框架:Laravel
  • 資料庫:MySQL

考慮到資料量也不小,手動操作是不可能了,選擇使用RabbitMQ進行資料遷移

新表設計

使用者表

CREATE TABLE `member` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `tel` bigint(20) DEFAULT NULL COMMENT `手機號碼`,
  `password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT `登入密碼`,
  `status` tinyint(4) NOT NULL DEFAULT `0` COMMENT `賬號狀態 0:正常`,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `member_tel_unique` (`tel`),
  KEY `member_tel_status_index` (`tel`,`status`)
) ENGINE=InnoDB AUTO_INCREMENT=80073 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

使用者授權表

CREATE TABLE `member_authorized` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `member_id` bigint(20) NOT NULL COMMENT `使用者編碼`,
  `prefix` varchar(25) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT `第三方名稱`,
  `token` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT `第三方標示`,
  `data` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT `授權獲得的使用者資訊`,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `member_authorized_prefix_index` (`prefix`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

使用者資訊表

CREATE TABLE `member_data` (
  `member_id` bigint(20) NOT NULL COMMENT `使用者編碼`,
  `sex` enum(`0`,`1`,`2`) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT `性別 0=>女生 1=>男生 2=>未知`,
  `nick_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT `姓名/暱稱`,
  `img` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT `使用者頭像`,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  UNIQUE KEY `member_data_member_id_unique` (`member_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

佇列

通過佇列,可以選擇laravel內建的佇列或者rabbitmq都可以。將資料遷移到新表中。當然你需要選擇一個訪問量最低的時間段。並不是凌晨就少,不同的行業的活躍時間段不一樣。建議先使用百度統計、騰訊分析等等的檢視活躍時間區間。

迭代

重構並不是一言一語,幾行程式碼或者一個大佬的方案就可以解決的。實際重構也是一個開發的過程。在不斷的迭代中,將重構完成的部分補回到業務中。

致謝

感謝你看到這裡,希望本篇文章可以幫到你。有問題可在評論區留言。

相關文章