zoukankan      html  css  js  c++  java
  • MySQL基础总结

    MySql

    常用的数据库操作

    CREATE DATABASE IF NOT EXISTS Gao_Mysql --创建数据库
    

    删除数据库

    drop database Gao_Mysql
    

    数据库的列类型

    数值

    • tinyint 十分小的数据 1个字节

    • smallint 较小的数据 2个字节

    • mediumint 中等大小的数据3个字节

    • int标准的整数 4个字节 常用的int

    • bigint 较大的数据 8个字节

    • float 浮点数 4个字节

    • double 浮点数 8个字节(精度问题! )

    • decimal 字符串形式的浮点数 金融计算的时候, 一般是使用decimal

    字符型

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

    时间类型

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

    数据库的字段属性

    Unsigned

    • 无符号的整数
    • 声明了该列不能是负数。

    zerofill

    • 0填充的。
    • 不足的位数用零来填充 int(3) 5 --> 005

    自增

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

    非空

    • 假设设置为not null ,如果不给它赋值,就会报错!
    • NUII .如果不填写值,默认就是nul!

    数据库建表

    CREATE TABLE IF NOT EXISTS `Gao_Mysql`(
                  `id` INT(8) NOT NULL primary key  COMMENT '学号',
                  `name` VARCHAR(10) NOT NULL DEFAULT '帅' COMMENT '姓名',
                  sex VARCHAR(2) NOT NULL DEFAULT '男' COMMENT '性别',
                  adress VARCHAR(30) DEFAULT NULL COMMENT '地址',
                  birthday VARCHAR(10) DEFAULT NULL COMMENT '出生日期',
                  pwd VARCHAR(20) NOT NULL DEFAULT '123456' COMMENT '密码',
                  email VARCHAR(20) DEFAULT NULL COMMENT '邮箱地址'
    )ENGINE=INNODB DEFAULT CHARACTER SET UTF8;
    
    

    格式:

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

    数据表类型

    /*
    INNODB 默认使用~
    MYISAM 早些年使用的
    */
    
    MYISAM INNODB
    事务支持 不支持 支持
    数据行锁定 不支持 支持
    外键约束 不支持 支持
    全文索引 支持
    表空间的大小 较小 较大 约为MYISAM的2倍
    • MYISAM 节约空间 速度较快。
    • INNODB 安全性较高 支持事务的处理。
    一张表,里面有 ID 自增主键,当 insert 了 17 条记录之后,删除了第 15,16,17 条记录,再把 Mysql 重启,再 insert 一条记录,这条记录的 ID 是 18 还是 15 ?
    
    (1)如果表的类型是 MyISAM,那么是 18。因为 MyISAM 表会把自增主键的最大 ID 记录到数据文件里,重启 MySQL 自增主键的最大ID 也不会丢失
    
    (2)如果表的类型是 InnoDB,那么是 15
    InnoDB 表只是把自增主键的最大 ID 记录到内存中,所以重启数据库或者是对表进行OPTIMIZE 操作,都会导致最大 ID 丢失
    

    修改和删除数据表字段

    ALTER table sex_ RENAME AS gao_mysql; --表的重命名
    
    ALTER TABLE gao_mysql ADD Gao VARCHAR(20);-- 添加字段
    
    -- ALTER TABLE  表名  MODIFY 字段名  列属性[]
    alter TABLE gao_mysql MODIFY Gao varchar(20);--修改字段的约束
    
    -- ALTER TABLE  表名  CHANGE 旧名字  新名字  列属性[]
    
    alter table gao_mysql change gao Gaoshuai varchar(20) --修改字段的名字
    
    alter table gao_mysql drop gao --删除属性列  删除表的字段: ALTER  TABLE  表名  DROP  字段名
    
    

    添加外键约束

    alter table gao_mysql ADD constrant `FK_grade` Foreign key('gradeID') reference grade('gradeID')
    -- ALTER TABLE表  ADD CONSTRAINT(约束) 约束名 FOREIGN KEY(作为外键的列) REFERENCES 那个表(哪个字段)
    
    

    Inster

    insert into gao_mysql(id,name,sex,adress) VALUES ('20183529','高帅','男','石家庄');
    
    insert into gao_mysql(name,sex,adress) VALUES ('蔡鹏瑞','男','朔州');
    
    insert into gao_mysql(name,sex,birthday) VALUES ('田永平','男','2001-01-06'),('刘贺鑫','男','1999-02-22');
    
    

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

    UPDATE

    UPDATE 表名 set COInum_ name=value,[ COInum_name=value,....] where [条件]

    操作符 含义 范围 结果
    = 等于
    <>或者!= 不等于
    <
    >
    >=
    <=
    between...and... 在...之间 [2,5]
    and &&
    or ||

    删除

    delete 命令

    语法:delete from 表名 where 条件

    truncate命令 清空一张表 表的结构 索引 约束都不会改变。

    语法: truncate 表名

    delete和truncate对比

    相同点:

    • 都可以删除数据,不会删除表结构。

    不同点:

    • truncate 重新设置自增列 自增回归零
    • truncate 不会影响事务

    delete删除问题

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

    DQL查询语句

    1631860530263

    --查询全部的学生 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
    

    去重 distinct

    
    select DISTINCT DIST_NAME from t_corp_dist;   --(对重复的数据只显示一条
    
    select DISTINCT DIST_NAME,concat('高帅:', FARE_PLACE) as '新地址' FROM t_corp_dist;
    

    where条件语句

    select DISTINCT DIST_NAME from t_corp_dist where DIST_CORP_SEQ_ID = 5;
    
    select DISTINCT DIST_NAME from t_corp_dist where DIST_CORP_SEQ_ID != 5;
    
    select DISTINCT DIST_NAME from t_corp_dist where DIST_CORP_SEQ_ID BETWEEN 5 and 7;
    

    模糊查询

    运算符 语法 结果
    is null a is null
    is not null b is not null
    between ... and... a between b and c
    like a like b sql匹配 如果a匹配b 则为true
    in a in (b1,b2,b3...) (完全匹配) a在b1,b2,b3中的一个则为true
    select inst from users WHERE `Status` BETWEEN 0 and 1;
    
    --username中有g字母的
    select id,inst from users where username like '%g%';
    
    --username中以g开头的
    select id,inst from users where username like 'g%';
    
    --  %匹配0到任意个字符  _ 匹配一个字符
    
    select id, inst from users where username in ('gaoshuai','gs12%'); -- in 是完全匹配
    

    联表查询

    -- 查询参加了考试的同学信息(学号,学生姓名,科目编号,分数)
    select r.studentno,studentname,subjectno,studentresult 
    from  student s
    INNER JOIN result r
    on s.studentno = r.studentno;
    
    -- 查询参加了考试的同学信息(学号,学生姓名,科目编号,分数)
    select r.studentno,studentname,subjectno,studentresult 
    from  student s
    left JOIN result r
    on s.studentno = r.studentno;
    
    select *
    from  student s
    left JOIN	result r
    on s.studentno = r.studentno;
    
    -- 查询缺考的同学
    select r.studentno,studentname,subjectno,studentresult 
    from  student s
    left JOIN	result r
    on s.studentno = r.studentno
    where studentresult is NULL;
    
    -- 思考题:查询参加了考试的同学信息(学号,学生姓名,科目名,分数)
    select s.studentno,studentname,subjectname,studentresult
    from student s
    left join result r
    on s.studentno = r.studentno
    left join `subject` sub
    on r.subjectno = sub.subjectno
    where studentresult is not null;
    

    图解:1631846954428

    内连接:

    要点:返回的是所有匹配的记录。

    1. select * from a,b where a.x = b.x ////内连接
    2. select * from a cross join b on a.x=b.x order by a.x //不同写法的内连接
    3. select * from a inner join b on a.x=b.x order by a.x //不同写法的内连接

    外连接有左连接和右连接两种。

    要点:返回的是所有匹配的记录 外加 每行主表外键值为null的一条记录。辅表所有列为null值。

    1. select * from a left join b on a.x=b.x order by a.x //左外连接或称左连接
    2. select * from a right join b on a.x=b.x order by a.x //右外连接或称右连接

    练习:

    -- 思考题:查询参加了考试的同学信息(学号,学生姓名,科目名,分数)
    
    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.subjectno
    where studentresult is not null
    
    
    -- 查询学员及所属的年级(学号,学生姓名,年级名)
    SELECT studentno,studentname,gradename 
    from student s
    inner join grade g
    on s.gradeid = g.gradeid;
    
    
    -- 查询科目及所属的年级(科目名称,年级名称)
    select subjectname '科目名称',gradename 
    from `subject` sub
    inner join grade g
    on sub.gradeid = g.gradeid;
    
    

    排序与分页

    排序的关键字是 order by DESC是降序 ASC是升序。

    -- 查询 所有考试结果(学号 学生姓名 科目名称 成绩)
    -- 按成绩降序排序
    
    select s.studentno,studentname,subjectname,studentresult
    from student s
    inner join result r
    on s.studentno = r.studentno
    inner join `subject` sub
    on sub.subjectno = r.subjectno
    ORDER BY studentresult DESC;
    
    select s.studentno,studentname,subjectname,studentresult
    from student s
    inner join result r
    on s.studentno = r.studentno
    inner join `subject` sub
    on sub.subjectno = r.subjectno
    where studentresult is not null
    ORDER BY studentresult ASC;
    
    

    分页:

    
    
    -- 每页显示5条数据
    SELECT s.studentno,studentname,subjectname,StudentResult
    FROM student s
    INNER JOIN result r
    ON r.studentno = s.studentno
    INNER JOIN `subject` sub
    ON r.subjectno = sub.subjectno
    WHERE subjectname='数据库结构-1'
    ORDER BY StudentResult DESC , studentno
    LIMIT 0,5
    

    练习

    -- 查询 JAVA第一学年 课程成绩前10名并且分数大于80的学生信息(学号,姓名,课程名,分数)
    select s.studentno,studentname,subjectname,studentresult
    from student s
    join result r
    on s.studentno = r.studentno
    join `subject` sub
    on sub.subjectno = r.subjectno
    where studentresult>80 and subjectname = '高数'
    order by studentresult DESC
    limit 0,10;
    

    子查询

    -- 查询 数据库结构-1 的所有考试结果(学号,科目编号,成绩),并且成绩降序排列
    select s.studentno,r.subjectno,studentresult 
    from student s 
    join result r 
    on s.studentno = r.studentno
    join `subject` sub
    on r.subjectno = sub.subjectno
    order by studentresult DESC
    where subjectname = '高数';
    
    
    -- 子查询完成
    select studentno,subjectno,studentresult 
    from result r
    where subjectno = (
    select subjectno from `subject` where subjectname = '高数'
    )
    order by studentresult DESC;
    
    -- 查询课程为 高数 且分数不小于80分的学生的学号和姓名
    -- 方法一:使用连接查询
    SELECT s.studentno,studentname
    FROM student s
    INNER JOIN result r
    ON s.`StudentNo` = r.`StudentNo`
    INNER JOIN `subject` sub
    ON sub.`SubjectNo` = r.`SubjectNo`
    WHERE subjectname = '高数' AND StudentResult>=80
     
    -- 方法二:使用连接查询+子查询
    -- 分数不小于80分的学生的学号和姓名
    SELECT r.studentno,studentname FROM student s
    INNER JOIN result r ON s.`StudentNo`=r.`StudentNo`
    WHERE StudentResult>=80
     
    -- 在上面SQL基础上,添加需求:课程为 高等数学-2
    SELECT r.studentno,studentname FROM student s
    INNER JOIN result r ON s.`StudentNo`=r.`StudentNo`
    WHERE StudentResult>=80 AND subjectno=(
        SELECT subjectno FROM `subject`
        WHERE subjectname = '高数'
    )
    
    
    -- 查 高数 的前5名学生的成绩信息(学号,姓名,分数) 使用子查询,查询郭靖同学所在的年级名称
    select s.studentno,studentname,studentresult 
    from student s 
    join result  r
    on s.studentno = r.studentno
    where subjectno = (
    select subjectno from `subject` where subjectname = '高数'
    )
    ORDER BY studentresult DESC
    limit 0,5;
    
    -- 查询郭靖同学所在的年级名称
    
    select gradename 
    from grade g
    join student s
    on g.gradeid = s.gradeid
    where studentname = '李佳伟'
    
    select gradename 
    from grade 
    where gradeid = (
    select gradeid from student where studentname = '李佳伟'
    )
    

    聚合函数

    函数名称 描述
    count() 返回满足Select条件的记录总和数,如 select count(*) 【不建议使用 *,效率低】
    sum() 返回数字字段或表达式列作统计,返回一列的总和。
    avg() 通常为数值字段或表达列作统计,返回一列的平均值
    max() 可以为数值字段,字符字段或表达式列作统计,返回最大的值。
    min() 可以为数值字段,字符字段或表达式列作统计,返回最小的值。
    -- 聚合函数
     /*COUNT:非空的*/
     SELECT COUNT(studentname) FROM student;
     SELECT COUNT(*) FROM student;
     SELECT COUNT(1) FROM student;  /*推荐*/
     
     -- 从含义上讲,count(1) 与 count(*) 都表示对全部数据行的查询。
     -- count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况。即不统计字段为null 的记录。
     -- count(*) 包括了所有的列,相当于行数,在统计结果的时候,包含字段为null 的记录;
     -- count(1) 用1代表代码行,在统计结果的时候,包含字段为null 的记录 。
     /*
     很多人认为count(1)执行的效率会比count(*)高,原因是count(*)会存在全表扫描,而count(1)可以针对一个字段进行查询。其实不然,count(1)和count(*)都会对全表进行扫描,统计所有记录的条数,包括那些为null的记录,因此,它们的效率可以说是相差无几。而count(字段)则与前两者不同,它会统计该字段不为null的记录条数。
     
     下面它们之间的一些对比:
     
     1)在表没有主键时,count(1)比count(*)快
     2)有主键时,主键作为计算条件,count(主键)效率最高;
     3)若表格只有一个字段,则count(*)效率较高。
     */
     
     SELECT SUM(StudentResult) AS 总和 FROM result;
     SELECT AVG(StudentResult) AS 平均分 FROM result;
     SELECT MAX(StudentResult) AS 最高分 FROM result;
     SELECT MIN(StudentResult) AS 最低分 FROM result;
    
    
    
    -- 查询不同课程的平均分,最高分,最低分
     -- 前提:根据不同的课程进行分组
     
     SELECT subjectname,AVG(studentresult) AS 平均分,MAX(StudentResult) AS 最高分,MIN(StudentResult) AS 最低分
     FROM result AS r
     INNER JOIN `subject` AS s
     ON r.subjectno = s.subjectno
     GROUP BY r.subjectno
     HAVING 平均分>80;
     
     /*
     where写在group by前面.
     要是放在分组后面的筛选
     要使用HAVING..
     因为having是从前面筛选的字段再筛选,而where是从数据表中的>字段直接进行的筛选的
     */
    

    总结

    1631866415543

    事务

    什么是事务

    • 事务就是将一组SQL语句放在同一批次内去执行
    • 如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行
    • MySQL事务处理只支持InnoDB和BDB数据表类型

    事务的ACID原则 百度 ACID

    • 原子性(Atomic)

    整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(ROLLBACK)到事务开始前的状态,就像这个事务从来没有执行过一样。

    • 一致性(Consist)

    一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。也就是说:如果事务是并发多个,系统也必须如同串行事务一样操作。其主要特征是保护性和不变性(Preserving an Invariant),以转账案例为例,假设有五个账户,每个账户余额是100元,那么五个账户总额是500元,如果在这个5个账户之间同时发生多个转账,无论并发多少个,比如在A与B账户之间转账5元,在C与D账户之间转账10元,在B与E之间转账15元,五个账户总额也应该还是500元,这就是保护性和不变性。

    • 隔离性(Isolated)

    隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。

    • 持久性(Durable)

    在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。 事务一旦提交是不可逆的

    事务的基本语法

    
    -- 使用set语句来改变自动提交模式
    SET autocommit = 0;   /*关闭*/
    SET autocommit = 1;   /*开启*/
     
    -- 注意:
    ---  1.MySQL中默认是自动提交
    ---  2.使用事务时应先关闭自动提交
     
    -- 开始一个事务,标记事务的起始点
    START TRANSACTION  
     
    -- 提交一个事务给数据库
    COMMIT
     
    -- 将事务回滚,数据回到本次事务的初始状态
    ROLLBACK
     
    -- 还原MySQL数据库的自动提交
    SET autocommit =1;
     
    -- 保存点
    SAVEPOINT 保存点名称 -- 设置一个事务保存点
    ROLLBACK TO SAVEPOINT 保存点名称 -- 回滚到保存点
    RELEASE SAVEPOINT 保存点名称 -- 删除保存点
    
    

    三大范式

    • 第一范式 (1st NF)

      • 第一范式的目标是确保每列的原子性,如果每列都是不可再分的最小数据单元,则满足第一范式

      • 1631883016473

        地址可能不符合第一范式

    • 第二范式(2nd NF)

      • 第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
      • 第二范式(2NF)属性完全依赖于主键
      • 1631883153569
    • 第三范式(3rd NF)

      • 如果一个关系满足第二范式,并且除了主键以外的其他列都不传递依赖于主键列,则满足第三范式.

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

      • 第三范式(3NF)属性不依赖于其它非主属性 属性直接依赖于主键

      • 数据不能存在传递关系,即每个属性都跟主键有直接关系而不是间接关系。像:a-->b-->c 属性之间含有这样的关系,是不符合第三范式的。

        比如Student表(学号,姓名,年龄,性别,所在院校,院校地址,院校电话)

        这样一个表结构,就存在上述关系。 学号--> 所在院校 --> (院校地址,院校电话)

        这样的表结构,我们应该拆开来,如下。

        (学号,姓名,年龄,性别,所在院校)+(所在院校,院校地址,院校电话)

    • 规范化和性能的关系

      • 为满足某种商业目标 , 数据库性能比规范化数据库更重要
      • 在数据规范化的同时 , 要综合考虑数据库的性能
      • 通过在给定的表中添加额外的字段,以大量减少需要从中搜索信息所需的时间
      • 通过在给定的表中插入计算列,以方便查询

    范式越高,性能越差 需要找一个平衡点

  • 相关阅读:
    《手把手教你构建自己的 Linux 系统》学习笔记(7)
    《手把手教你构建自己的 Linux 系统》学习笔记(6)
    《手把手教你构建自己的 Linux 系统》学习笔记(5)
    《手把手教你构建自己的 Linux 系统》学习笔记(4)
    《手把手教你构建自己的 Linux 系统》学习笔记(3)
    《手把手教你构建自己的 Linux 系统》学习笔记(2)
    《手把手教你构建自己的 Linux 系统》学习笔记(1)
    Mac 下如何判断 WIFI 的极限传输速度还有信号强度?
    Mac 下如何快速重启 Dock 栏?
    编译器的工作过程
  • 原文地址:https://www.cnblogs.com/g414056667/p/15306498.html
Copyright © 2011-2022 走看看