高性能可擴展mysql 筆記(二)用戶模型設計、用戶實體表結構設計、設計范式


個人博客網:https://wushaopei.github.io/    (你想要這里多有)

一、用戶模型設計

電商羡慕中用戶模型的設計涉及以下幾個部分:

                

以電商平台京東的登錄、注冊頁面作為例:

    

用戶的基本模塊涉及用戶的賬戶名、密碼、以及手機號碼、所在地等信息。

             

由個人后台信息截圖可知,用戶的實體信息其實很多,不僅僅是當前頁面所看到的,如下圖:

                

二、用戶實體屬性的CRUD操作的問題分析

1、當我們確定了需要保存用戶的屬性后,就需要考慮怎么將屬性存到表中了?同時還要考慮保存數據時的一些問題以及優劣性分析!

             

在將數據進行保存操作時會出現如下幾個問題:

1、數據插入異常

    PK : 用戶登錄名

    用戶表 :{登錄名 ... ... 會員級別,級別積分上限,級別積分下線}

    insert into 用戶表(會員級別)values(`青銅`);

2、數據更新異常

        要修改某一行的值時,不得不修改多行數據

      例:  用戶等級: 青銅級 —> 注冊會員

               update 用戶表 set 等級= `注冊會員` where 等級= `青銅級`

3、數據刪除異常

        刪除某一數據時不得不同時刪除另一數據

    例:    如何刪除用戶等級名為青銅的等級

               delete from 用戶表 where 用戶等級=`青銅`;

4、數據存在冗余

5、數據表過寬,會影響修改表結構的效率

三、用戶實體屬性的操作問題的解決方式

遵守數據庫的設計方式:

  •       設計方式是數據庫設計的規范
  •       有多種設計范式,如數據庫設計第一范式,第二范式和第三范式
  •       數據庫設計最低要滿足第三范式的要求

1、第三范式(3NF)的定義

  一個表中的列和其他列之間既不包括部分函數依賴關系,也不包括傳遞函數依賴關系,那么這個表的設計就符合第三范式。

2、根據第三范式(3NF)優化拆分用戶表

這里根據范式將第一張表中的會員級別、級別積分上限、級別積分下線進行拆分成一個小表,因為用戶的個人信息修改的頻率不高,而用戶的級別可能隨着時間、經驗值等的提升而經常變動,單獨拆分出來可以避免對冷數據的重復檢索、節約IO資源。

              

3、根據第三范式設計好的表如下:

用戶登錄表(customer_login)

DROP TABLE IF EXISTS `customer_login`; CREATE TABLE `customer_login` ( `customer_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用戶ID', `login_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶登錄名', `password` char(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'md5加密的密碼', `user_stats` tinyint(4) NOT NULL DEFAULT '1' COMMENT '用戶狀態', `modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改時間', PRIMARY KEY (`customer_id`) ) ENGINE=InnoDB DEFAULT CHARSET=gbk COMMENT='用戶登錄表';

用戶信息表(customer_inf)

create table customer.customer_inf( customer_inf_id int unsigned auto_increment not NULL comment '自增主鍵ID', customer_id int unsigned not null comment 'customer_login表的自增ID', customer_name varchar(20) not null COMMENT '用戶真實姓名', identity_card_type TINYINT not null default 1 COMMENT '證件類型:1身份證,2軍官證,3護照', identity_card_no varchar(20) comment '證件號碼', mobile_phone int unsigned comment '手機號', customer_email varchar(50) COMMENT '郵件', gender char(1) comment '性別', user_point int not null DEFAULT 0 COMMENT '用戶積分', register_time TIMESTAMP not null COMMENT '注冊事件', birthday datetime COMMENT '會員生日', customer_level tinyint not null DEFAULT 1 COMMENT '會員級別:1普通會員,2青銅會員,3白銀會員,4黃金會員,5鑽石會員', user_money decimal(8,2) not null default 0.00 COMMENT '用戶余額', modified_time TIMESTAMP not null DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT '最后修改時間', primary key pk_customerinfid (customer_inf_id) ) engine=innodb comment '用戶信息表' ;

用戶級別表(customer_level_inf)

create table customer_level_inf( customer_level TINYINT not null auto_increment COMMENT '會員級別ID', level_name varchar(10) not null comment '會員級別名稱', min_point int unsigned not null default 0 comment '該級別最低積分', max_point int unsigned not null DEFAULT 0 COMMENT '該級別最高積分', modified_time TIMESTAMP not null DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP comment '最后修改時間', PRIMARY key pk_levelid (customer_level) ) engine=innodb comment '用戶級別信息表' ;

用戶地址表 (customer_addr)

create table customer_addr ( customer_addr_id int UNSIGNED auto_increment not null comment '自增主鍵ID', customer_id int UNSIGNED not null COMMENT 'customer_login表的自增ID', zip smallint not null comment '郵編', province smallint not null comment '地區表中省份的id', city smallint not null comment '地區表中城市的id', district smallint not null comment '地區表中的區id', address varchar(200) not null comment '具體的地址門牌號', is_default TINYINT not null comment '是否默認', modified_time TIMESTAMP not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP comment '最后修改時間', PRIMARY key pk_customeraddid(customer_addr_id) ) engine=innodb comment '用戶地址表' ;

用戶積分日志表(customer_point_log)

create table customer_point_log( point_id int UNSIGNED not null auto_increment comment '積分日志ID', customer_id int UNSIGNED not null comment '用戶ID', source tinyint unsigned not null comment '積分來源:0訂單,1登錄,2活動', refer_number int unsigned not null default 0 comment '積分來源相關編號', change_point SMALLINT not null default 0 comment '變更積分數', create_time TIMESTAMP not null comment '積分日志生成時間', PRIMARY key pk_pointid(point_id) ) engine=innodb comment '用戶積分日志表' ;

用戶余額變動表(customer_balance_log)

create table customer_balance_log( balance_id int UNSIGNED not null auto_increment comment '余額日志id', customer_id int UNSIGNED not null comment '用戶ID', source TINYINT UNSIGNED not null DEFAULT 1 COMMENT '記錄來源:1訂單,2退貨單', source_sn int UNSIGNED not null COMMENT '相關單據ID', create_time TIMESTAMP not null DEFAULT CURRENT_TIMESTAMP COMMENT '記錄生成時間', amount decimal(8,2) not null DEFAULT 0.00 comment '變動金額', PRIMARY key pk_balanceid(balance_id) ) ENGINE=INNODB COMMENT '用戶余額變動表' ;

用戶登錄日志表(customer_login_log)

create table customer_login_log( login_id int UNSIGNED not null auto_increment comment '登錄日志ID', customer_id int UNSIGNED not null COMMENT '登錄用戶ID', login_time TIMESTAMP not null COMMENT '用戶登錄時間', login_ip int unsigned not null COMMENT '登錄IP', login_type TINYINT not null COMMENT '登錄類型:0未成功 1成功', PRIMARY key pk_loginid (login_id) ) ENGINE=INNODB COMMENT '用戶登錄日志表' ;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM