背景:将一本书,存入我们的数据库中,并可以查出来
采用:第三范式(3NF)设计模式
第一范式(1NF):确保表的每一列都是不可分割的原子数据项。
第二范式(2NF):在满足第一范式的基础上,非主键列必须完全依赖于整个主键,而不是主键的一部分。
第三范式(3NF):在满足第二范式的基础上,非主键列之间不存在传递依赖关系,即一个非主键列不能依赖于另一个非主键列。
我们通过迭代,一步一步完成到第三范式
身边有书就拿起书,没书咱们就感谢前辈的努力(crrl+左键)PS:文字作者的休闲时刻奇妙幻想
第一眼,我们可以看见一个叫封面
第二眼,我们可以看见一个叫书名
第三眼,我们可以看见作者的名字
第四眼,侧边有一个出版社(实体书)
第五眼,侧边话还有一个时间
第六眼,书的背面有大佬点评(实体书)
第七眼,我们可以看见字数总和
第八眼,我们可以看见浏览量
第一层组成:封面,书名,作者,出版社,时间,点评,字数,浏览量(我拿三本书看到的信息)
翻开一页,利用上面的那个网站作为例子的,直接看下面就好(点个赞!)
又来了,
第一眼,我们可以看见作者的介绍(目前不涉及)
第二眼,作者写这本书的目的,也就是前言
第二层组成:介绍,前言
再翻几页,我们发现就是那密密麻麻的章节了,没有的按开始提供的网页进行参考
第一眼,我们可以看见加粗的h1标签的章节(凭感觉应该可以看出这个明细是h1打印出来的)
第二眼,每一篇的小标题
第三眼,页数
第三层组成:总章节,每一篇的小标题
第四层就是我们最熟悉的小标题+内容了
这样我们的第一步就完成了,将四层组合一如下
第一层组成:封面,书名,作者,出版社,时间,点评,字数,浏览量
第二层组成:介绍,前言
第三层组成:总章节,每一篇的小标题
第四层组成:小标题,内容
第一层:封面,书名,作者,出版社,时间,点评,字数,浏览量,已经完成条件不可分割
第二层:介绍,前言,同上
第三层,第四层一样
第一层1nf代码如下,
- CREATE TABLE ak47 (
- id INT AUTO_INCREMENT PRIMARY KEY,
- cover VARCHAR(255) NOT NULL COMMENT '封面图片路径',
- title VARCHAR(255) NOT NULL COMMENT '书名',
- author VARCHAR(255) NOT NULL COMMENT '作者',
- publisher VARCHAR(255) NOT NULL COMMENT '出版社',
- publish_date DATE NOT NULL COMMENT '出版时间',
- review TEXT COMMENT '点评',
- word_count INT NOT NULL COMMENT '字数',
- view_count INT DEFAULT 0 COMMENT '浏览量',
- introduction TEXT COMMENT '介绍',
- preface TEXT COMMENT '前言',
- chapter_number INT COMMENT '章节序号',
- subtitle VARCHAR(255) COMMENT '小标题',
- content TEXT COMMENT '内容'
- );
在满足第一范式的基础上,非主键列必须完全依赖于整个主键,而不是主键的一部分。
拆出来:必须完全,整个主键
整个主键:一整个表只能有一个主键,那么前面这句一整个表好理解,主键是什么呢?
主键:具有代表整个表的关键词(编号,身份证,表单的身份证)
一山不容二虎,除非他是子表
根据这个内容,我们的1nf范式,去进行一个拆解
我们可以分为三大类:第一类:书籍基本信息
第二类:书籍章节
第三类:书籍评价
这一个表就被拆成如下:
第一类:(主键)书籍编号,封面,书名,作者,出版社,出版时间
第二类:书籍编号(父表),书籍章节(主键),章节标题,章节内容,浏览量,字数
第三类:书籍编号(父表),评论ID(主键),评论内容,评论时间
为什么这么拆:封面,书名,作者,出版社,出版时间这些只能通过书籍编号获取,非主键列必须完全依赖于整个主键,
完全依赖,就是指,书名只能通过一个东西去获得,不能通过其他的去得到
第一个原则:重复性,当一个元素能重复时,他就不具有做主键的代表性
所以在选择主键的时候,考虑他可能重复吗?这里我们又可以进行拆一次
第一类:(主键)书籍编号,封面,书名,出版社,出版时间
第二类:作者(主键),作者名字,作者账号,作者简介,作品(父表)
第三类:书籍编号(父表),书籍章节(主键),章节标题,章节内容,浏览量,字数
第四类:书籍编号(父表),评论ID(主键),评论内容,评论时间
这时,作品又可以分类讨论了:一个本书没问题,两本书难不成像文章一样吗,
用《第一本》,《第二本吗》,放在同一个列中吗,很显然不可能
这样看着是不是怪怪的
再分就成五类了
第一类作者信息:作者账号(主键),作者名字,作者简介
第二类书籍信息:(主键)书籍编号,封面,书名,出版社,出版时间
第三类章节信息:书籍编号(父表),书籍章节(主键),章节标题,章节内容,浏览量,字数
第四类评论信息:书籍编号(父表),评论ID(主键),评论内容,评论时间
第五类作者作品:作者编号(父表),书籍编号(父表)
为什么第五类这么拆,我们可以根据查询语句,直接查出父表的内容,说人话就是
父表的内容可以直接被查出来,这样设计就有一点MVC模式了
类拆好了,那么该实现代码了
- CREATE TABLE authors (
- -- 作者账号,作为主键,具有唯一性
- author_account VARCHAR(255) PRIMARY KEY UNIQUE,
- -- 作者名字
- author_name VARCHAR(255) NOT NULL,
- -- 作者简介
- author_bio TEXT
- );
第二类
- CREATE TABLE books (
- -- 书籍编号,作为主键,具有唯一性
- book_id INT PRIMARY KEY UNIQUE,
- -- 封面
- cover VARCHAR(255),
- -- 书名
- title VARCHAR(255) NOT NULL,
- -- 出版社
- publisher VARCHAR(255),
- -- 出版时间
- publication_date DATE
- );
第三大类
- CREATE TABLE chapters (
- -- 书籍编号,作为父表引用书籍信息表
- book_id INT,
- -- 书籍章节编号,与书籍编号组合作为复合主键,具有唯一性
- chapter_number INT,
- -- 章节标题
- chapter_title VARCHAR(255) NOT NULL,
- -- 章节内容
- chapter_content TEXT,
- -- 浏览量
- view_count INT DEFAULT 0,
- -- 字数
- word_count INT,
- -- 设置复合主键
- PRIMARY KEY (book_id, chapter_number),
- -- 设置父表约束
- FOREIGN KEY (book_id) REFERENCES books(book_id)
- );
第四类:
- CREATE TABLE comments (
- -- 评论ID,作为主键,具有唯一性
- comment_id INT PRIMARY KEY UNIQUE,
- -- 书籍编号,作为父表引用书籍信息表
- book_id INT,
- -- 评论内容
- comment_content TEXT NOT NULL,
- -- 评论时间,默认为当前时间戳
- comment_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- -- 设置父表约束
- FOREIGN KEY (book_id) REFERENCES books(book_id)
- );
第五类
- CREATE TABLE author_works (
- -- 作者账号,作为父表引用作者信息表,具有唯一性(与书籍编号组合)
- author_account VARCHAR(255),
- -- 书籍编号,作为父表引用书籍信息表,具有唯一性(与作者账号组合)
- book_id INT,
- -- 设置复合主键,确保作者与书籍的关联唯一
- PRIMARY KEY (author_account, book_id),
- -- 设置父表约束
- FOREIGN KEY (author_account) REFERENCES authors(author_account),
- FOREIGN KEY (book_id) REFERENCES books(book_id)
- );
总结2nf的一个原则,不可重复性,当出现了重复性,那么我们就要将其分出来
第三范式(3NF):在满足第二范式的基础上,非主键列之间不存在传递依赖关系,即一个非主键列不能依赖于另一个非主键列。
说人话就是,除了主键和父键以外的列,他们是独立存在的,互不影响,就和国家与国家一样,
第一类作者信息:作者账号(主键),作者名字,作者简介
第二类书籍信息:(主键)书籍编号,封面,书名,出版社,出版时间
第三类章节信息:书籍编号(父表),书籍章节(主键),章节标题,章节内容,浏览量,字数
第四类评论信息:书籍编号(父表),评论ID(主键),评论内容,评论时间
第五类作者作品:作者编号(父表),书籍编号(父表)
来来看看父表和主键之外的内容有没有联系
能通过作者名字去确定一个作者的简介吗?很显然不能,因为名字可重复,但是账号不可重复
除非你把账号和作者的名字改一下
A和B之间没有直接的关系,独立,互不影响,但是硬要深挖他们就是属于书的一部分
总结一下:三段范式,是属于叠加态,简称父子关系,而他们的父亲
具体关系如下,1nf是父,2nf是儿,3nf就是孙子
每一代都继承了父代的优势
1nf是原子性,即本质性
2nf是具有原子性,诞生了不可重复性
3nf是具有原子性,不可重复性,独立互不影响性
第一步:拆解,拆解成1
例子:12,就拆成12个1
第二步:确定唯一主键和父键,如果有需求可以再来一个义父键
例子:A,B,C
A是父键,B是主键,C是列
他们直接的联系就是,A是连接B的,B是用来连接C的
第三步:看除主键父键以外的内容,是否是独立互不影响性
0.1版本,2024/3/16数据库3nf范式模板