1、学数据库需要知道哪些东西

  • 什么是数据库设计?
  • 数据库设计的步骤
  • 数据库概念模型
  • 会画、会看E-R图
  • 了解三大范式
  • 数据库的一些操作( 普通程序员也就停留在这里,即:CRUD程序员[ 增删查改 ] )

 

  • 1)、数据库设计
    • 根据用户的需求,在具体的数据库管理系统上,设计数据结构和建立数据库的过程

 

  • 2)、设计步骤
    • 需求分析 ——> 概念结构设计 ——> 逻辑结构设计 ——> 数据库的实施 ——> 数据库的运行与维护( 升级 )
      • 注:一般都是直接搞数据库实施了,但是数据库设计是一条路( 数据库架构师 ),就需要这么玩

 

  • 3)、数据库概念模型
    • (1)、相关概念
      • 数据:客观事物的描述 如:一个人有哪些? —— 姓名、年龄.....  
      • 数据库:长期保存到计算机中的有组织、可共享的数据集合  
      • 数据库管理工具( DBMS ):用来管理数据库的,负责建立数据库、使用、维护的软件,如:sqlyog、Navicat

 

    • (2)、概念模型
      • 基本
        • 实体:客观存在并相互区分的事物。类似于java中的类
        • 属性:实体具有的某一特征。和java中的属性一样
        • 键:主键、外键  
          • 主键:标识事物的唯一性,就像身份证号一样
          • 外键:是另一个事物的主键
        • 实体型:具有相同的实体必有的特征
        • 实体集:相同的实体类型的集合
        • 联系:实体之间的关系
          • 实体之间的关系:
            • 一对一、一对多 / 多对一、多对多

 

    • (3)、了解E-R图 —— 用来描述实体之间的关系。网上找图来看
      • 长方形:实体
      • 圆形:属性
      • 菱形:关系

 

    • (4)、三大范式
      • ①、范式的作用
        • 用来更好的设计数据库,专门用来让人遵循的规则,目的:减少数据冗余
      • 具体的三大范式
        • 第一范式:确保每一列的原子性( 原子性:即列的字段不可以再分出其他字段,如:学院,还可以分大数据与信息工程、文化与传媒学院... )
        • 第二范式:在第一范式的前提下,确保每张表只做一件事
        • 第三范式:在第一、第二范式的前提下,确保表中的每一列都与主键直接相关,而不是间接相关

 

  • 4)、数据库介绍
    • 大型数据库:DB2、Oracle( 个人认为:DB2比Oracle更好 )    一般是银行企业使用
    • 中型数据库:sqlServer
    • 小型数据库:mysql       一般是小型企业使用
    • 详细区分:
      • 关系型数据库
        • MySQL、SqlServer、DB2
        • 这种数据库是通过表与表之间、列与列之间进行数据的存储,如:学生表
      • 非关系型数据库
        • Redis、MongDB
        • 这种数据库是通过对象的属性来进行存储数据

 

  • 5)、学习数据库就用:mysql    sql语句都是相通的,只是有细微的区别而已
    • (1)、为什么使用mysql?
      • 易于学习和掌握
      • 性能高,即:访问速度较快
      • 最重要的一点:开源、免费

 

以上这些内容不明白的也没事儿,慢慢的就懂了

 

