本文不讲具体的技术点,谈一点设计这也是在本次项目当中的一点心得体会。本文的一些观点主要是我平时的项目实践以及阅读和学习到,希望能够启发大家的思考,只有不断的思考才能不断的去领悟,他山之石可以攻玉,才会形成自己独特的理解并根据实际情况加以利用,形成自己的只是体系。主要是本次的项目部分的数据库的设计看的太蛋疼,所以写一写自己的感想。
一、账户体系:
账户体系
:任何一个带有权限的多用户系统,账户体系都是必备的基础体系基础。我们这里将结合这个具体的来分析数据库的设计。
账户体系包含的内容
:
- 用户常见的登录信息:
- 用户名密码的组合 | 邮箱和密码的组合
- openid 和电话的组合或者单独的 openId 的组合
- qq进行登录的信息(这个没有做过不知道具体的标识是啥)
- 指纹di
- 其他生物信息
- 用户的个人信息:
- 用户类型
- 电话
- 会员等级
- 积分总额
- 已使用积分
- 各种状态
- 用户昵称
- 用户创建时间
- 用户图像
- 密码的盐值
- 推送的id标识
- 来源(用户统计各个推广平台的转化率)
- 邀请者 id
- 用户总金额
- 用户可用余额
- 用户标签
- 通知次数
……
这是本次构建的系统的一部分的用户的信息,对!! 你没有听错,这只是一部分,上述我所提到的信息,全部在一张表内,当然登录的信息没有那么多,目前只有一个微信登录和用户名密码登录。
二、感想:
这个目前是我们公司设计的表,当然不是我设计的,不然也不会有这篇博文,多的咱就不提了,咱们下面就说一说该如何正确的拆分和设计。
2.1 数据库的设计原则(这个标题有点大,这里我只提我用到过的):
- 符合三范式,非必须,因为有很多时候我们需要反三范式设计(后面再提)
- 正确认识冗余
- 中间表的设计
- 防止数据库打补丁的原则:
- 数据库表越少越好:实体是对客观世界的高度的抽象,只有抽象的够好,逻辑处理才会简单,各个实体的职责比较清晰,自然补丁就不会找你。
- 数据库的字段个数合适:这里不说最少是最好的,因为很多情况我们必须要考虑冗余,这是为了我们查询更加的便捷,减少拼表提高效率,毕竟通常数据库做的大量的事情是查询。这里我们需要在 数据冗余 和 处理速度之间找到一个平衡点
- 需要做好抽象工作,在这里我们依旧需要对设计模式原则有比较好的掌握(其实这也体现一点,有些原则是一通百通),
- 例如:单一职责原则(例子我们会通过上面的案例来具体的分析)
- 开闭原则:你可以在我上面扩展,但是拒绝修改,这个和上面的减少打补丁的原则一致
- 迪米特法则:尽可能的减少和其他实体的发生相互作用,其实本质上还是单一职责的问题以及高度抽象的问题
- OLTP 还是 OLAP
- 前者关注事务、后者关注分析,对于事务型的我们往往会设计规范化的表,对于分析性的我们就会设计一个非规范化的表。
- 对于事务型的我们更加关注并发,所以事务需要是轻量级的。对于分析性的我们往往会增加冗余毕竟去大量拼表。
- 可能我们的系统中既有OLTP类型的也有OLAP类型的,一般公司比较小就不会划分这么细,那么具体的就具体的去分析,这里不用过多的考虑,一般这种情况很少出现,以前请教了一个支付宝的DBA,给我一顿鄙视(开个玩笑我的一个学长来的)他就说道这是你们公司自己垃圾设计的表都搞到一起了,一般公司都会有专门的数据仓库来处理
基本上我在设计数据库的时候会结合这些来考虑。有可能读者会看到,哎…… 这里并没有说怎么主键、外键、索引、视图、字段类型选择、约束性…… 呃,我只能说这些会在后面提升数据库性能的一章中提到。单一原则吗~~~
三、我们结合上面的来具体的设计一下表:
3.1、用户登录信息表
①:普通类型的
名 | 类型 | 长度 | 键 | common |
---|---|---|---|---|
id | unsigned int | 11 | primary key auto_incremetn | |
user_id | unsigned int | 11 | ||
phone | varcher | 15 | 这个长度为15的原因是防止要存储区号 | |
pwd | varcher | 30 | 这个设计长一点因为一般都是混淆加密的 | |
salt | varcher | 10 |
②:第三方登录的
名 | 类型 | 长度 | 键 | common |
---|---|---|---|---|
id | unsigned int | 11 | primary key auto_incremetn | |
user_id | unsigned int | 11 | ||
oauth_name | varcher(40) | |||
oauth_id | varchar | 40 | 一般第三方的OpendId 都比较长 |
3.2、个人信息表
名 | 类型 | 长度 | 键 | common |
---|---|---|---|---|
user_id | unsigned int | 11 | primary key auto_incremetn | |
phone | varcher | 15 | 这个地方就是冗余,因为登录表我们只做登录获取token,后续就不用了,但是电话号码我们需要做营销或者通知,所以还是添加到个人信息表里面,迪米特法则,尽量少与其他实体发生相互作用 | |
nick_name | varcher | 30 | ||
birth | datetime | |||
img | varcher | 100 | 有的第三方图像巨长 | |
user_from | unsigned int | 11 | 用户来源,用于统计推广的转化率 |
后面肯定还有具体的用户信息,我们就不在写了,这个表大多只是展示用的,只做查询之用。
3.3、用户账户表
名 | 类型 | 长度 | 键 | common |
---|---|---|---|---|
user_id | unsigned int | 11 | primary key | |
vip_level | unsigned int | 11 | 会员等级 | |
discount | decimal(3,2) | 11 | 可享受的折扣,这个肯定也是别的表计算的结果,但是在这个地方依旧是冗余字段 | |
total_score | unsigned int | 11 | 会员总消费积分 | |
eff_score | unsigned int | 11 | 有效会员积分 |
这里也会有很多的具体的业务字段,这个大家根据具体业务具体的分析。
四、小结一下
数据库设计的如何直接决定整个应用程序的逻辑的复杂程度、稳定性。但是由于这个业务并不复杂,不可能将所有的原则技巧都使用上,只是看到我们的用户那部分的数据库设计比较糟糕,有感而发顺带总结一下数据设计的技巧。
上面主要用到了单一的设计原则,开闭原则,迪米特法则以及适当的冗余等。
ER图这个东西是没有具体的答案的,数据库设计的如何取决以下方面:
- 你对整个业务流程的了解程序,因为设计表的时候你要考虑了到如何去查,把这个放到那一块才会减小不同实体间的相互作用
- 你对数据库设计原则的理解程度
- 你的经验:对于数据冗余和处理速度之间的平衡感
- 你对有业务的抽象的能力
- 细心程度投入程度,对于良好的设计的追求程度(你所看到的把所有的信息堆积到一起的,完全就是抱着一副完成任务的态度,这样说啥都是白扯)
今天的分享就到这里,接下来还有很多的欠账都没有补上,rabbitmq的内容是还没有写完的,我这里正在重新整理当中,因为后来我又重读了我的博客,我感觉还是没有讲清楚和讲明白,所以后面打算重写整个系列,有兴趣的请大家多关注一下。
用场景驱动的方式,讲述能看的懂能落地的技术。加入java技术进阶交流群(570980002)一起纯粹的讨论技术(非培训机构)。
博客首发地址csdn:https://blog.csdn.net/weixin_42849915
简书地址:https://www.jianshu.com/u/4b48be4cf59f
希望结识更多的大牛一同学习一同进步
网友评论