高性能Mysql——电商项目用户模块设计示例
用户实体
用户实体中包含的属性如下:
有些属性是通过用户录入进行输入的,而有些属性则是通过后台计算得到的。
保存上述一个用户实体,最简单的方法当然是简单粗暴的把用户实体内的属性保存在一个表里面,如下图所示:
这样做的好处很明显:容易进行数据的存取,不用考虑多个表中的数据一致性问题,当然也不用关联数据表,查询时是很方便的。
用户表逻辑设计
但是上述的表很明显会产生数据插入、删除、更新等异常。
一般来说,对于用户模块的数据库表的设计需要满足如下两个条件:
根据第三范式,我们可以看到,会员积分上下限依赖于会员级别,而会员级别依赖于用户的登录名。所以对于会员级别会存在增删改的异常。需要单独剥离出去。
一般来说,设计到上面这个步骤就可以了,但是一个好的数据库表的设计还应该做到冷热数据的分离,减小表的宽度。
一般做到冷热数据的分离,就需要区分哪些列是经常被一起访问的,哪些列可以单独提取出来放到一个扩展表中。
比如每次登陆的时候,只需要用户名和密码,另外可能还需要用户的状态。
再比如用户的地址可能有多个,我们也需要把地址抽出来单独形成一个表。
剩下的属性就是放在扩展表中的属性。
具体是如下区分的:
用户表的表结构设计
紧接逻辑设计,将用户表分成了下面几个表:
- 用户登录表。
- 会员登记表。
- 用户信息表。
- 用户地址表。
- 用户积分日志表。
- 用户登录日志表。
- 用户余额变动表。
在逻辑设计的基础上,多出了3张表,分别用于记录积分、登录、余额的变动。
下面,来说明每个表的表结构设计:
在建表的时候同时维护数据字典,所以使用COMMENT
字段来表名该列的备注信息。
使用int(10) unsigned
的自增id来做唯一主键。login_name
是一个varchar(20)
的字段,后续一般会在用户登录名上建立一个索引。password
使用md5加密,所以其长度是固定的32位,这里使用char(32)
类型。
另外要注意的就是modified_time
这个列了,一般会在每个表中都会加入这个列,ON UPDATE
在其他列修改的时候,自动的修改这一列的值。这对于数据分析时,增量数据分析是特别有用的。
最后,在表的定义上,使用了ENGINE
属性表名表的存储引擎,同时COMMENT
也表名了表的备注信息,这样才算一个完整的数据字典。
在costomer_inf表中,使用customer_id
作为其外键约束。
其他行暂且不表,注意其数据类型即可。
比如tinyint(1)
和 tinyint(4)
中的1和4并不表示存储长度,只有字段指定zerofill是有用,如tinyint(4),如果实际值是2,如果列指定了zerofill,查询结果就是0002,左边用0来填充。
其他表,在github中查看即可。