在上小节制定了数据库开发规范后,这小节之后将开始数据库电商项目实战。在电商实战项目中我们一共涉及用户模块商品模块订单模块仓储模块。本次测试所用的数据库版本mysql 5.7

涉及模块功能:

ssl

1.用户模块属性

用户模块的属性一般有

ssl

ssl

将用户实体所有的属性存放在一张表中,在数据的读取和写入时比较方便,但是也会带来一些问题?

数据插入异常?

插入异常:想要插入数据,结构因为表设计的问题,导致不能成功插入。

在上面表中,如果我们想给用户设一个等级,小于100积分(青铜级),100-200(白银级),200-300(黄金级),300-400(铂金级),400积分以上(钻石级)。

insert into 用户名(会员级别) value('青铜级')

这条sql是会报错,因为用户表中用户名时主键,主键是不能为NULL,所以插入数据会报错。

数据更新异常?

更新异常:要修改某一行的值,不得不修改多行数据

有一天,产品经理说想要把青铜级用户改为注册会员,需要执行以下sql

update 用户表 set 等级 = '注册会员' where 等级 = '青铜级'

本来我们想修改一条数据,将青铜级改为注册会员,但是由于表结构的设计,导致要更新用户表中所有的青铜级

数据删除异常?

数据删除异常:删除某一数据时不得不同时删除另一数据

过了一段时间后,产品进来说不想要注册会员了,需要执行以下sql

delelt from 用户表 where 用户等级 = '注册会员';

本来只想删除用户等级为注册会员,结果把用户信息也一并删除,如果真这么做了,估计明天就不用去上班了。

数据冗余?

数据冗余:想修改一个属性,就要更新多行数据

每当我们更新用户等级信息,就必须也要更新用户的积分上限和下限,这样会造成大量的数据冗余问题。

2.优化用户表设计

设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库。目前关系数据库有六种范式:第一范式(1NF)第二范式(2NF)第三范式(3NF)巴斯-科德范式(BCNF)第四范式(4NF)第五范式(5NF)。一般说来,数据库只需满足第三范式(3NF)就基本不会碰到上面遇到的问题。

下面我们就上上面的表拆分下:

用户级别信息表(customer_level_inf):

会员级别        积分上限        积分下限

用户登录表(customer_login):

登录名      登录密码        登录状态

用户地址表(customer_addr):

省      市      区      邮编        地址

用户信息表(customer_info):

用户姓名        证件类型        证件号码        手机号      邮箱        性别        积分        注册时间        生日        会员级别        用户余额

3.建表语句

用户级别

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 DEFAULT charset=utf8 COMMENT '用户级别信息表';

用户登录表

CREATE TABLE customer_login(
	customer_id	INT UNSIGNED AUTO_INCREMENT	NOT NULL COMMENT '用户ID',
	login_name VARCHAR(50) NOT NULL COMMENT '用户登录名',
	password CHAR(32) NOT NULL COMMENT '用户登录密码',
	user_stats TINYINT  NOT NULL DEFAULT 1 COMMENT '用户状态,1在线,0离线',
	modified_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
	PRIMARY KEY pk_customerid(customer_id)
)ENGINE=INNODB DEFAULT charset=utf8 COMMENT '用户登录表';

用户地址表

CREATE TABLE customer_addr(
	customer_add_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 '省',
	city SMALLINT NOT NULL COMMENT '市',
	district SMALLINT NOT NULL COMMENT '区',
	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_add_id)
)ENGINE=INNODB DEFAULT charset=utf8 COMMENT '用户地址表';

用户信息表

CREATE TABLE 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_emial 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_customerinfif (customer_inf_id)	
)ENGINE=INNODB DEFAULT charset=utf8 COMMENT '用户信息表';

用户登录日志表

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 DEFAULT charset=utf8 COMMENT '用户登录日志表'

用户积分日志表

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_ponit SMALLINT NOT NULL DEFAULT 0 COMMENT '变更积分数',
	create_time TIMESTAMP NOT NULL COMMENT '积分日志生成时间',
	PRIMARY KEY pk_pointid (point_id)
)ENGINE=INNODB DEFAULT charset=utf8 COMMENT '用户积分日志表';

用户余额变动表

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退货单',
	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 DEFAULT charset=utf8 COMMENT '用户余额变动表';

mysql 电商项目实战

mysql 数据库设计规范(1) mysql 数据库范式(2) mysql 用户模块设计(3) mysql 分区(4)