2、开始学习MySQL

  • 1)、安装MySQL ( 个人建议最好下载5.7版的,也有人说5.5稳定,但是我个人认为:5.7更稳定,另外到了公司就需要根据公司要求来弄版本)

 

    • (1)、下载MySQL地址:MySQL :: Download MySQL Community Server
      • 数据库 — 更新完毕
      • 注意:我这种是解压方式安装MySQL,有人也会用 .exe的方式进行安装( 但是:个人建议别用 . exe的方式进行安装,因为卸载麻烦,需要删除注册表中的MySQL ,不然卸载不干净 )
      • 然后:下载好之后,把压缩包解压到自己要放的盘符路径中即可 
      • 个人建议:最好单独建一个安装文件夹,然后安装一个程序 在里面新建一个文件夹,然后把路径选择进去

 

    • (2)、现在来正式进行安装  
      • ①、配置环境变量
        • 找到刚刚解压的MySQL压缩包,然后进到bin目录下,把这个路径复制一下,如:我的
          • 数据库 — 更新完毕
      • ②、进到电脑的path目录中,然后把复制的路径加进去,最后保存( 怎么进到path中去,win10、win7的区别就不用说明了吧 )
      • ③、再次回到刚刚的解压包那里,即:bin的上一级,然后建一个my.ini配置文件,如:我的
        • 数据库 — 更新完毕
      • ④、用记事本 / 自己配置的其他软件( 如:我是用notepad++ )打开这个文件夹,创建如下内容:
        • 数据库 — 更新完毕

           注意:盘符路径切换成自己的,即:D:............mysql-5.7.34的路径。另外:注意[ ] 是英文输入法下打出来的,这种已经不想再说明了,吐了,因为:javaSE的时候已经说明过N多次了

      • ⑤、在自己的电脑上找到命令提示符,用管理员身份打开切记:一定要用管理员身份打开,不然配置不成功
        • 数据库 — 更新完毕
      • ⑥、进到Dos窗口之后( 即:上面的命令提示符 ),把路径切换到自己刚刚解压的压缩包的bin目录下,然后输入 mysqld -install 这是在安装mysql。切记:-install前面有一个空格,注意看结果,success / OK,不然安没安装成功都进行下一步了。如下:
        • 数据库 — 更新完毕

 

        • 额外补充一下:这里使用mysql -install时,有可能自己的电脑会报:msvcr120.dll找不到,尝试重装程序可能得以解决
          • 这种问题一是买电脑商家给你装系统时把你小小的坑了一下,没给你装这些系统程序( 一般都不会这样,在官铺买的电脑不会这么整人的啊 )
          • 第二种情况就是最常见的情况:自己把系统进行升级了,这也是必经的一个过程 ( 就是自己的电脑买来的时候发现是家庭版的,然后自己把系统升级到专业版了 —— 注:如果自己的电脑是家庭版的,那么就自己去官网下载专业版,然后找别人 / 自己买一个专业版密钥,把自己的电脑重装系统,弄为专业版,然后通过密钥永久激活 。如果自己的电脑不是专业版的,那么现在玩玩没什么,但是到了后面玩分布式开发时,总会因为家庭版的原因发生各种各样的问题 )
            • 回到正题:这种把系统升级之后,发生这种msvcr120.dll文件找不到是因为自己对系统进行升级时操作不当 / 下载的系统有问题,从而导致重装系统之后根本没有这个msvcr120.dll文件( 一般发生这种情况了,少的不止这一个文件,而是起码有近10个文件是缺失的 )
            • 解决办法:下载修复工具,把缺失的文件补回来
            • 打开解压包,运行下面的程序,然后跟着步骤来就可以了
              • 数据库 — 更新完毕

 

          • 如果经过上面的方式都还没解决的话,那就问题更大了,自行百度找适合自己电脑的解决方案吧

    

      • ⑦、上一步成功之后,然后再输入 mysqld --initialize-insecure --user=mysql  这是初始化数据文件( 即:在my.ini中datadir后面有一个data,这里就是初始化这个data,然后在目录中自动生成data文件夹 )
        • 注意:--initialize前面是有一个空格 和 两个 - 。user前面也是一样的
        • 数据库 — 更新完毕

           成功之后,它会自动跳转到bin目录

 

      • ⑧、退出Dos窗口,重新进去( 不用管理员也可以 )输入命令 mysql -uroot -p 回车,在输入password( 即:密码)时直接回车,因为在配置my.ini时有一个skip跳过密码登录的配置,成功进到sql之后,目录名字变了,成为了mysql,如下:
        • 数据库 — 更新完毕

           

        • 数据库 — 更新完毕

           解决办法:我接下来的最后一步那里,开启mysql服务 使用命令开启 或 快捷键ctrl+alt+delete,选择任务管理器,选择服务,把mysql服务开启

      • ⑨、进入到mysql之后,开始更改mysql的登录密码输入 update mysql.user set authentication_string = password( '这里面就是自己要设置的mysql密码' ) where user = 'root' and Host = 'loaclhost';  
        • 数据库 — 更新完毕
        • 注意事项:
          • password里面就是以后登录数据库的密码,所以一定需要记住,不然很头疼
          • 最重要的一点:上述语句是 ; 分号结尾的,千万别漏掉这个了
          • 多提一嘴:上述的指令就是一个数据库的修改指令而已,数据库本质是文件,所以上述命令就是修改文件( 数据库中说的表 ) 的信息而已

 

      • ⑩、刷新权限。上述的修改密码执行成功之后,接着输入 flush privileges;
        • 数据库 — 更新完毕
        • 注意事项:
          • 还是记得 ; 分号结尾
          • 在这一步可能会由于自己电脑的配置、性能等乱七八糟的原因导致在这里显示配置成功了,但是后面使用密码登录数据库时却发现登录不进去
            • 因此建议:这里的刷新权限多执行几次
      • 取消无密码登录数据库。回到my.ini文件中,把那个skip跳过密码登录语句注释掉( 在前面加一个 # 就搞定了 ),如下:
        • 数据库 — 更新完毕

           

           

      • 最后重启mysql服务,有两种方式
        • 1)、使用命令关闭 / 开启
          • 退出刚刚的Dos窗口,再重新进去( 记得以管理员身份进去 ) 输入 net stop mysql  这是关闭mysql服务,记得先关闭mysql服务,然后再开启,这样才可以让刚刚做的那些操作生效。
          • 等成功关闭之后,接着输入 net start mysql 这是开启mysql服务
          • 数据库 — 更新完毕

 

        • 2)、手动开启 / 关闭mysql,直接按 ctrl + alt + delete , 选择任务管理器,选择服务,找到mysql,然后鼠标右键停止 / 开启
          • 数据库 — 更新完毕

             

      • 以防万一:还是测试一下吧,看看有没有配置成功
        • 进到Dos窗口中( 不用管理员身份都行 ),即:win + r,然后输入cmd确认进去
          • 数据库 — 更新完毕

             

             

      • 要卸载mysql就只需要:把解压的文件删除就行
        • 注:需要彻底删除 即:选择文件夹 按shift+delete彻底删除( 回收站都找不到 )

 

 

  • 2)、数据库安装好了之后,数据库管理工具可以采用Navicat / sqlyog.... ——— 数据库管理工具就是一个连接数据库,然后方便人看的可视化工具( 不然在Dos窗口中做数据库不得麻烦死 )
    • 注:Navicat使用注册机破解 / sqlyog注册码这些我不进行说明,留点空白,自行摸索。
    • 另:我用的是sqlyog,所以我的示例是sqlyog写的,不过不影响,语法都一样,只是可视化界面不一样而已

 

  • 3)、开始玩数据库
    • 1、准备工作:基础知识
      • (1)、数据库的类型( 这是对于数据库本身而言的 )
        • ①、数据库列字段的类型
          • 壹、数值类型
            •  tinyint    十分小的数据    1字节
            • smallint    较小的数据       2字节
            • mediumint   中等大小的数据    3字节
            • int             标准的整数      4字节( 常用 )
            • bigint         较大的数据      8字节
            • float           单精度浮点数   4字节
            • double         双精度浮点数   8字节
            • decimal       字符串形式的浮点数    一般金融相关会用这个decimal  

 

          • 贰、字符串
            • char           固定大小的字符串( 不可变长字符串 )        取值是0 · 255
            • varchar      可变字符串( 会随着内容的增加而自动增加长度 )        取值0 · 65535         java中String类型,在数据库中就可以用这个来对应
            • tinytext        微型文本串   取值2^8 - 1
            • text              大文本       取值2^16 - 1 ( 就像写博客这种,就是需要很大的空间来装,就可以用text )

 

          • 叁、时间日期  ———— 和java中java.util.Data包下的这个data对应的日期差不多
            • data        日期格式,如:YYYY-MM-DD
            • time        时间格式,如:HH:mm:ss
            • datetime  标准时间格式,如:YYYY-MM-DD HH:mm:ss ( 最常用 )
            • timestamp  时间戳  1970.1.1开始 — 现在的毫秒数 ( 也常用 )
            • year  表示年份

 

          • 肆、null
            • 没有值,未知
            • 注意:别用null进行运算,最终的结果为:null

 

 

        • ②、数据库行字段的类型( 重点 )
          • Unsigned   无符号整数   即:声明该列不能为负数
          • zerofill        用o填充        即:数值的位数不够的时候    如:int(5)        输入的值是4  那么在存储的时候这个位数不够,则:就会用00004来保存
          • auto_increment     自增( 通常是用来设置唯一的主键 )    即:自动在上一条的基础上+1( 默认是这样 )
            • 注意:这个必须是整型才可以,如:int,不然会报错
            • 这个可以在后面自己添加自增的步长是多少
          • not null      非空      即:必须填内容,不填就会报错
          • default       默认值     即:设置默认的值,在需要设置默认值的字段中使用default这个关键字,然后后面跟想要设置默认值即可( 注意:自己定义的字段的列类型啊
            • 别搞个:字段的列类型是int , 然后用default '默认值',这样搞个字符串类型的默认值,这要不得啊

 

      • (2)、对于数据库里面 —— 即:对于表本身
        • ①、数据库引擎( 详细的知识最好学完自行去百度一下,初学者会看不懂,留个印象,学完数据库的全部知识,再把这个引擎看一下,上档次的面试贼喜欢问 ,还有后面要玩的索引,数据库优化[ 最低要求答出7条以上 ] )
          • MYISAM   —— 这是早些年使用的
          • INNODB   —— 后面出现的
            • 数据库 — 更新完毕

               由图来看:INNODB更好,但是:在某些时候,MYISAM更爽

 

          • MYSIAM   节约空间 速度较快
          • INNODB   安全性高  支持事务处理 多表多用户操作

 

        • ②、数据库中表在物理空间的位置
          • 都在自己安装的数据库目录中的data文件夹下,一个文件夹对应一个数据库,里面就有相应的表
            • 数据库 — 更新完毕

               

              对图中几个文件后缀的说明:

              • INNODB引擎,在数据库表中只有一个*.frm的文件 和 上一级目录的ibd
              • MYISAM引擎:
                • *.frm    表结构定义的文件
                • *.myd   数据文件( data)
                • *.myi    索引文件( index )

 

        • ③、设置数据库表的默认编码 charset = utf8
          • 直接打开my.ini,在里面配置如下:
            • 数据库 — 更新完毕
          • 不设置的话:表的默认编码是Latinl  这种编码不支持中文( 图中内容和我不一样的,这没影响的啊,因为那是我设置的默认时区 —— 这是后续使用IDEA链接数据库时的一个小bug )

 

 

    • 2)、开始玩sql语法
      • 玩数据库玩的是什么?
        • 数据库本身 > 数据库中的表 > 数据库表中的信息( 数据 )

 

      • (1)、对于数据库本身 —— 创建、使用、删除、查看数据库
        •  先讲一下数据库中的注释
          • 行注释
            • -- 注释内容  
              • 注意:--之后是空了一格的  这也是我在java基础篇中说 // 注释内容 空一格的原因,就是为了给这里养成习惯
          • 多行注释
            • /* 注释内容 */

 

          • -- mysql中不区分大小写  数据库中的符号输入 和 java中一样 是英文输入法下打出的
            -- 链接数据库在安装数据库时已经玩了 即:mysql -uroot -p 所以不再演示
            -- 当然:后面这些都是通过语句来玩的,只要安装了数据库管理工具( 即:数据库的可视化软件 ) 是可以通过鼠标点击式玩的
            
            -- 1、创建数据库
            /*
                语法:
                    create database [ if not exists ] 要创建的数据库名;
                    注意:每一个sql语句结束,最好使用 ; 分号结尾
            */
            CREATE DATABASE IF NOT EXISTS `sqlstudy`; 
            -- 选择这一句运行就行了 后续的也是一样的 -- `sqlstudy` 外面的` ` 是tab按键上面 esc按键下面的那个按键( 即:在js中说的那个飘儿字符 ) -- 加这个飘儿字符的原因,为了解决字段与数据库中本身有的名字冲突的情形
            —— 这个在数据库中解决字段冲突都通用
            -- IF NOT EXISTS是为了判断要创建的数据库在数据库是否存在,如果不存在才创建 这也是为了严谨性 -- 所以创建时最好加上这个逻辑判断( 当然只要保证数据库中并没有要创建的这个数据库,则不要这句话也行的 )

            -- 2、删除数据库 /* 语法: drop database [ if exists ] 要删除的数据库名 */ DROP DATABASE IF EXISTS `sqlstudy`; -- 这里最好也加上判断

            -- 3、使用数据库 /* 语法: use 要使用的数据库名 */ USE `sqlstudy`;

            -- 4、查看数据库 /* 语法: show database */ SHOW database; -- 这是查看所有的数据库

             

      • (2)、对于数据库中的表本身
        • -- 二、对于数据库中表本身
          
          -- 1、创建表
          /*
              语法:
                  create table ] if not exists ] `要创建的表名`(
                  
                      `字段名1· 数据类型( 空间大小 ) 其他的说明,
                      `字段名2· 数据类型( 空间大小 ) 其他的说明,
                       .........
                      `字段名3· 数据类型( 空间大小 ) 其他的说明
                  )[ 数据引擎类型 字符集编码 ];
                  
                  注意:每一行之间使用 , 逗号隔开 最后一个不用
          */
          CREATE TABLE IF NOT EXISTS `test`(  -- 这里其实不用加 ·· 这个飘字符都可以
                                              -- 因为这个test名字并没和数据库中原有的名字冲突
                                              
              `id` INT AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT'编号',   -- comment就是解释的意思,即:对改字段进行说明
                                                                           -- primary key就是主键的意思
              `name` VARCHAR(20) NOT NULL COMMENT'名字',
              `sex` CHAR(2) NOT NULL COMMENT'性别'
          
          )ENGINE = INNODB DEFAULT CHARSET = utf8;
          -- engine 就是引擎的意思   default charset就是设置表的字符编码 虽然在安装mysql时在my.ini中设置了默认字符编码
          -- 但是:为了保险起见,所以在这里又加入和字符编码
          
          
          
          
          
          -- 2、删除表
          /*
              语法:
                  drop table [ if exists ] 要删除的表名;;
          */
          DROP TABLE IF EXISTS `test`;
          
          
          
          -- 3、修改表
          -- (1)、对表重命名
          /*
              语法:
                  alter table 旧表名 rename as 新表名
          */
          ALTER TABLE `test` RENAME AS `person`;
          
          -- (2)、给表添加新的字段
          /*
              语法:
                  alter table 表名 add 字段名 数据类型( 空间大小 ) 其他说明;
          */
          ALTER TABLE `person` ADD `phone` VARCHAR(12) NOT NULL COMMENT'电话号码';
          
          -- (3)、修改字段的约束 / 数据类型等
          /*
              语法:
                  alter table 表名 modify 字段名 数据类型( 空间大小 ) 其他说明;
          */
          ALTER TABLE `person` MODIFY `phone` VARCHAR(20) NULL COMMENT'电话号码';
          
          -- 对alter的一个补充 可以跟change  即:字段重命名
          /*
              语法:
                  alter table 表名 change 旧字段名 新字段名 [ 数据类型( 空间大小 ) 其他说明 ] ;
                  从这个结构可以看出:其实这个change也可以实现修改字段的约束,只是不建议用,这个change最好用来字段重名
                  而:修改字段的约束就用modify
          */
          ALTER TABLE `person` CHANGE `phone` `phoneNumber`;  
          
          
          -- 对alter的第二个补充  删除表的字段
          /*
              语法:
                  alter table 表名 drop 字段名;
          */
          ALTER TABLE `person` DROP `phoneNumber`;
        • 补充:外键 —— 其实不太想说明,因为外键这个东西切记最好别出现在mysql中,要实现外键的效果最好在程序中去实现( 如:java中 ),因为数据库的本质是存储数据的,所以不应该出现另外任何的附属操作( 这个就和javaSE中说的线程一样,线程就是一个资源类,不应出现任何的附属操作 ),另外:外键会增加表与表之间的耦合度,即:使用了外键,那么要删除表就需要先删除从表( 即:一个表A的一个字段当做另一个表B的主键,这里的B表 ),然后再删除主表( 即:前面说的A表 ),在表很少的情况使用外键还没什么,但是试想一下:要是表很多的话,那么使用了外键的话,删表不是很麻烦?这不是增加了工作量吗。因此:这里就当做知识来了解吧!
          • 添加外键的手段有两种,一种是在创建表的时候就添加;另一种就是把表创建完了之后,再添加外键,这里只弄出语法,不演示,因为:这种东西都是一看就会的,顺便养成一种学习的思想,不然新技术出来自己摸索文档不是很难受吗。
            • 语法:
                      在建表时就进行添加外键
                          key ·FK_要添加为外键的字段名`( ` 要添加为外键的字段名 ` ),  
                               -- 这里`FK_要添加为外键的字段名`其实是给外键起名字,只是格式最好是这样而已
                               -- 然后这句代码以 , 逗号结尾
                          constraint ` 上一步起的外键名 ` foreign key( ` 要添加为外键的字段名 ` ) 
                          references `从表的名字`( ` 和主表中要作为外键的相同字段名 ` );
                               -- constraint是约束的意思,foreign key就是外键的关键字,references就是涉及的意思
                               -- 上述的 ·· 还是tab按键上面 esc按键下那个飘字符,下面也是
                          
                      在建表完成之后进行外键添加
                          alter table `主表的名字` add constraint `外键的名字` foreign key( ` 作为外键的列 ` ) 
                          references 从表名字( ` 和主表中要作为外键的相同字段名 ` );

 

前面这些都是基操

后续的都是重点

 

 

      • (3)、DML语言 —— 即:所谓的增删改语言( data modify language )        需要全部记住
        • insert
        • delete / truncate
        • update

 

        • 准备工作:先创建一个数据库 和 表
          • CREATE DATABASE IF NOT EXISTS `sqlstudy`;
            
            USE `sqlstudy`;
            
            CREATE TABLE IF NOT EXISTS `student`(
            
                `snum` VARCHAR(20) NOT NULL PRIMARY KEY COMMENT'学号',   -- '学号' 这里的' ' 是单引号
                `name` VARCHAR(15) NOT NULL COMMENT'学生名字',
                `sex` CHAR(2) NOT NULL COMMENT'学生性别' CHECK( `sex` = '' OR `sex` = '' ),   -- check()就是为了约束的
                                                                                                -- 在这里就是为了输入时只能输入男或女
                `phone` VARCHAR(12) NOT NULL COMMENT'学生电话'
            )ENGINE = INNODB DEFAULT CHARSET = utf8;
          • 创建好之后效果如下:
            • 数据库 — 更新完毕

 

        • ①、给表中增加数据
          • -- ①、给表中添加数据
            /*
                语法:
                    insert into 表名( `要添加数据的字段名1` , `要添加数据的字段名2`..... )
                    values( '字段1的值' , '字段2的值'..... );
                 
                    注:1、如果要赋多个值 则:在values后面用多个()括号就可以了,然后多个()之间使用 , 逗号隔开 如下:
                        insert into 表名( `要添加数据的字段名1` , ` 要添加数据的字段名2 ` )
                        values( '字段1的值1' , '字段2的值1' .....  ),
                               ......
                              ( '字段1的值2' , '字段2的值2' .....  );
                              
                        2、表名()这个括号里面的 `` 是tab按键上面、esc按键下面的那个飘字符
                        values()这个括号中的 '' 是单引号
                            如果嫌麻烦 那么:表名()这里面的 `` 不用每个都写 只要遇到和mysql中原有的名字冲突再加``都行
                            
                        3、还是前面说的,mysql中的符号都是英文输入法下打出的( 应该说:编程中和符号相关的符号都是英文输入法下的)
            */
            INSERT INTO `student`( `snum` , `name` , `sex` , `phone` )
            VALUES( 'xh123001' , '紫邪情' , '' , '1234567' );
            
            INSERT INTO student( snum , `name` , sex , phone )
            VALUES( 'xh123002' , '梅雪嫣' , '' , '9694321' ),
                  ( 'xh123003' , '韩非' , '' , '9964367' );
            效果如下:
            • 数据库 — 更新完毕

 

 

        • ②、删除表中的数据
          • -- ②、删除表中的数据
            /*
                有两种方式
                
                第一种:
                    语法
                        delete from `表名` [ 条件 ];
                        
                        
                第二种:下面这种方法是直接把表的所有数据清空了 但是不影响表的结构( 即:表中有哪些字段不会变 )
                         所以:下面这种方法用得不多,但是有时需要用
                    truncate table `表名`;
                    
                delete和truncate的区别
                    delete是单纯的删除数据,不会影响表的结构,但是:如果表中的字段使用了自增( 即:auto_increment )
                    那么:这个自增的顺序是不会被清除的 ( 如:该字段在删除之前的自增序号为3,那么删除之后,下一次就是从4开始 )
            另外:delete删除只是一种状态的删除,即sql只是标记要删除的那一行数据为删除状态,因此:数据的空间并没有释放
            这样是为了可以数据复用,下一次创建时就不需要再开辟新空间了,直接使用留下的这个空间
            所以:这种删除是可以恢复的,但是有点麻烦,不演示了 —— 面向百度编程 而truncate是清空整个表中的数据,也不会影响表的结构和索引约束( 索引在后续做说明 ), 但是:自增会归0( 即:上一次自增为3,那么下一次重新存数据就是从0开始 )
            同时:truncate还不会影响事务
              
            */ DELETE FROM student WHERE `name` = '韩非'; TRUNCATE TABLE student;

            效果如下( 韩非的信息没了 ):
            • 数据库 — 更新完毕

 

        • ③、修改表中的数据
          • -- ③、修改表中的数据
            /*
                语法
                    update 表名 set 列字段名 = 要修改的值..... 条件
                    注:不加条件的话是把整个表中符合条件都修改了 所以需要指定是哪一行的数据要做修改
                    
                    说明:
                        多个列字段名之间使用 , 逗号隔开
                    
                    
                知识补充:条件     where子句 后面可以跟哪些
                    运算符: >  <   >=  <=  !=或<>这两个都是不等于的意思
            and or 与、或嘛
            区间: between.....and..... 指的是:在什么之间 是[ ] 取值范围是前后双开的
            */ UPDATE student SET `sex` = '' WHERE `snum` = 'xh123001';
            效果如下:
            • 数据库 — 更新完毕

 

 

      • (4)、DQL语言 —— 即:所谓的查询语言( date query language )       最重要:需要达到贼熟练
        • 所有的查询都需要用它  select
        • 数据库中最核心、最重要的语句
        • 使用频率最高的语句

 

        • select完整语句
          • -- select语句
            
            /*
            
                select完整语法
                    select colnum_name... from table_name          -- colnum_name 是要查询的列字段名  table_name 为表名
                        [ left or right or inner ] join table_name on 链接条件   -- 这是联表查询
                        where子句条件                       -- 指出结果需要满足的条件
                        group by 要分组的字段               -- 这是分组
                        having 过滤条件                     -- 这是为了过滤掉一些信息
                        order by 需要进行排序的字段         -- 这是为了以某一字段进行排序
                        limit dateStart , pageSize;           -- 这是为了让查询出来的数据进行分页显示
                        
                        
                    以上的这个语句顺序都不能乱( 可以少,但不能把顺序打乱 ),需要用对应的语句时只能以这个顺序来进行写sql
            接下来会依次对上面的语句进行说明,但是不是按顺序来进行说明的,而是从简到难
            */

 

        • ①、select的简单玩法
          • -- ①、查询全部
            SELECT * FROM student;      -- * 就表示所有
            
            -- ②、查询字段字段
            SELECT snum , `name` , phone FROM student;
            
            -- ③、有时列字段名 / 表名 不是那么的见名知意,因此:我们还可以自己给它起别名,使用 as 关键字
            --      不用as 直接跟自定义别名也可以
            SELECT snum AS studentNumber , `name` studentName , phone FROM student;  
            -- 这样起了别名之后,我们用的时候,就可以直接使用别名了

 

        • ②、有时发现查询出来的结果有重复的,怎么去重?
          • 使用distinct关键字
            • 如:在student表中新增一个重复数据
              • 数据库 — 更新完毕

                 这样虽然学号不一样,但是:其他信息是重复的,所以查询一下:

                • 数据库 — 更新完毕

                   这不是想要的结果,所以来去重一下

                  • 数据库 — 更新完毕

                     

                     加上distinct关键字就去重成功了

 

 

        • ③、where条件子句 —— 这个其实已经玩过了,如下:
          • 作用:检索数据中符合条件的值
          • -- ⑤、where条件子句
            SELECT * FROM student WHERE snum = 'xh123001';  -- 单条件查询
            
            SELECT * FROM student WHERE snum = 'xh123001' AND `name` = '紫邪情';   -- 多条件查询

 

          • where查询的延伸 —— 模糊查询
            • -- 对where查询的补充 —— 模糊查询
              -- 利用运算符 和 区间查询已经说明过了
              -- 那么在不确定完整信息、只记得大概信息的情况下怎么查询
              -- 就两种 like 和 in
              
              /*
                  对于like
                      % 表示前面 / 后面 / 中间有 0 - 任意个字符
                      _ 表示一个字符 当然 __ 两个就表示两个字符,依次类推
              */
              -- 这里假设我要查询紫邪情这个人的信息,但是:我只知道她姓紫,然后她名字后面有多少个字我都不知道
              SELECT * FROM student WHERE `name` LIKE '紫%';   -- 这样就可以表示出来了,姓紫,后面的字是任意个
              
              
              -- 假设:我要查紫邪情的信息,但是我只知道她名字的中间那个字是邪,其他我都不知道
              SELECT * FROM student WHERE `name` LIKE '%邪%';  -- 这样就表示出来了,中间字为邪,前面和后面是任意个字符
              
              
              -- 假设我知道紫邪情的最后一个字为情
              SELECT * FROM student WHERE `name` LIKE '%情';
              
              
              -- 假设我知道紫邪情姓紫,是三个字
              SELECT * FROM student WHERE `name` LIKE '紫__';      -- 这里是两个 _ 下划线
              
              
              
              /*
              
                  对于in
                      a in ( b1 , b2 , b3 ) 只要a在b1 , b2 , b3中的任意一个里面就为true
              */
              -- 假设:我知道名字是紫邪情 或 紫邪晴  当然:通过前面的方法也可以拿到这里想要的结果
              -- 这里只是为了演示这个知识点   in这个东西一般都是在子查询中嵌套时会用到 而且还很重要
              -- 复杂的联表查询一般都会用到这个in
              SELECT * FROM student WHERE `name` IN ( '紫邪情' , '紫邪晴' );

               


 

        • ④、联表查询 join on
          • 准备工作 重新建表 不再用前面的student
            • -- 新建表、添数据
              CREATE TABLE IF NOT EXISTS stuInfo(
              
                  snum VARCHAR(20) NOT NULL PRIMARY KEY COMMENT'学号',
                  `name` VARCHAR(20) NOT NULL COMMENT'学生姓名',
                  sex CHAR(2) NOT NULL COMMENT'学生性别' CHECK( sex = '' OR sex = '' ),
                  phone VARCHAR(12) NOT NULL COMMENT'学生电话号码' CHECK( len( phone ) = 11 )
              )ENGINE = INNODB DEFAULT CHARSET = utf8;
              
              
              CREATE TABLE IF NOT EXISTS score(
              
                  snum VARCHAR(20) NOT NULL PRIMARY KEY COMMENT'学号',
                  `name` VARCHAR(20) NOT NULL COMMENT'学生姓名',
                  score INT NOT NULL COMMENT'学生成绩'
              )ENGINE = INNODB DEFAULT CHARSET = utf8;
              
              
              INSERT INTO stuInfo
              VALUES( 'xh123001' , '紫邪情' , '' , '1234567' ),
                    ( 'xh123002' , '君莫邪' , '' , '1433243' ),
                    ( 'xh123003' , '张雪' , '' , '694537' ),
                    ( 'xh123004' , '不知火舞' , '' , '9090950' );
              
              
              INSERT INTO score
              VALUES( 'xh123001' , '紫邪情' , '90' ),
                    ( 'xh123002' , '君莫邪' , '98' ),
                    ( 'xh123003' , '张雪' , '99' ),
                    ( 'xh123004' , '不知火舞' , '100' );
              效果如下:
              • 数据库 — 更新完毕数据库 — 更新完毕

 

          • 现在来开始玩联表查询  —— 只演示一个,其他的都是一样的原理
            • -- 想要查 紫邪情 的学号、姓名、性别、成绩
              /*
              
                  join on 的语法
                      select colnum_name from table_name
                          [ left or right or inner ] join 要加入的表 on 两个表的链接条件   -- 最常用的是这三种连接
                          
                      说明:
                          使用left join on 那么就是以left左边的表为主,即:需要的数据全是来自于左边的表 即使左边的表没有想要数据也没事
                          使用right join on 那么就是右边的表为主,即:需要的数据全是来自于右边的表 即使左边的表没有想要数据也没事
                          使用inner join on 那么从 要加入的表 中得到数据,是只要这个表中有一个数据满足就得吃

              上述说的“为主”是什么意思?
              即:查询出来的字段以哪张表为主。举个例子:
              如:要查询的字段,在两张表中,前一张表中有这个字段,后一张表中也有这个字段,
              那么:以哪张表为主,查询的字段也以哪张表为主。
              */ -- 1、首先看需求:需要查询什么? -- 学号、姓名、性别、成绩 SELECT snum , `name` , sex , score -- 2、再看怎么去拿到这些数据 -- 这些数据是来自不同的表,那么联表 SELECT s.snum , s.`name` , sex , score FROM stuInfo AS s LEFT JOIN score ON s.`snum` = score.`snum` ;
              -- 把score表连进来,连接条件就是:stuinfo表中的snum 和 score表中的snum是一样 -- 故:找连接条件就是找两个表之间相同的列字段
              结果如下:
              • 数据库 — 更新完毕

 

            • 上述的查询可以做简化
              • -- 联表查询做简化
                SELECT stuInfo.`snum` , stuInfo.`name` , sex ,score FROM stuInfo , score
                WHERE stuInfo.`snum` = score.`snum`;    
                -- 这样得到的结果也是一样的,但是:这种比join no的性能更低

 

            • 对联表查询的拓展 —— 总的联表查询有7种方式 最常用的是上述说的三种而已,这些玩法也是差不多的
              • 数据库 — 更新完毕
              • 注意:联表查询在做简单的小系统时,如:xxx管理系统之类的,这种弄联表查询没关系的,但是:大型系统,如:分布式的,访问量贼大,动不动同一时刻几千万访问量的系统,坚决别用联表查询( 数据库设计时“一般”也不会整这种没前途的表设计,一般都会大表拆小表,玩分布式架构的演进时再去了解吧 ),因为:联表查询性能低,查数据、添加数据、修改数据等都需要联表嘛,这性能能不低吗

 

 

          • ⑤、自连接  ———— 就是把一张表拆成两张表( 要懂得怎么看这种表,怎么拆这种表 )
            • 数据库 — 更新完毕
            •  所谓的自连接就是:自己玩自己,简称:自wei嘛,这种建表方式其实很常见,如:我国的城市划分,省下有哪些市,市下有哪些县.........

 

        • ⑥、分页和排序
          • 还是用前面创建的学生信息表stuInfo 和 成绩表score 不过:数据太少,那就加多一点
            • 添加的数据如下:
              • 数据库 — 更新完毕
          •  
            -- 想要查询学生信息表中的学号、姓名、电话号码,并且显示前5行数据
            /*
                分页limit的公式
                    limit ( n - 1 )*pageSize , pageSize
                    
                    其中:
                        n   是当前页的大小 如:第1页、第2页....第n页
                        pageSize    为当前页要显示的数据量  如:当前页显示5条数据
                        
                        另:页的总数 = 总数据条数 / 每页要显示的数据量
            */
            SELECT snum , `name` , phone FROM stuInfo 
            LIMIT 0,5   -- 第1页  ( 1 -1 )*5 , 5   ————> 0 , 5
            -- limit 5,5   -- 第2页
            -- limit 10,5  -- 第3页
            -- limit 11
            
            
            -- 排序
            /*
            语法: order by 使用排序的列字段 desc / asc 其中:desc为降序 asc为升序 */ -- 查询学生信息表中的学号、姓名、并以降序排列 SELECT snum , `name` FROM stuInfo ORDER BY snum DESC; -- 升序也就会玩了嘛 SELECT snum , `name` FROM stuInfo ORDER BY snum ASC; -- 既有升序、又有降序,那么就用 , 逗号隔开,如:学号降序,成绩升序 order by snum desc , score asc

 

        • ⑦、子查询 —— 就是再套一个查询语句罢了,一个不够,那就继续套
          • 玩这个的逻辑就是从里到外 —— 就像搞函数一样
          • -- 子查询
            -- 还是查询学号、姓名、成绩
            -- 使用连接查询
            SELECT stuinfo.`snum` , stuinfo.`name` , score FROM stuinfo , score
            WHERE stuinfo.`snum` = score.`snum`;   -- 这样是很轻松办到的,不过有时使用这种方法并不能得到想要的结果
            
            
            -- 所以:开始推导、演变
            -- 1、需要查询什么? 学号、姓名、成绩
            -- 学号、姓名都可以在stuinfo表中查询,而成绩是在score表中
            -- 因此:需要在score表中查询成绩
            SELECT score FROM score;  -- 这样可以把成绩查出来
            
            -- 2、需要查询stuinfo表中的学号、姓名
            SELECT stuinfo.`snum` , stuinfo.`name` FROM stuinfo;  -- 这样可以把学号和姓名查出来
            
            
            -- 3、需要把这两个结果连接起来 ———— 联表    下面加粗的就是子查询,即:在一个查询语句中套了另一个查询语句
            SELECT stuinfo.`snum` , stuinfo.`name` , score FROM stuinfo , score  -- 问题来了:成绩这个字段是怎么来的?
            -- 当然是从:score表中来的 所以:怎么把这个查score的子查询 和 查stuinfo的查询连接起来?
            -- 前面在说模糊查询的时候,不是说过一个关键字吗 ———— in 即:结果来自于in里面
            SELECT stuinfo.`snum` , stuinfo.`name` , score FROM stuinfo , score
            WHERE score IN(     -- 这里可以用in 也可以用=
                                /* 
                                    区别就是:
                                        in里面的结果是可能有多个( 如:这里成绩查出来是很多个 )
                                        = 里面的结果是一个,等于嘛,当然是一个了,难不成是多个值吗
                                */
                SELECT score FROM score
            );   -- 根据需求多层子查询嵌套也是可以的,这只是最简单的子查询,逻辑都是一样的,一层一层推导就可以了

            -- 上述的整个子查询不就感觉和java中写函数一样吗 ———— 因此:注意排版,这样更容易让人看懂逻辑,别搞成一行整完所有
          • 延伸:组合查询
            • 看名字就知道,把多个查询结果组合起来嘛

 

            • 什么情况下可以用组合查询?
              • 1、需要在多个表中查询数据
              • 2、多个查询之后,按一个查询来返回数据

 

            • 示例:
              • -- 组合查询  ———— 使用union关键字进行拼接
                -- 查询学生信息表中的学号、姓名、性别、电话 ———— 用以前的方法可以做到,但是:这里不用,而是为了演示union
                -- 查询学号、姓名
                SELECT snum , `name` FROM stuinfo;
                
                -- 查询性别、电话
                SELECT score FROM score;
                
                -- 以上都可以分别查出应查的列字段
                -- 但是想要的结果是:这二者的组合
                
                -- 因此:使用union关键字 把 两个结果组合( 拼接 )在一起
                SELECT snum , `name` FROM stuinfo
                UNION SELECT sex , phone FROM stuinfo;    
                /*
                    使用union需要保证表的列字段都是一样的
                    换句话说:就是对同一个表做多次查询
                    为什么需要这样做?
                        因为:有时需求需要在一个表中查询不同的结果,然后和另外的表进行比对,所以就需要用到这个
                */
                效果如下( 这就把后面查询的结果 和 上一个查询的结果拼接在一起了 ):
                • 数据库 — 更新完毕

                   

                   这个例子举的不好,和真正的需求不一样,所以看起来感觉没多大用,但是:实质上这个组合查询很有用

                • 假如:有如下这样的一个表
                  • 数据库 — 更新完毕 
                • 需求:查询“计算机系”与“电子工程系“不同职称教师的Tname和Prof
                  • -- 就需要下面这么玩
                    SELECT
                    Tname,Prof FROM Teacher WHERE Depart ='计算机系' AND Prof NOT IN( SELECT Prof FROM Teacher WHERE Depart ='电子工程系' ) UNION SELECT Tname,Prof FROM Teacher WHERE Depart ='电子工程系' AND Prof NOT IN( SELECT Prof FROM Teacher WHERE Depart ='计算机系' );
                    效果如下:
                    • 数据库 — 更新完毕

 

 

        • ⑧、分组和过滤
          • -- 分组和过滤
            /*
            
                语法:
                    group by 要进行分组的字段
                    having 要过滤的条件
            */
          • 示例就不演示了,因为用法和排序差不多,这个就是用来以某一个 / 多个字段进行分组,同时还可以在分组之后过滤掉一些条件罢了

 

 

 

      • (4)、 MySQL中的一些常用函数
        • ①、与数学相关
          • -- 与数学相关
            /*
                abs( a )        绝对值 如:abs(-2)
                mod( a , b )    求余数 如:mod( 5 , 2 )  结果为:1
                ceil( a )       向上取整 如:ceil( 9.6 )
                floor( a )      向下取整 如:floor( 9.6 )
                rand()          生成一个0 - 1之间的随机数
                sign( a )       获取符号 正数为1 负数为-1
            */
            SELECT ABS( -1 );
            SELECT MOD( 5,2 );
            SELECT CEIL( 9.6 );
            SELECT FLOOR( 9.6 );
            SELECT RAND();
            SELECT SIGN( -2 );

             

 

        •  ②、与字符串相关
          • -- 与字符串相关
            /*
                char_length( String str )               获取字符串的长度
                concat( String str , String s )         字符串拼接
                insert( String s , int start , int end , String str )   从某个位置开始替换某个长度的字符串
                lower( String s )       转小写
                upper( String s )       转大写
                instr( String s , String childS )       返回指定字串ChildS在S中第一次出现的索引值
                replace( String s , String futureReplaceS , String replaceS )   把s中的子串futureReplceS替换成replaceS
                substr( String s , int start , int end )        返回指定区间的子字符串
                reverse( String s )     反转
            */
            SELECT CHAR_LENGTH('老衲来了');
            SELECT CONCAT( '太阳出来东边亮,' , '俺想和你搞对象' );
            -- 基本上java中都有,不演示了

 

        •  ③、和时间和日期相关 ——— 这个很重要
          • -- 和时间与日期相关(这个很重要)
            /*
                current_date()      获取当前日期  如:2021-09-03
                curdate()           获取当前日期  如:2021-09-03
                now()               获取当前日期    -- 这个更常用  如:2021-09-03 17:14:16
                localtime()         本地时间      如:2021-09-03 17:14:16
                dayofweek( date )   获取一个时间是星期几  这个返回值结果是: 1 - 7表示周一 到 周天
            当然还有年月日、时分秒的函数
            year( date )
            month( date )
            day( date )
            hour( date )
            minute( date )
            second( date )
            */ SELECT CURRENT_DATE(); SELECT CURDATE(); SELECT NOW(); SELECT LOCALTIME(); SELECT DAYOFWEEK( NOW() );

 

        •  ④、与系统相关 —— 了解即可
          • -- 与系统相关
            SELECT VERSION();  -- 查看自己mysql的版本  这个有点用,因为:不知道mysql版本的时候就可以用这个
            -- 获取登录用户名和权限
            SELECT USER();     -- 是用来显示当前登陆的用户名与它对应的host
            SELECT SYSTEM_USER();  -- 是用来获取系统的用户名和对应host
            SELECT  CURRENT_USER();     -- 是用来显示当前登陆用户对应在user表中的哪一个

 

 

      •  ⑤、聚合函数  ———— 很重要、非常重要
        • -- 聚合函数   很重要、非常重要
          /*
              count()     计数
              avg()       平均数
              max()       最大数
              min()       最小数
              sum()       求和
          */
          SELECT COUNT(snum) FROM stuinfo;
          SELECT AVG(score) FROM score;
          SELECT SUM(score) FROM score;
          SELECT MAX(score) FROM score;
          SELECT MIN(score) FROM score;

 

      •  ⑥、创建存储过程 和 自定义函数 
        • 壹、准备知识
          • if语句
            • -- MySQL中的if语句
              /*
                  语法:
                      if 条件 then
                          逻辑代码
                      end if;
                          
                   或
                      if 条件 then
                          逻辑代码
                      else
                          逻辑代码
                      end if;
                          
                   或
                      if 条件 then  
                          逻辑代码
                      else if 条件 then 
                          逻辑代码
                      .....
                      end if;
              
              */

               


          • MySQL中的循环语句
            • -- MySQL中的循环
              /*
                  一共有三种:  
                      loop        相当于java中的for循环  
                      repeat      相当于是java中的do while
                      while
                      
                      循环中的两个关键字
                      leave      相当于java中的break
                      iterect    相当于java中的continue
                      
                      
                  loop语法:
                      循环名:loop
                          循环体;
                          这里面可以使用 leave 循环名 来中断程序
                      end loop;   -- 注意:这里是有 ; 分号结尾的
                      
                  repeat的语法:
                      repeat
                          循环体;
                      until 条件;     -- 注意:这里是有 ; 分号结尾的
                      end repeat;     -- 注意:这里是有 ; 分号结尾的
                      
                  while和java中的用法一样
                      
              */

 

 

        • 贰、MySQL的自定义函数 function
          • -- MySQL中的自定义函数
            /*
              为什么需要自定义函数?
            这个就和java中的封装是一样的思想,那种经常增删改、特别是查询的语句,每一次都写,不是很麻烦吗?
            所以:自定义函数,把这些东西
            封装起来,下一次用的时候直接调用即可
            */
            /*
            创建函数语法: -- 版本不一样,所以创建时总有一些bug,MySQL5.7版本的就需要加一个delimiter // ..... // delimiter;
            delimiter $$ create function fun_函数名( 参数名字 数据类型 , 参数名字 数据类型.....) [ returns 返回值类型 ] begin 函数体; 这里面还可以定义变量,语法如下: declare 变量名 变量类型 [ default 默认值 ];
            给变量赋值:
            set 变量名 = 值; end $$
            delimiter; 说明: fun_函数名 这整个是一个函数名,只是命名规范需要这样 数据类型 就是MySQL前面一开始的讲的那些列类型,如:int 、 float 、 double...... 函数的调用 函数名( 传参 / 不传参 ); 删除函数 drop function 函数名; 查看函数 show create function 函数名;
            */ -- 练习 编写绝对值函数 DELIMITER $$ -- 这个是自定义分隔符,因为MySQL遇到 ; 就表示结束了 -- 所以这里需要用这个来自定义结束符,不一定是// 用$$也行,这是MySQL版本的语法解析器的问题 CREATE FUNCTION fun_abs( a INT ) RETURNS INT BEGIN IF( a > 0 ) THEN RETURN a; ELSE RETURN -a; END IF; -- if中其实要不要这个end if都行 循环中才注意需要 END $$ DELIMITER; -- 这是恢复MySQL的分隔符
            -- 创建好了,记得运行
            SELECT fun_abs( -3 ); -- 调用自定义函数 SHOW CREATE FUNCTION fun_abs; -- 查看自定义函数 DROP FUNCTION fun_abs; -- 删除自定义函数
            效果如下:
            • 数据库 — 更新完毕
          • 创建成功之后是可以看到自定义的函数的
            • 数据库 — 更新完毕
          • 因为版本问题,所以可能会导致:语句对的,在别人哪里可以运行成功,但是在自己那里就不行,所以:这里补充一种查看适合自己版本的自定义函数
            • 数据库 — 更新完毕

               

               选择这个函数,然后鼠标右键,选择创建函数

            • 输入函数名 —— 注意:命名规范 fun_真正的函数名
            • 数据库 — 更新完毕

               

               这里面就可以告诉自己:怎么创建适合自己版本的函数,同时也可以从这里看出,自己的函数中可以包含哪些东西

 

        • 叁、MySQL中创建存储过程  procedure
          • 其实和自定义函数贼像,就是关键字变了、少了一点东西而已
            • 数据库 — 更新完毕

 

          • -- MySQL创建存储过程
            /*
                那为什么需要创建存储过程?
                    试想一下:如果表很多、表中的数据很庞大,那么读写的时候很慢怎么办?
                    使用存储过程,这样就和自定义函数有点类似了,把需要进行读写的数据进行提前存储起来
                    对外只需要接收参数即可。
                    
                    补充一点:MySQL是先编译,然后再执行,这样在高并发访问时,就会造成浪费资源和时间
                              导致MySQL占用的线程多,也就是所谓的“慢“
                              
                    所以:存储过程就是用来提示性能的
                              
                              
                MySQL创建存储过程语法:
                    delimiter$$
                        create procedure pro_名字( 模式 参数名 数据类型 , 模式 参数名 数据类型....) 
                            begin
                                逻辑代码;
                            end $$
                    delimiter;
                    
                    说明:
                        模式  指的是参数的模式  即:输入型参数in    输出型参数out    输入输出型参数inout( 这个不常用 了解即可 )
                        
                调用存储过程:
                    call pro_名字;
                    
                删除存储过程:
                    drop procedure pro_名字;
                    
                在这个存储过程中有一个除了变量赋值,还有一种结果赋值 即:把查询出来的结果赋给一个变量
            */
            DELIMITER $$
                CREATE PROCEDURE pro_test( IN studentNumber VARCHAR(20) )
                    BEGIN
                    
                        DECLARE scoreNum INT;
                        SELECT score INTO scoreNum FROM score WHERE snum = studentNumber;  -- 这里就是利用into把查询出来的score赋给了scoreNum变量
                        
                        IF scoreNum = 90 THEN
                            UPDATE score SET score = score + 10 WHERE snum = studentNumber;
                        END IF;
                        
                    END$$
            DELIMITER;   -- 记得编写好之后,运行创建
            
            CALL pro_test('xh123001');
            SELECT * FROM score;
            
            DROP PROCEDURE pro_test;    -- 删除存储过程

             效果如下:

            • 数据库 — 更新完毕

 

 

 

      • (5)、MySQL的事务
        •  什么是事务?
          • 将sql放到一个批次中去执行,要么都成功,要么都失败。最典型的就是转账:一个要转出,一个要转入

 

 

          • 一致性(Consistency)
            • 事务前后的数据完整性要保持一致,就如:A给B转了1000,结果A自己的钱还没减

 

          • 持久性(Durability)
            • 事务一旦被提交,则不可逆,会持久化到数据库中

 

          • 隔离性(Isolation)
            • 事务之间不可以彼此影响
          • 隔离性会导致的一些问题:
            • ①、脏读    指:一个事务读取了另一个事务未提交的数据 。如:转钱中,A给B转钱,还没转成功呢,但是:B事务那边就已经读取到了A事务要提交的数据( 即:B事务的钱增加了 )
            • ②、虚读    指:表级别的,就是:一个事务A读取了一遍“表的数据”,但是:另一个事务B又对表插入了一条数据,然后A事务 / 其他事务C读取表的数据时,两次的结果就不一样了( 多一行 / 少一行.... )
            • ③、不可重复读    指:一个事务读取“某一行数据",但是:每次读取的结果都不一样( 这种不一定是错误,是一种巧合 )。如:A事务去查询一个数据,这时A事务已经提交了,但是此时也有其他事务修改了这一行数据,所以A事务再读取时发现数据发生了改变,和上一次读取的不一样了
            • 这些我只是简单说了一下,要看详细的就看我前面放的那个CSDN链接,他那里面更详细

 

          • ②、开始玩事务
            • /*
                  知识准备工作:
                      MySQL是默认自动提交事务的
                      所以:我们怎么来手动开启和关闭自动提交?
                          set autocommit = 0;     -- 1、关闭自动提交
                          set autocommit = 1;     -- 开启自动提交 MySQL默认就是这个
                      
                      MySQL怎么开启事务?
                          start transaction-- 2、开启事务  这就是标记一个事务的开始
                                             -- 从这之后,到结束事务( 即:提交事务 )这中间的sql都在一个事务内
                          
                          -- 3、这中间干的事情就是:
                          insert / delete / update / select;
                          
                          commit;  -- 4、事务的结束标志,就是提交事务( 即:持久化到数据库 )
                                   -- 但是还有一种情况涩,就是万一断网了爪子之类的,没有提交成功呢?
                                   
                          -- 所以:这里还有一个命令
                          rollback;   -- 4.1、回滚 即:回到没有提交事务之前( 即:数据库中数据原来的样子 )
                          
                          -- 5、最后:记得做一件事,把自动提交给别人开启
                          set autocommit = 1;
              */
                     
          • 玩一个事务:模拟一下转钱的事
            • -- 开始整事务
              SET autocommit = 0;     -- 关闭MySQL的自动提交
              START TRANSACTION;      -- 开启事务
              
              -- 事务之间干的事情
              -- A给B转钱,所以A自己少钱,B多钱咯
              UPDATE account SET money = money - 500 WHERE `name` = 'A';
              UPDATE account SET money = money + 500 WHERE `name` = 'B';
              
              COMMIT;     -- 提交事务
              ROLLBACK;   -- 事务回滚
              
              SET autocommit = 1;     -- 还原MySQL默认的自动提交设置
              
              
              -- 检验一下:
              SELECT * FROM account;
              效果如下:
              • 数据库 — 更新完毕

 

 

 

        • 简单说一下索引的简单知识
          • 索引     指的是:能够更高效的获取数据的数据结构
            • 提取主干: 索引的本质就是一种数据结构

 

          • 索引在小数据量中效果不明显,但是:如果数据量很大时,效果就出来了,速率会很快( 但是:不是绝对的快,索引不是越多越好 )

        

          • 索引分类
            • ①、主键索引  即:primary key
              • 一个表中只能有一个,不可重复

 

            • ②、唯一索引  即:unique key
              • 一个表中可以有多个,可以重复( 多个列组合成唯一索引也可以 )。这是为了避免出现重复的列字段

 

            • ③、常规索引  即:key / index   
              • 也是默认的索引。通过key 和 index来设置。即:可以在常规索引的列出现重复的值,         

 

            • ④、全文索引  即:fullText
              • 在MyISAM引擎下才有
              • 就是为了快速定位到数据,是查询更快

 

            • -- 索引
              /*
              
                  手动创建,鼠标点击嘛
                  
                  sql语句创建:
                  语法( 建完表之后再添加 ):
                      alter table 数据库名.表名 add  索引类型  index  index_索引名( 表中要添加索引的字段名 )
                      说明:老规矩  index_索引名才是真正的索引名,只是索引名规范需要这么写而已
                      
                      另外一种写法:
                          create 索引类型 index index_索引名 on 表名( 要添加为索引的字段 )  
                          
                  删除索引:
                      drop index index_索引名        这是一种方式,有些版本不支持,所以:第二种如下:
                      
                      alter table 表名 drop index 索引名;
                      
                  查询全部索引:
                      show index from 表名;
              */
              ALTER TABLE sqlstudy.score ADD FULLTEXT INDEX index_score(snum);
              
              CREATE UNIQUE INDEX index_test ON score(snum , score); -- 这两种索引创建方式都可以
              
              ALTER TABLE score DROP INDEX index_test;    -- 删除索引
              
              SHOW INDEX FROM score;      -- 查看表的所有索引

               表结构如下:

              • 数据库 — 更新完毕

 

            • 附加:看sql的执行状态 —— 了解即可
              • -- 分析sql的执行状态( expain )  下面两种的规律自行总结
                EXPLAIN SELECT * FROM score;       -- 针对非全文索引的
                
                
                -- 针对全文索引  需要先建立全文索引  这样使用以下方法就可以知道查询有多快了
                EXPLAIN SELECT * FROM score WHERE MATCH(`name`) AGAINST('');         -- MATCH 匹配  AGAINST 依靠...

              • 效果如下( 其他的不用管,我们只需要盯住一个地方就行 ):
                • 数据库 — 更新完毕

 

 

            • 使用索引的情况
              • 在大数据量中
                • 经常查询的列
                • 经常分组 或 排序的列
                • 经常进行链接的列

 

 

            • 最后:索引原则
              • 索引不是越多越好
              • 索引不是乱加的,一般是加在常用来查询的字段上的
              • 小数据量的表不要加索引
              • 不要对线程变动数据加索引

 

 

 

        •  索引的简单总结:
          • 数据库 — 更新完毕

 

 

        • 最后:索引其实不难,如果是本专业的( 即:计算机系的 ),那么理解索引非常的简单,相信本专业的都学过计算机组成原理,那么有没有想过,当自己在搜索大数据量时,你电脑的那个风扇为什么会转得很快( 急需扇热 )?这其实就和索引挂钩了,索引的硬件底层原理就是在这里,电脑磁盘其实就是很细小的一个格子,小到肉眼看不见,而我们在访问大数据量时,会急速转动,会听到风扇急速扇热的声音,这就是为了去找到我们要访问的数据是在哪个格子里,找到之后,把磁盘上的数据拷贝出来,然后返回给我们看得到的地方,因此转的很快,所以:索引其实就相当于是一个门牌号,就是为了标记我们要的数据在哪个位置罢了

 

      • (7)、用户权限管理 与 数据备份
        • ①、创建用户 和 给用户授权
          • sqlyog手建 ———— 想要用户有什么权限,直接在里面手动赋予就可以了
            • 数据库 — 更新完毕  

 

          •  sql建用户、授权  
            • 预备知识:整用户,那么本质就是对mysql中的mysql.user这张user表进行操作 ———— 前面安装mysql时,不是有一个修改密码的操作吗,就是对这张表进行增删改查操作  
              • 数据库 — 更新完毕  

 

            • 权限分类  
              • 数据库 — 更新完毕  

                 

                 

                -- 1、创建用户
                /*
                    语法:
                        create user 用户名 identified by '密码';     -- 注意啊:用户名没单引号 密码有单引号
                */
                CREATE USER xieGongZi IDENTIFIED BY '123456';
                
                -- 2、修改当前登录的用户 的 密码
                /*
                    set password = '新密码';
                */
                SET PASSWORD = '123456';
                
                -- 3、对用户重命名
                /*
                    rename user 用户名 To 新用户名;
                */
                RENAME USER xieGongZi TO ziXieQing;
                
                -- 4、删除用户
                /*
                    drop user 用户名;
                */
                DROP USER ziXieQing;
                
                
                -- 5、给用户授权
                /*
                    grant 权限 on 库名.表名 from 用户名;     -- grant就是授权的意思,这个很重要
                                                              -- 库名.表名 就是给哪个数据库中的哪个表授权
                                                              -- 用户名    就是要授权的对象
                                                              -- 权限有哪些,在手动创建时就可以看到,那里面全是字面意思
                                                              
                    查看用户权限:
                        show grant for 用户名;
                        
                    删除用户的权限:
                        revoke 哪些权限 on 哪个库.哪个表 from 哪个用户;
                */
                GRANT ALL PRIVILEGES sqlstudy.`stuinfo` FROM xieGongZi;     -- ALL PRIVILEGES 是授予所有的权限
                
                REVOKE ALL PRIVILEGES ON sqlstudy.`stuinfo` FROM xieGongZi;     -- 删除指定用户的权限

 

 

          • ②、数据备份
            • 为什么要数据备份?
              • 保证数据不丢失
              • 数据转移

 

            • 数据备份的方式
              • 手动备份
                • 一、直接去盘符中的data目录中拷贝物理地址
                • 二、在可视化工具中,右键对应的数据库 / 表进行导出( 注:选择导出数据和结构 ,这样表的列字段,对应的数据这些才不会丢失 ),如以下sqlyog的导出
                  • 数据库 — 更新完毕

 

              •  使用命令导出
                • 数据库 — 更新完毕

 

 

      • (8)、MySQL触发器 —— 不推荐使用,建议使用存储过程
        • ①、手动创建
          • 数据库 — 更新完毕

 

        •  ②、使用sql命令创建
          • 老规矩:不知道怎么创建,那么就手动创建一个,然后看默认生成的是怎么创建的?
            • 数据库 — 更新完毕

 

          •  把里面的东西提出出来,然后做一下调整
            • -- 使用sql命令创建触发器
              /*
                  为什么需要使用触发器?
                      主要原因:在进行增删改之前 / 之后 做一个检查
                      
                  触发器是什么?
                      在数据增删改之前 / 之后,触发某一个事件
                      
                  创建触发器:
                      delimiter $$
              
                          create trigger trigger_名字
                          
                              before / after 
                              
                              insert / update / delete ON 库名.表名
                              
                              for each row   -- 对于每一行语句
                              
                              begin
              
                                  逻辑代码;       -- 这里面可以是一句sql 也可以是多行sql
              
                              end$$
                  
                      delimiter ;
                      
                      
                  删除触发器:
                      drop trigger trigger_名字;
                      
                  查看触发器:
                      show trigger_名字
              */
              
              -- 创建触发器
              -- 给stuinfo表添加数据 也给student表中添加数据
              DELIMITER $$
                  CREATE TRIGGER trigger_insert
                      AFTER   -- 表示在执行相应的操作之后,执行另外的操作
                          INSERT ON stuinfo   -- 表示是在给stuinfo表进行插入数据时会触发某个事件
                          FOR EACH ROW        -- 表示给stuinfo表进行插入数据一次 / 多次就要开始触发某个事件
                              BEGIN       -- 这个begin 和 end之间就是要触发的事件
                                          -- 这里面也支持定义变量、变量赋值、if语句、循环
                              
                                  INSERT INTO student VALUES( 'xh123004' , '邪公子' , '' , '7749321' );
                              
                              END$$
              DELIMITER ;
              
              
              -- 测试一下:给stuinfo添加数据
              INSERT INTO stuinfo VALUES( 'xh123012' , '梅雪烟' , '' , '4626746' );
              
              -- 查看触发器
              SHOW TRIGGER \G;    -- 加 \G 是为了让结果看起来有条理  就像查看电脑属性一样
              
              -- 删除触发器
              DROP TRIGGER IF EXISTS trigger_insert;
              
              -- 修改触发器  删了重建想要的触发器
              效果如下:
              • 数据库 — 更新完毕

 

 

      • (9)、数据库设计
        • ①、为什么需要进行数据库设计?
          • 当数据库很复杂的时候就需要我们设计了

 

          • 糟糕的数据库
            • 数据冗余,浪费空间
            • 效率慢
            • 数据库增删查改都麻烦得很,还不定会整些异常出来

 

          • 优秀的数据库
            • 节约空间
            • 效率高
            • 保证数据的完整性

 

        • ②、怎么设计数据库?
          • 先分析需求:分析业务和数据库处理的需求
          • 然后进行概要设计:即 设计关系图 E-R模型

 

        • ③、附加:优化数据库
          • 优化的第一步:去掉所有的 *        如:select * from xxx;        这里就把 * 换成指定的列字段
          • 优化连接:当数据量很大时,保证 on 之后的子句上面有索引
          • 给出字符串合理的长度       如:性别 就两种 所以:char(2) 就够了
          • 使用了count()的话,那么就尽量使用count( * ),因为:count( * )的本质是统计行数
          • 给热点数据增加索引、让热点数据的列字段成为最左(这个最左原则看前面放的我个人喜欢的索引介绍就懂了)
          • 以上是随便列举的MySQL方面的,后续还有Redis缓存技术、ElasticSearch搜索增强
          • ...........

 

 

      • (10)、三大范式
        • 第一范式   1NF  :原子性
          • 即:保证每一列不可以再分    如:学院     还可以分大数据与信息工程学院、传媒学院..........
        • 第二范式  2NF :
          • 前提:满足第一范式
          • 每张表只做一件事

 

        • 第三范式  3NF :
          • 满足第一、二范式
          • 确保表中的每一列都和主键直接相关,而不是间接相关

 

        • 在设计时,必须保证第一范式,另外两个范式,以能力、情况来

 

 

 

至此:数据库的基本知识就完毕了,JDBC我原本想放在这里面的,但是想了一下还是单独提出来

把JDBC单独弄成一篇小随笔!!!!!

 

数据库 — 更新完毕

 

相关文章: