MySQL

    技术2022-07-10  113

    MySQL

    MySql基础

    1:基本数据库命令

    命令行连接

    #使用cmd连接mysql --连接数据库 mysql -uroot -p123456 -- 修改用户密码 update mysql.user set authentication_string=password('123456') where user='root' and Host = 'localhost'; -- 刷新权限 flush privileges; -- 所有的sql语句都要用分号来进行结尾 -- 查看所有的数据库 show databases; --切换数据库use数据库名 use shool; Database changed; -- 查看数据库中所有的表 show tables; -- 显示数据库中所有表的信息 describe student; -- 创建一个数据库 create database 数据库名; --离开,退出连接 exit -- 单行注释(SQL本来的注释) -- 在SQLyog中可以使用#来表示单行注释 /* (SQL的多行注释) hello */

    2:操作数据库

    操作数据库 > 操作数据库中的表 > 操作数据库中表的数据

    mysql关键字不区分大小写

    2.1 操作数据库(了解)

    1、创建数据库

    create database [if not exists] hello;

    2、删除数据库

    drop database [if exists] hello

    3、使用数据库

    -- 如果你的表名或者字段名是一个特殊符号,就要带`` use `school`

    4、查看数据库

    show databases --查看所有的数据库

    2.2 数据库的列操作

    数值

    tinyint 十分小的数据 1个字节smallint 较小的数据 2个字节mediumint 中等大小的数据 3个字节int 标准的整数 4个字节 常用的 intbigint 较大的数据 8个字节float 浮点数 4个字节double 浮点数 8个字节(精度问题!)decimal 字符串形式的浮点数 金融计算的时候,一般使用decimal

    字符串

    char 字符串固定大小的 0~255varchar 可变字符串 0~ 65535 常用的变量 Stringtinytext 微型文本 2^8-1text 文本串 2^16-1

    时间日期

    java.util.Date

    data YYYY-MM-DD 日期格式time HH:mm:ss 时间格式datetime YYYY-MM-DD HH:mm:ss 最常用的时间格式timestamp 时间戳,1970.1.1到现在的毫秒数!也较为常用!year 年份表示

    null

    没有值,未知注意,不要使用null进行运算,结果为null

    2.3 数据库的字段属性(重点)

    Unsigned

    无符号的整数

    声明了该列不能声明为负数

    zerofill

    0填充的不足的位数,使用0来填充,int(3) 5—> 005

    自增

    通常理解为自增,自动在上一条记录的基础上+1(默认)通常用来设计唯一的主键~index,必须是整数类型可以自定义设计主键自增的起始值和步长

    非空 Null not null

    假设设置为not null,如果不给他赋值,就会报错Null,如果不填写值,默认值就是null!

    默认

    设置默认的值!sex,默认值为男,如果不指定该列的值,则会有默认的值

    拓展(每一个表中,都需要以下5个字段)

    id 主键vsersion 乐观锁is_delete 伪删除gmt_create 创建时间gmt_update 修改时间

    2.4 创建数据库表

    -- 注意点,使用英文的(),表的名称和字段尽量用``括起来 -- AUTO_INCREMENT 自增 -- 字符串使用单引号括起来 -- 所有的语句后面加,(英文的),最后一个不加 -- PRIMARY KEY 主键,一般一个表只有唯一的一个主键 CREATE TABLE IF NOT EXISTS `student`( `id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号', `name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名', `pwd` VARCHAR(20) NOT NULL DEFAULT '123' COMMENT '密码', `sex` VARCHAR(20) NOT NULL DEFAULT '男' COMMENT '性别', PRIMARY KEY(`id`) )ENGINE=INNODB DEFAULT CHARSET=utf8

    格式

    CREATE TABLE [IF NOT EXISTS] 表名( '字段名' 类属性 [属性] [索引] [注释], PRIMARY KEY(`id`) )[表类型] [字符集设置] [注释]

    常用的命令

    show create database 数据库名 -- 查看创建数据库的语句 show create table 表名 -- 查看数据库表的定义语句 desc 表名 -- 显示表的结构

    2.5 数据表的结构

    -- 关于数据库引擎 INNODB 默认使用 MYISAM 早些年使用 MYISAMINNODB事务支持不支持支持数据行锁定不支持支持外键约束不支持支持全文索引支持不支持表的大小较小较大,约为MYISAM的两倍

    常规使用操作

    MYISAM 节约空间,速度较快INNODB 安全性高,事务的处理,多表多用户操作

    在物理空间存在的位置

    所有的数据库文件都存在data目录下,一个文件夹对应一个数据库

    本质还是文件的存储!

    MYQL引擎在物理上的区别

    InnoDB在数据库表中只有一个*.frm文件,以及上级目录下的ibdata1文件MYISAM对应的文件 *.frm 表结构的定义文件*.MYD 数据文件(data)*.MYI 索引文件(index)

    设置数据表的字符集编码

    charset=utf-8

    不设置的话,会是mysql默认的字符集编码(不支持中文)

    mysql的默认编码是Latin1,不支持中文

    2.6 修改删除表

    修改

    -- 修改表名: alter table 旧表名 rename as 新表名 alter table teacher rename as teacher1 -- 增加表的字段:alter table 表名 add 字段名 列属性 alter table teacher1 add age int(11) -- 修改表的字段(重命名,修改约束) -- alter table 表名 modify 字段名 列属性[] alter table teacher1 modify age varchar(11) --修改约束 -- alter table 表名 change 旧名字 新名字 列属性[] -- 字段重命名 -- 删除表的字段:alter table 表名 drop 字段名 alter table teacher1 drop age1

    删除

    -- 删除表(如果表存在再删除) drop table if exists teacher1

    所有的创建和删除操作尽量加上判断,以免报错

    注意点:

    `` 字段名,使用这个包裹注释 – /**/sql关键字大小写不区分,尽量用小写

    3:MYSQL数据库管理

    3.1 外键(了解即可)

    外键就是两张表有关联

    删除有外键关系的表的时候,必须先删除引用别人的表(从表),再删除被引用的表(主表)

    创建表成功后,添加外键约束

    -- 创建表的时候没有外键关系 alter table `student` add constraint `FK_gradeid` forengn key(`gradeid`) references `grade`(gradeid) alter table 表名 add constraint 约束名 foreign key(作为外键的列) references 哪个表(哪个字段)

    以上的操作都是物理外键,数据库级别的外键,不建议使用! (避免数据库过多造成困扰,这里了解即可)

    最佳实践

    数据库就是单纯的表,只用来存数据,只有行(数据) 和 列(字段)我们使用多表的数据,想使用外键(程序去实现)

    3.2 DML语言(全部记住)

    **数据库意义:**数据存储,数据管理

    DML 语言:数据操作语言

    3.3 添加

    insert

    -- 插入语句(添加) -- insert into 表名([字段名1,字段2,字段3]) values('值1'),('值2'),('值3') insert into `grade`(`gradename`) values('大四') -- 由于主键自增我们可以省略(如果不写表的字段,它就会一一匹配) insert into `grade` values('大三') -- 一般插写插入语句,我们一定要数据和字段一一对应 -- 插入多个字段 insert into `grade`(`gradename`) values('大二'),('大一') insert into `student`(`name`) values(`张三`) insert into `student`(`name`,`pwd`,`sex`)values(`张三``aaaa`,``) insert into `student`(`name`,`pwd`,`sex`)values(`李四`,`aaa`,``),(`王五`,`bbb`,``)

    语法:insert into 表名([字段名1,字段2,字段3]) values('值1'),('值2'),('值3')

    注意事项:

    1.字段和字段之间使用英文符号隔开2.字段可以省略,但是后面的值必须要一一对应,不能少3.可以同时插入多条数据,values后面的值,需要使用,隔开即可values( ),( )…

    3.4 修改

    update

    -- 修改学员名字,带了简介 update `student` set `name`='hello' where id=1; -- 不指定条件的情况下,会改动所有的表 update `student` set `name`='hello' -- 修改多个属性,用逗号隔开 update `student` set `name`='hello',`email`='123456@qq.com' where id=1;

    条件 :where子句

    操作符会返回布尔值

    操作符含义=等于<>或!=不等于><<=>=between…and…在某个范围内 [ ]and和 &&or或 || -- 通过多个条件定位数据 update `student` set `name` = '长江7号' where `name`='hello' and sex='男'

    语法:update 表名 set colnum_name = value,[colnum_name = value,.....] where [条件]

    注意:

    colnum_name 是数据库的列,尽量会带上``条件,筛选的条件,如果没有指定,则会修改所有的列value,是一个具体的值,也可以是一个变量多个设置的属性之间,使用英文逗号隔开

    3.5 删除

    delete命令

    语法: delete from 表名[where 条件]

    -- 删除数据(避免这样写,会全部删除) delete from `student` -- 删除指定的数据 delete from `student` where id=1

    truncate命令

    作用:完全清空一个数据库,表的结构和索引约束不会变

    -- 清空student表 truncate `student`

    delete 和truncate的区别

    相同点:都能删除数据,都不会删除表结构不同: truncate 重新设置 自增列,计数器会归零delete不会影响自增truncate 不会影响事务

    了解即可:delete删除的问题,重启数据库,现象

    innoDB 自增列会从1开始(存在内存中,断电即失)MyISAM 继续从上一个自增量开始(存在文件中,不会丢失)

    4:DQL查询数据(最重点)

    4.1 DQL

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A6T6uH20-1593573462679)(C:\Users\86131\AppData\Roaming\Typora\typora-user-images\image-20200525160332275.png)]

    (Data query language:数据查询语言)

    所有的查询语句都用它,select简单的查询,复杂的查询它都能做数据库最核心的语句,最重要的语句使用频率最高的语句

    4.2 指定查询字段

    -- 查询全部的学生 select 字段 from 表 select * from student -- 查询指定的字段 select `studentNo`,`studentName` from student -- 别名,给结果起一个名字 As 可以给字段起别名,也可以给表起别名 select `studentNo` as 学号,`studentName` as 学生姓名 from student as s --函数 Concat(a,b) select concat('姓名:',studentName) as 新名字 from student

    语法:select 字段,.... from 表

    有的时候,列名字不是那么的见名知意。我们可以给字段和表起别名

    去重 distinct

    作用:去除select查询出来的结果中重复的数据,重复的数据只显示一条

    select * from result --查询全部的考试成绩 select `studentNo` from result -- 查询有哪些同学参加了考试 select distince `studentNo` from result -- 发现重复数据,去重

    数据库的列(表达式)

    select version() --查看系统的版本(函数) select 100*3-1 as 计算结果 --用来计算(表达式) select @@auto_increment_increment --查询自增的步数(变量) -- 学员考试成绩+1分查看 select `studentNo`,`studentResult`+1 as '加分后' from result

    数据库中的表达式 : 文本值,列,null,函数,计算表达式,系统变量…

    select 表达式 from 表

    4.3 where条件子句

    作用:检索数据中符合条件的值

    搜索的条件由一个或者多个表达式组成,结果布尔值

    逻辑运算符

    运算符语法描述and &&a and b a&&b逻辑与。两个都为真,结果为真or ||a or b a||b逻辑或。其中一个为真,则结果为真Not !not a ! a逻辑非。真为假,假为真 select `studentNo` `studentResult` from result -- 查询考试成绩在95~100分之间 select `studentNo` `studentResult` from result where studentResult>=95 and studentResult<=100 -- and && select `studentNo` `studentResult` from result where studentResult>=95 && studentResult<=100 --模糊查询(区间) select `studentNo` `studentResult` from result where studentResult between 95 and 100 --除了1000号学生之外的同学的成绩 select `studentNo` `studentResult` from result where studentNo!=1000 -- != not select `studentNo` `studentResult` from result where not studentNo = 1000

    模糊查询:比较运算符

    运算符语法描述is nulla is null如果操作符为null,结果为真is not nulla is not null如果操作符不为null,结果为真betweena bettween and c若a在b和c之间,则结果为真likea like bSQL匹配,如果a匹配b,则结果为真ina in (a1,a2,a3…)假设a在a1,或者a2…其中的一个值,就为真 -- 查询姓刘的同学 -- like结合 %(代表0到任意符号) _(一个字符) select studentNo,studentName from student where studentName like '刘%' -- 查询姓刘的同学,名字后面只有一个字的 select studentNo,studentName from student where studentName like '刘_' -- 查询名字中间有家字的同学 %家% select studentNo,studentName from student where studentName like '%家%' -- in(具体的一个或者多个值) -- 查询1001,1002,1003号学员 select studentNo,studentName from student where studentNo in(1001,1002,1003); -- 查询在北京和上海的学生 select studentNo,studentName from student where address in('北京','上海') -- 查询地址为空的学生 null '' select studentNo,studentName from student where adderss='' or address is null -- 查询有出生日期的同学, 不为空 select studentNo,studentName from student where bornDate is not null -- 查询没有有出生日期的同学 为空 select studentNo,studentName from student where bornDate is null

    4.4 联表查询

    JOIN 对比

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mzSKhvDl-1593573462693)(D:\有道云笔记\weixinobU7VjjsnV94OBfYaNJ_qqoIRbdg\b67caf7d50574ce2b6bb8774865d9e3d\3a272323170f465d95c8a8b7435e835e.jpg)]

    -- join (连接的表) on (判断的条件) 连接查询 -- where 等值查询 -- 两个表查询 -- inner join select s.studentNo,studentName,subjectNo,studentresult from student as s inner join result as r on s.studentNo = r.studentNo -- right join select s.studentNo,studentName,subjectNo,studentresult from student as s right join result as r on s.studentNo = r.studentNo --left join select s.studentNo,studentName,subjectNo,studentresult from student as s left join result as r on s.studentNo = r.studentNo --查询缺考的同学 --left join select s.studentNo,studentName,subjectNo,studentresult from student as s left join result as r on s.studentNo = r.studentNo where studenresult is null -- 三表查询 select s.studentNo,studentName,subjectName,studentresult from student as s right join result as r on s.studentNo = r.studentNo inner join subject as sub on r.subjectno = sub.subjectno -- 我要查询哪些数据,select... -- 从那几个表中查 from 表 ..Join 连接的表 on 交叉条件 -- 假设存在一种多表查询,慢慢来,先查询两张在慢慢的加 操作描述Inner join如果表中至少有一个匹配,就返回行left join会从左表中返回所有的值,即使右表中没有匹配right join会从右表中返回所有的值,即使左表中没有匹配

    自连接(了解)

    自己的表和自己的表连接,核心:一张表拆分为两张一样的表即可

    父类

    cateforyidcategoryName2信息技术3软件开发5美术设计

    子类

    pidcategoryidcategoryName34数据库28办公信息36web开发57ps技术

    操作:查询父类对应的子类关系

    父类子类信息技术办公信息软件开发数据库软件开发web开发美术设计ps技术

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6p4aefDD-1593573462697)(C:\Users\86131\AppData\Roaming\Typora\typora-user-images\image-20200525153024484.png)]

    -- 查询父子信息:把一张表看为两个一模一样的表 select a.categoryName as '父栏目',b.categoryName as '子栏目' from category as a ,category as b where a.categoryid=b.pid

    例子

    例子1:查询学员所属的年级(学号,学生的姓名,年级名称)(两张表查询) select studentNo,studentName,gradeName from student s inner join grade g on s.gradeId = g.gradeId 例子2:查询科目所属的年级(科目名称,年级名称)(两张表查询) select subjectName,gradeName from subject sub inner join grade g on sub.gradeId = g.gradeId 例子3:查询参加了 数据库结构 考试的同学信息:学号,学生姓名,科目名,分数 select s.studentNo,studentName,subjectName,studentResult from student s inner join result r on s.studentNo = r.studentNo inner join subject sub on r.subjectNo = sub.subjcetNo where subjectName = '数据库结构'

    4.5 分页和排序

    排序

    ASC :升序

    DESC :降序

    order by 通过那个字段排序,怎么排

    select s.studentNo,studentName,subjectName,studentResult from student s inner join result r on s.studentNo = r.studentNo inner join subject sub on r.subjectNo = sub.subjcetNo where subjectName = '数据库结构' order by studentResult ASC -- studentResult进行升序

    分页

    分页:每页只显示5条数据 select s.studentNo,studentName,subjectName,studentResult from student s inner join result r on s.studentNo = r.studentNo inner join subject sub on r.subjectNo = sub.subjcetNo where subjectName = '数据库结构' order by studentResult ASC limit 0,5 -- 第一页 limit 0,5 (1-1)*5 -- 第二页 limit 5,5 (2-1)*5 -- 第N页 limit 0,5 (n-1)*pagesize,pagesize -- pagesize:页面大小 -- (n-1)*pagesize:起始值 -- n:当前页 -- 页面总数/页面大小=总页数

    语法:limit(查询起始值下标,pagesize)

    子查询

    -- 连表查询 select studentNo,r.subjectNo,studentResult from result r inner join subject sub on s.studentNo = r.studentNo where subjectName = '数据库结构' order by studentResult DESC -- 子查询(由里及外) select s.studentNo,subjectNo,studentResult from result where subjectNo=( select subjectNo from subject where subjectName = '数据库结构' ) order by studentResult DESC

    嵌套查询(由里及外)

    select studentNo,studentName from student where studentNo in ( select studentNo from result where studentResult>80 and subjectNo =( select subjectNo from subject where subjectName = '数据库结构' ) )

    4.6 分组和过滤

    -- 查询不同课程的平均分,最高分,最低分 -- 核心:(根据不同的课程分组) select subjectname,avg(studentresult) as 平均分,max(studentresult),min(studentresult) from result r inner join `subject` sub on r.`subjectno` = sub.`subjectno` group by r.subjectno -- 通过什么字段来分组 having 平均分>80

    4.7 select 小结

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-raJ7G5Yj-1593573462700)(C:\Users\86131\AppData\Roaming\Typora\typora-user-images\image-20200630164943074.png)]

    5:MySQL函数

    5.1 常用函数

    -- 数学函数 select abs(-8) -- 绝对值 select ceiling(9.4) -- 向上取整数 select floor(9.4) -- 向下取整数 select rand() -- 返回一个0-1之间的随机数 select char_length('haha') -- 字符串长度 select concat('我','love') -- 字符串的拼接 select lower('hh') -- 小写转大写 select upper('HH') -- 大写转小写 -- 时间和日期函数 select current_date() -- 获取当前的时间 select curdate() -- 获取当前日期 select now() -- 获取当前时间 select localtime() -- 本地时间 select sysdate() -- 系统时间 -- 系统 select system_user() select user() select version()

    5.2 聚合函数

    函数名称描述count()计数sum()求和avg()平局值max()最大值min()最小值…… -- 都能够统计,表中的数据 (查询表中有多少记录) select count(`字段名`) from 表名; -- count(字段名),会忽略所有的null值 select count(*) from 表名; -- count(*) ,不会忽略null值,本质计算行数 select count(1) from 表名; -- count(1) ,不会忽略所有的null值,本质计算行数 selecct sum(`字段名`) as 总分 from 表名 selecct avg(`字段名`) as 平均分 from 表名 selecct max(`字段名`) as 最高分 from 表名

    5.3 数据库级别的MD5加密

    什么是MD5

    主要增强算法复杂度和不可逆性MD5不可逆

    MD5破解网站的原理,背后是一个字典,MD5加 密后的值,加密后的值

    -- 插入的时候加密 insert into test values(1,'小明',MD5('123')) -- 如何校验:将用户传递进来的密码,进行MD5加密,然后比对加密后的值 select * from test where name='小明' and pwd=MD5('123')

    6:事务

    要么都成功,要么都失败


    1:sql执行 a给b转账 a 1000 ---->100 b200

    2:sql执行,b收到钱 a 800 ------>b 300


    事务原则:ACID原则 原子性,一致性,隔离性,持久性

    原子性(Atomicity)

    要么成功,要么失败

    一致性(Consistency)

    事务前后数据完整性要保证一致

    持久性(Durability)

    事务一旦提交则不可逆,被持久化到数据库中

    隔离性(Isolation)

    事务的隔离性是多个用户并发访问数据库时,数据库为每个用户开启的事务,不能被其他的操作数据所干扰,事务之间要互相隔离

    隔离所导致的一些问题

    脏读

    指一个事务读取了另外一个事务未提交的数据

    不可重复读

    在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误的,只是某些场合不对)

    虚读(幻读)

    是指一个事务内读取到了别的事务插入的数据,导致前后读取不一致

    测试事务

    -- 模拟转账,事务 set autocommit = 0;-- 关闭自动提交 start transaction -- 开启一个事务(一组事务) update account set momney=moey-500 where `name` = 'a' -- a减去500 update account set momney=moey+500 where `name` = 'b' -- b加去500 commit; -- 提交事务,就被持久化了 bollback; -- 回滚 set autocommit = 1; -- 恢复自动提交

    7:索引

    MySQL官方对索引的定义为:索引是帮助MySQL高效获取数据的数据结构

    提取句子主干,就可以得到索引的本质:索引是数据结构

    7.1 索引的分类

    在一个表中,主键索引只能有一个,唯一索引有多个

    主键索引(primary key) 唯一的表示,主键不可重复,只能有一个列作为主键 唯一索引(unique key) 避免重复的列出现,唯一索引可以重复,多个列都可以标识为唯一索引 常规索引(key、index) 默认的,index,key关键字来设置 全文索引(fulltext) 在特定的数据库引擎下有,MyISAM快速定位数据

    基础语法

    -- 索引的使用 -- 1、在创建表的时候给字段增加索引 -- 2、创建完毕后,增加索引 -- 显示所有的索引信息 show index from student -- 增加一个全文索引(索引名) 列名 alter table school.student add fulltext insex `studentName`(`studentName`) -- EXPLAIN 分析sql执行的状况 explain select * from student; -- 非全文索引 explain select * from student where match(studentName) against('刘')

    索引在小数据量的时候,用处不大,但是在大数据的时候,区别十分明显

    7.2 索引原则

    索引不是越多越好不要对经常变动的数据加索引小数据的表不需要加索引索引一般加在常用来查询的字段上

    索引的数据结构

    Hash类型的索引

    Btree:InnoDB的默认结构

    8:数据库权限和备份

    8.1 用户管理

    SQLyog可视化管理

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vwBz3rlI-1593573462704)(C:\Users\86131\AppData\Roaming\Typora\typora-user-images\image-20200701101934622.png)]

    sql命令

    -- 创建用户 create user 用户名 inentified by '密码' create user hello inentified by '123456' -- 修改密码 (修改当前用户 密码) set password = password('123456') --修改密码 set password for hello = password('123456') -- 重命名 rename user hello to hello1 -- 用户授权 All privileges 全部的权限,库,表 -- All privileges 除了给别人授权,其他都能够干 grant all privileges on *.* to hello1 -- 权限查询 show grants for hello1 -- 查看指定用户的权限 show grants for root@localhost -- 撤销权限 revoke 哪些权限,在哪个库撤销,给谁撤销 revoke all privileges on *.* from hello1 -- 删除用户 drop user hello1

    8.2 MySQL备份

    为什么要备份

    保证重要的数据不丢失数据转移

    MySQL数据库备份的方式

    直接拷贝到物理层在sqlyog可视化工具中手动导出 在想要导出的表或者库中,右键,选择备份或者导出

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eNZjm2Kt-1593573462709)(C:\Users\86131\AppData\Roaming\Typora\typora-user-images\image-20200701103412735.png)]

    使用cmd命名行导出 mysqldump 命令行使用 # mysqldump -h 主机 -u 用户名 -p 密码 数据库 表名 > 物理磁盘/文件名 mysqldump -hlocalhost -uroot -p123456 school student > D:/a.sql # mysqldump -h 主机 -u 用户名 -p 密码 数据库 表名1 表名2 > 物理磁盘/文件名 mysqldump -hlocalhost -uroot -p123456 school student student2 > D:/a.sql # mysqldump -h 主机 -u 用户名 -p 密码 数据库> 物理磁盘/文件名 mysqldump -hlocalhost -uroot -p123456 school > D:/a.sql #登入 #登录的情况下,切换到指定的数据库 #source 备份文件 source d:/a.sql

    假设你要备份数据库,防止数据丢失。

    把数据库给朋友,sql文件给别人即可

    9:规范数据库设计

    9.1 为什么需要设计

    当数据库比较复杂的时候,我们就需要设计了

    糟糕的数据库设计:

    数据冗余,浪费空间数据库插入和删除都会比较麻烦,异常【屏蔽使用物理外键】程序的性能差

    良好的数据库设计:

    节省内存空间保证数据库的完整性方便我们开发系统

    软件开发中,关于数据库的设计

    分析需求:分析业务和需要处理的数据库的需求概要设计:设计关系图E-R图

    9.2 数据库的三大范式

    为什么需要数据库范式

    信息重复更新异常插入异常 无法正常显示信息 删除异常 丢失有效的信息

    三大范式

    第一范式

    原子性:保证每一列不可再分

    第二范式

    前提:满足第一范式

    每张表只描述一件事情

    第三范式

    前提:满足第一范式和第二范式

    第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关

    规范和性能问题

    关联查询的表不得超过三张表

    考虑商业化的需求和目标,(成本和用户体验)数据库的性能更加重要在规范性能的问题的时候,需要适当的考虑一下规范性故意给某些表增加一些冗余字段。(从多表查询中变为单表查询)故意增加一些计算列。(从大数据量降低为小数据量的查询:索引)
    Processed: 0.012, SQL: 9