个人博客网: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 '用户登录日志表'
;

高性能可扩展mysql 笔记(二)用户模型设计、用户实体表结构设计、设计范式的更多相关文章

  1. 高性能可扩展mysql 笔记(一)数据库表、索引、SQL语句设计规范

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 项目说明:该笔记的背景为电商平台项目,电商项目由于其高并发.多线程.高耗能等特性,在众多的项目类型中涉及 ...

  2. 高性能可扩展mysql 笔记(六) SQL执行计划及分页查询优化、分区键统计

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 常见业务处理 一.使用数据库处理常见业务: 案例: 如何对评论进行分页展示 使用 EXPLAIN 获得s ...

  3. 高性能可扩展mysql 笔记(四)项目分区表演示

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 登录日志的分区 如何为Customer_login_log表分区? 从以下两个业务场景入手: 用户每次登 ...

  4. 高性能可扩展mysql 笔记(五)商品实体、订单实体、DB规划

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.商品模块 ​ 商品实体信息所存储的表包括: 品牌信息表: create table `brand_i ...

  5. 高性能可扩展mysql 笔记(三)Hash分区、RANGE分区、LIST分区

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.MySQL分区表操作 1.定义:数据库表分区是数据库基本设计规范之一,分区表在物理上表现为多个文件, ...

  6. Mysql 笔记二

    Mysql 笔记二 Mysql 笔记二 Table of Contents 1. 前言 2. Master Thread 工作方式 2.1. 主循环(loop) 2.2. 后台循(backgroup ...

  7. MySql笔记(二)

    目录 MySQL笔记(二) 一幅画,一次瞬间的回眸,就在那次画展上,那个眼神,温柔的流转,还是那干净的皮鞋,一尘不染,俊朗的眉宇性感的唇,悄悄走近,牵手一段浪漫 MySQL笔记(二) 13.条件查询 ...

  8. MySql笔记二:命令简介

    从笔记二开始讲解一些简单的命令,这些我在SQL Server里面都讲过了,什么主键,约束啥的数据库这些都是相通的,所以MySql这里,不讲,粗略过一遍. 使用命令框登录MySql mysql -u r ...

  9. MySQL笔记二

    Ø function 函数 函数的作用比较大,一般多用在select查询语句和where条件语句之后.按照函数返回的结果, 可以分为:多行函数和单行函数:所谓的单行函数就是将每条数据进行独立的计算,然 ...

随机推荐

  1. NEON中的L可以避免溢出

    在做加法时,比如两个255x255的数值相加,那么正确结果将是130050,对一个最大值为65565的unsigned short是会溢出的,但是如果使用L命令时,则不会产生溢出.这说明L命令,不是先 ...

  2. [hdu5373 The shortest problem]模拟

    http://acm.hdu.edu.cn/showproblem.php?pid=5373 思路:按题意来即可. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  3. 两个有序数组 A1 A2 的合并

    /** * 问题6.有序数组 A1 A2 的合并 */ @Test public void orderArrayMerge() { // 两个有序数组 A1 A2 的合并 int[] A1 = {1, ...

  4. mp4封装格式各box类型讲解及IBP帧计算

    mp4封装格式各box类型讲解及IBP帧计算 目录 mp4封装格式各box类型讲解及IBP帧计算 box ftyp box moov box mvhd box (Movie Header Box) t ...

  5. php的 mysqlnd驱动

    这篇文章写的好 http://blog.linuxeye.com/395.html 传统编译php的时候需要指定mysql 的参数 --with-mysql=/usr/local/mysql \ -- ...

  6. 弹性式数据集RDD

    弹性式数据集RDD ​ 一.RDD简介二.创建RDD        2.1 由现有集合创建        2.2 引用外部存储系统中的数据集        2.3 textFile & who ...

  7. Java—CountDownLatch使用详解

    CountDownLatch介绍 CountDownLatch概述 CountDownLatch一般用作多线程倒计时计数器,强制它们等待其他一组(CountDownLatch的初始化决定)任务执行完成 ...

  8. 【Django】rest_framework 序列化自定义替换返回值

    # 序列化设置 class PagerSerialiser(serializers.ModelSerializer): name = serializers.CharField(source=&quo ...

  9. Django之form表单常用字段与插件

    from django.shortcuts import render,HttpResponse from django import forms from app01 import models f ...

  10. 你想了解的python基础数据类型这里都有

    目录 python基础数据总结 数字型数据类型 数字型数据基本知识 算术运算符 进制 二进制运算符 字符串数据类型 字符串基础知识 字符串数据操作方法(增 查 改) 集合数据类型 集合基础知识 集合元 ...