数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,创建数据库及其应用系统,使之可以有效地存储数据,知足各类用户的应用需求(信息要求和处理要求)。在数据库领域内,经常把使用数据库的各种系通通称为数据库应用系统。 数据库设计的设计内容包括:需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库的实施和数据库的运行和维护。git
◆ 课程的属性:{主标题,副标题,方向,分类,难度最新最热,时长,简介,人数,需知,收获,讲师名讲师职位,课程图片综合评分,内容实用,简洁易懂,逻辑清晰}github
◆ 课程列表的属性:{章名,小节名, 说明,小节时长,章节URL,视频格式}数据库
◆ 讲师的属性:{讲师昵称,说明,性别,省,市,职位说明,经验,积分,关注人数,粉丝人数}bash
◆ 问答评论属性:{类型,标题,内容,关联章节,浏览量,发布时间,用户昵称}数据库设计
◆ 笔记的属性:{用户昵称,关联章节 笔记标题,笔记内容,发布时间}。函数
◆ 用户的属性:{用户昵称密码,说明,性别,省,市,职位,说明,经验,积分,关注人数粉丝人数}性能
◆评价的属性:{用户,课程主标题,内容,综合评分,内容实用,简洁易懂,逻辑清晰,发布时间}学习
◆ 课程的属性:{主标题,副标题,方向,分类难度最新,最热,时长,简介,人数,需知,收获,讲师名,讲师职位,课程图片综合评分,内容实用,简洁易懂,逻辑清晰}测试
例如当使用 优化
例如,咱们想新增Java开发方向的课程
例如,咱们想删除数据库方向
咱们只是单纯想删除数据库方向而已,但该语句却将许多课程也删除了,这并不符合咱们的预期.
相同的数据在一个表中出现了屡次
那么是否是这么多问题就意味着宽表一无可取呢?存在即合理!
因为宽表中,全部数据存在于一个表中,所以在查询时,无需多表查询,SQL执行效率较高,且存在的上述问题在报表应用中都不是大问题
既然宽表不适合咱们的当前业务,那么怎么寻找合适的方法呢?
例如如下实例中的联系方式是一个复合属性,明显就违反了该范式,在数据库中是没法分离出来的
咱们只需对其进行简单的改动便可
即标准的二维表.
前提
标准的二维表,即第一范式成立
表中必须存在业务主键,而且非主键依赖于所有
业务主键
例如以下博客表实例
使用用户字段做为PK是否可行呢? 显然一个用户会对应多个博客记录,且章节标题也能为多个用户编辑,因此单列字段PK失效
使用<用户,章节,标题>的复合PK 然而用户积分字段也只和用户字段依赖,并不依赖于总体的PK,因此依旧不符合第二范式
拆分将依赖的字段单独成表
从上面,咱们也能够发现:
依旧看看课程表
首先,一个字段的PK显然符合第二范式,大部分字段也只依赖于PK,然而对于讲师职称字段实际上是依赖于讲师名的,因此不符合第三范式.
{主标题,副标题,方向,分类,难度,最新,最热,时长,简介,人数,需知,收获,讲师名讲师职位,课程图片综合评分,内容实用,简洁易懂,逻辑清晰}
咱们显然能够将其拆分以下:
主标题(PK)
,副标题,方向,分类,难度,上线时间,学习人数,时长,简介,需知,收获,讲师昵称,课程图片,综合评分,内容实用,简洁易懂,逻辑清晰
讲师名及讲师的职称
其中最新
属性即对应着上线时间计算得出,业务上可规定时间段判断是否为最新 最热
属性便可以学习人数字段排序来反映
课程方向名称(PK)
: 在课程表中有对应的方向字段 添加时间
分类名称(PK)
: 在课程表中有对应的方向字段 添加时间
课程难度(PK)
: 在课程表中有对应的方向字段 添加时间
[章节名,小节名](联合PK)
说明,小节时长,章节URL,视频格式
其中,说明
其实只依赖于章节名
小节时长
,小节URL
,视频格式
都只依赖于小节名
违反第二范式,因此须要拆分字段
章节名(PK)
,说明,章节编号
主标题,章节名
小节名称(PK),小节视频url,视频格式,小节时长,小节编号
主标题,章节名,小节名
讲师名,密码,性别,省,市,职称,说明,经验,积分,关注数,粉丝数
讲师名(PK)
,密码,性别,省,市,职称,说明,经验,积分,关注数,粉丝数
用户昵称,密码,性别,省市,职位,说明,经验,积分,关注数,粉丝数
用户昵称(PK)
,密码,性别,省市,职位,说明,经验,积分,关注数,粉丝数
和讲师表基本相同,且讲师其实也是一种用户,讲师的信息就会被存储两次,形成数据的冗余.,因而就难以保持数据一致性!考虑合并!
用户昵称(PK)
,密码,性别,省市,职位,说明,经验,积分,关注数,粉丝数,讲师标识
类型,标题,内容关联章节,浏览量,发布时间,用户昵称
其中标题文字是共享的,没法保持一致 同一用户在不一样章节提出的问题也可能相同 所以决定采用标题+用户昵称+关联章节
做为PK
如何记录关联章节字段呢? 是否是只能用课程章节的PK来记录呢? 所以,不得不将课程章节的关联表PK加入
[标题,课程主标题,课程章名,小节名称,用户呢称](PK)
父评论(被回复的问题/标题) 标题,内容,类型,浏览量,发布时间
用户昵称,关联章节,笔记标题,笔记内容,发布时间
和评论实体差很少,分析再也不赘述
[笔记标题,课程主标题,课程章名,小节名称,用户呢称](PK)
内容,发布时间
用户呢称;课程主标题,内容,综合评分,内容实用,简洁易懂,逻辑清晰,发布时间
[用户呢称;课程主标题](PK)
内容,综合评分,内容实用,简洁易懂,逻辑清晰,发布时间
只有选择/购买了课程的用户才能评价!!! 须要用户与所选课程的关联关系表
[用户呢称;课程主标题](PK)
选课时间,累积听课时长
若是咱们想要查询出一门课程包括全部章节和小节的相关信息
咱们就要关联5个表,查询效率极低!且查询课程信息的需求很大! 为了提升性能,咱们还须要对表结构进行优化操做
空间换时间的思想
因此能够并不须要关联关系表,而是呢能够直接把课程表和课程&章节联系表合并
课程章节表
[主标题,章节名](PK)
,说明,章节编号
虽然违反了第二范式,可是减小了一个表的查询,提升了查询性能,在频繁查询操做的系统中,这很值得!
通过反范式化后,咱们只须要查询三个表便可
课程相关表数量 5 -> 3
经过数据冗余避免数据不一致
课程章节表:{章节ID(PK),课程ID,章节名称,章节说明,章节编号}
课程小节表:{小节ID(PK),课程ID,章节ID,小节名称,小节视频url,视频格式,小节时长,小节编号}。
课程方向表:{课程方向ID(PK),课程方向名称,填加时间}
课程分类表:{课程分类ID(PK),分类名称,填加时间}
课程难度表:{课程难度ID(PK) ,课程难度,填加时间}
用户表:{用户ID(PK),用户昵称,密码,性别,省市,职位,说明,经验,积分,关注 人数,粉丝人数,讲师标识}
问答评论表:{评论ID(PK),父评论ID ,课程ID,章节ID,小节ID ,评论标题,用户 ID,内容,类型,浏览量,发布时间}
笔记表:{笔记ID(PK),课程ID,章节ID,小节ID笔记标题,用户呢称,笔记内容, 发布时间}
评价表:{评价ID(PK),用户ID,课程ID,内容综合评分,内容实用,简洁易懂,逻 辑清晰,发布时间}
用户选课表:{用户选课ID(PK),用户ID,课程ID,选课时间,累积听课时长}
新建表
插入数据
查询结果
因为北京时间是东八区,所以咱们更改时区
新的查询结果
这就是timestamp具备时区性的特色
INET_ATON( '255.255.255.255' ) = 4294967295
INET_ NTOA(4294967295) ='255.255.255.255'
复制代码
数据迁移的时候,它几乎不可能被其余数据库所支持,若是 ENUM 里面是字符串,对于其余数据库来讲就更郁闷了,还不能设为tinyint等类型的字段
纯数字类型的不建议用枚举类型,这是由于在 ENUM 内部维护有一个隐形的索引,也是按数字排列的,容易混淆;添加枚举值也是一个问题,若是添加在最后还好,若是添加在中间什么位置的话,原来的隐藏索引将再也不起做用
ENUM 字段默认是能够插入 NULL 值的,这个就比较尴尬了,并且没有办法优化
若是插入的值比ENUM设定的值大,会默认保存成接近的那个值;插入的值不能包含函数,不能传递参数
因此若是插入的值是数字型的,建议用tinyint,若是插入的值是字符型的,建议用char。若是真想用 ENUM 也是能够得,前提是要了解到 ENUM 的弊端,就能够有效规避这些问题
一、前奏:【业务分析】欲善其事,必三思而行; 二、高潮:【逻辑设计】范式化VS反范式化; 三、结束:【物理设计】存储引擎&数据类型&命名规约。
更多内容请关注JavaEdge公众号