• mysql技术总结


    mysql技术总结

    JavaEE:企业级开发,主要就是web

    前端(页面-展示数据)、后端(数据逻辑)、数据库(保存数据)

    1,简介

    数据库(db,database),数据仓库,用于存储数据。

    关系型数据库(sql):行、列

    • mysql、oracle、sql server、db2、sqlLite
    • 通过表和表之间,行和列之间的关系进行数据存储,用户信息系统

    非关系型数据库(nosql,not only sql):{key:value}

    • redis、MongoDB
    • 非关系型数据库,对象存储,通过对象的自身属性来决定

    数据库管理系统(DBMS,database management system):

    • 科学有效的管理数据,维护和获取数据
    • mysql本质就是一个数据库管理系统

    MySQL是一个关系型数据库管理系统,由瑞典[MySQL AB](https://baike.baidu.com/item/MySQL AB/2620844) 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。

    MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。

    MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库。

    2,安装

    2.1,安装mysql

    我这边直接使用docker安装的,当然也可以直接在官网下载安装.

    Docker不适合部署数据库的原因

    # 安装最新版的8.0.xmysql
    docker run -d --name ac-mysql \
    -p 3306:3306 \
    -e MYSQL_ROOT_PASSWORD=123456 \
    -v /opt/docker/mysql/data:/var/lib/mysql \
    mysql:latest
    
    
    # 进入docker容器,执行命令进入mysql的命令行(注意密码要紧贴着-p才有效)
    mysql -uroot -p123456
    
    update mysql.user set authentication_string=password('123456') where user='root' and Host = 'localhost'; -- 更新密码
    

    注意:8.x.x版本的数据库连接时需要额外设置 allowPublicKeyRetrieval=true

    2.2,安装DBeaver

    dbeaver是免费和开源(GPL)为开发人员和数据库管理员通用数据库工具。

    易用性是该项目的主要目标,是经过精心设计和开发的数据库管理工具。免费、跨平台、基于开源框架和允许各种扩展写作(插件)。它支持任何具有一个JDBC驱动程序数据库。它可以处理任何的外部数据源

    我这边使用的这个免费的管理工具,还挺好用的。

    image-20220305170946609

    备注:连接上后,可以勾选显示系统对象

    create DATABASE if not exists test;
    show databases;
    use test -- 切换数据库 不需要;号
    show tables;
    
    -- 单行注释
    /*
    多行注释
    */
    

    3,操作数据库

    操作 库 > 表 > 字段,mysql的关键字不区分大小写

    DDL(定义)、DML(操作)、DQL(查询)、DCL(控制)

    固定的语法和关键字需要记住!

    3.1,库操作

    创建数据库、数据表&字段

    create DATABASE if not exists test;		-- 增
    use test; -- 使用
    show databases;	
    drop database if exists test;	-- 删除
    show databases;
    
    -- auto_increment 自增
    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 '123456' comment '密码姓名',
    	`sex` varchar(2) not null default '未知' comment '性别',
    	`birthday` datetime default null comment '出生日期',
    	`address` varchar(100) default null comment '家庭地址',
    	`email` varchar(50) default null comment '邮箱',
    	primary key(`id`) 
    )engine=innodb default charset=utf8;
    
    -- 显示创建的命令
    show CREATE database school;
    show CREATE table student ;
    desc student ;
    

    备注:mysql 字段或者库名、表名使用`符号,与我之前使用的postgres不一样!

    3.2,数据库列操作

    数值、字符串、时间日期、null(空值,不要使用null进行运算)

    数值

    type 数据量 字节数
    tinyint 十分小 1
    smallint 较小 2
    mediumint 中等 3
    int 标准的整数 4
    bigint 较大的数据 8
    float 浮点数 4
    double 浮点数 8
    decimal 字符串形式的浮点数(金融计算精度) decimal类型怎么算字节数

    举个例子,数据库的商品售价字段类型被定义为Decimal(18,9),18这个数代表着商品售价最长可以到18位,而9这个数字表示小数点后面有9位数字,那么18-9=9,也就得出了整数位可以有9位。

    对于decimal类型来说,每4个字节存9个数字,那么以上数据一共有18位,所以会有18/9x4=8,再加上小数点会占一个字节,所以8+1=9,因此decimal(18,9)占用9个字节。

    字符串

    type 描述 字节数
    char 字符串固定大小 0~255
    varchar 可变字符串(常用) 0~65535
    tinytext 微型文本 2^8-1
    text 文本串(保存大文本) 2^16-1

    日期

    type 描述 字节数
    date YYYY-MM-DD,日期 0~255
    time HH:mm:ss 时间格式 0~65535
    datetime YYYY-MM-DD HH:mm:ss
    timestamp 时间戳,1970.1.1到现在的毫秒数 常用

    3.3,字段属性

    Unsigned:

    • 无符号整数
    • 声明该列不能为负值

    zerofill:

    • 0填充
    • 不足的位数使用0填充,int(3)----003

    自增:

    • 自动在上一条记录的基础上+1(默认值是+1,也可以自定义配置步长)
    • 通常用于设计唯一的主键~index,必须是整数

    非空:

    • 假设设置为not null,如果不给它设置值,就会报错!
    • null,

    备注:每一个表都必须存在下面的五个字段

    id 主键、'version' 乐观锁 、is_delete 伪删除、gmt_create创建时间、gmt_updatex修改时间

    3.4,数据表的类型

    数据库引擎主要有innodb、myisam

    引擎类型 MYISAM INNODB
    事务支持 no yes
    数据行锁 no,表锁 yes
    外键约束 no yes
    全文索引 yes no
    表空间大小 较小 较大,约为2倍

    常规使用操作:

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

    在物理空间存在的位置

    所有数据库文件都存在data目录下,本质还是文件的存储

    MySQL引擎在物理文件上的区别

    • INNODB在数据库表中,有一个*.ibd文件(以student表为例)
    • myisam在数据表中有三个文件(以teacher表为例):
      • .sdi,表结构的定义文件
      • .MYD,数据文件
      • .MYI,索引文件

    image-20220305215524293

    数据库表的字符集编码(charset=utf8),不设置的话,会使用mysql默认的字符集编码Latin1(不支持中文)。1,可以在创建的时候设置(建议使用这个,鲁棒性更高);2,也可以直接在my.ini里面配置默认编码charset=utf8

    3.5,修改删除表

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

    alter table teacher rename as teacher1;
    alter table teacher1 add `other` varchar(255);
    alter table teacher1 modify `other` int(1);	-- 不可以重命名,只能修改字段类型和约束
    alter table teacher1 change `other` `other1` varchar (11); --change用来重命名,不能修改字段约束
    
    alter table teacher1 drop `other1`;	-- 删除数据
    drop table if exists teacher1 ;
    

    注意:

    • `` 字段名,使用这个符号包裹
    • 注释 -- , /**/
    • sql关键字大小写不敏感,建议大家写小写的
    • 所有的符号全部使用英文

    3.6,外键

    了解即可

    -- 1,直接创建表的时候,添加外键
    -- 先创建外键的表
    CREATE table `grade`(
    	`gredeid` int(10) not null auto_increment comment 'id',
    	`name` varchar (30) comment '年级名称',
    	primary key (`id`)
    )engine=innodb default charset=utf8;
    
    -- 定义外键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 '123456' comment '密码姓名',
    	`sex` varchar(2) not null default '未知' comment '性别',
    	`birthday` datetime default null comment '出生日期',
    	`gredeid` int(10) not null comment '学生年级',
    	`address` varchar(100) default null comment '家庭地址',
    	`email` varchar(50) default null comment '邮箱',
    	primary key(`id`) ,
    	key `fk_gradeid`(`gredeid`),
    	constraint `fk_gradeid` foreign key (`gredeid`) references `grade`(`gredeid`)
    )engine=innodb default charset=utf8;
    
    -- 2,也可以在表创建好之后,通过alter来添加外键
    alter table `student` add constraint `fk_gradeid` foreign key (`gredeid`) references `grade`(`gredeid`);
    
    -- 删除表的时候,必须要先删除外键字段的来源表,之后才能删除这张表
    Cannot drop table 'grade' referenced by a foreign key constraint 'fk_gradeid' on table 'student'.
    

    备注:以上都是物理外键,数据库级别的外键,我们不建议使用!(避免数据库过多造成困扰)

    阿里巴巴编码规范:【强制】不得使用外键与级联,一切外键概念必须在应用层级解决。

    最佳实践

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

    4,数据库管理

    4.1,DML

    数据库的意义:数据存储与管理

    image-20220306180040204

    4.1.1,insert

    INSERT into grade  (`name`)values('三年级一班'); -- 如果不填写字段它会一一匹配
    
    INSERT into student (`name`,gredeid)values('张三',1);
    
    INSERT into student (`name`,gredeid)values('张三',1),('李四',1); -- 批量
    

    注意事项:

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

    4.1.2,update

    UPDATE
    	`student`
    set
    	`name` = 'wanyu',
    	address = 'hangzhou',
    	birthday = now()
    where
    	id = 1;
    
    操作符 含义 样例 结果
    = 等于 5=6 false
    <> 或者!= 不等于 5<>6 true
    >
    <
    >=
    <=
    between ... and ... 在范围内 [2,5]
    and 逻辑与
    or 逻辑或

    注意:

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

    4.1.3,delete

    DELETE from student WHERE id = 2; -- 当前企业级的删除都是逻辑软删除
    DELETE from student; -- 谨慎使用该语句,小心被通报!
    
    TRUNCATE`student`;-- 清空数据表,表结构和索引不会变
    
    -- 测速区别
    CREATE table `test`(
    	`id` int(4) not null auto_increment,
    	`coll` varchar(20) not null,
    	primary key(`id`)
    )engine=innodb default charset=utf8;
    
    INSERT into `test` (`coll`) values ('1'),('2'),('3');
    SELECT * from `test`;
    DELETE from `test`;
    INSERT into `test` (`coll`) values ('1'),('2'),('3');
    SELECT * from `test`;
    
    TRUNCATE`test`;
    INSERT into `test` (`coll`) values ('1'),('2'),('3');
    SELECT * from `test`;
    

    DELETE与TRUNCATE区别:

    • 相同点:都能删除数据,都不会删除表结构
    • 不同点:
      • truncate 重新设置自增列(计数器规律)
      • truncate不会影响事务

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

    • 如果使用innodb,自增序列会从1开始(存储在内存中,类似redis)
    • 如果使用MyISAM,继续使用上一个自增量(存在文件中,不会丢失)

    4.2,DQL

    data quary language 数据查询语言

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

    4.2.1,数据准备

    狂神说Java MySQL P16 school.sql

    -- 数据准备
    CREATE DATABASE  `school`;
    USE `school`;
    
    /*Table structure for table `grade` */
    
    DROP TABLE IF EXISTS `grade`;
    
    CREATE TABLE `grade`
    (
        `GradeID`   INT(11)     NOT NULL AUTO_INCREMENT COMMENT '年级编号',
        `GradeName` VARCHAR(50) NOT NULL COMMENT '年级名称',
        PRIMARY KEY (`GradeID`)
    ) ENGINE = InnoDB
      DEFAULT CHARSET = utf8;
    
    /*Data for the table `grade` */
    
    INSERT INTO `grade`(`GradeID`, `GradeName`)
    VALUES (1, '大一'),
           (2, '大二'),
           (3, '大三'),
           (4, '大四'),
           (5, '预科班');
    
    /*Table structure for table `result` */
    
    DROP TABLE IF EXISTS `result`;
    
    CREATE TABLE `result`
    (
        `StudentNo`     INT(4)   NOT NULL COMMENT '学号',
        `SubjectNo`     INT(4)   NOT NULL COMMENT '课程编号',
        `ExamDate`      DATETIME NOT NULL COMMENT '考试日期',
        `StudentResult` INT(4)   NOT NULL COMMENT '考试成绩',
        KEY `SubjectNo` (`SubjectNo`)
    ) ENGINE = InnoDB
      DEFAULT CHARSET = utf8;
    
    /*Data for the table `result` */
    
    INSERT INTO `result`(`StudentNo`, `SubjectNo`, `ExamDate`, `StudentResult`)
    VALUES (1000, 1, '2013-11-11 16:00:00', 85),
           (1000, 2, '2013-11-12 16:00:00', 70),
           (1000, 3, '2013-11-11 09:00:00', 68),
           (1000, 4, '2013-11-13 16:00:00', 98),
           (1000, 5, '2013-11-14 16:00:00', 58);
    
    /*Table structure for table `student` */
    
    DROP TABLE IF EXISTS `student`;
    
    CREATE TABLE `student`
    (
        `StudentNo`    INT(4)       NOT NULL COMMENT '学号',
        `LoginPwd`     VARCHAR(20) DEFAULT NULL,
        `StudentName`  VARCHAR(20) DEFAULT NULL COMMENT '学生姓名',
        `Sex`          TINYINT(1)  DEFAULT NULL COMMENT '性别,0或1',
        `GradeId`      INT(11)     DEFAULT NULL COMMENT '年级编号',
        `Phone`        VARCHAR(50)  NOT NULL COMMENT '联系电话,允许为空',
        `Address`      VARCHAR(255) NOT NULL COMMENT '地址,允许为空',
        `BornDate`     DATETIME    DEFAULT NULL COMMENT '出生时间',
        `Email`        VARCHAR(50)  NOT NULL COMMENT '邮箱账号允许为空',
        `IdentityCard` VARCHAR(18) DEFAULT NULL COMMENT '身份证号',
        PRIMARY KEY (`StudentNo`),
        UNIQUE KEY `IdentityCard` (`IdentityCard`),
        KEY `Email` (`Email`)
    ) ENGINE = MyISAM
      DEFAULT CHARSET = utf8;
    
    /*Data for the table `student` */
    
    INSERT INTO `student`(`StudentNo`, `LoginPwd`, `StudentName`, `Sex`, `GradeId`, `Phone`, `Address`, `BornDate`, `Email`,
                          `IdentityCard`)
    VALUES (1000, '123456', '张伟', 0, 2, '13800001234', '北京朝阳', '1980-01-01 00:00:00', 'text123@qq.com',
            '123456198001011234'),
           (1001, '123456', '赵强', 1, 3, '13800002222', '广东深圳', '1990-01-01 00:00:00', 'text111@qq.com',
            '123456199001011233');
    
    /*Table structure for table `subject` */
    
    DROP TABLE IF EXISTS `subject`;
    
    CREATE TABLE `subject`
    (
        `SubjectNo`   INT(11) NOT NULL AUTO_INCREMENT COMMENT '课程编号',
        `SubjectName` VARCHAR(50) DEFAULT NULL COMMENT '课程名称',
        `ClassHour`   INT(4)      DEFAULT NULL COMMENT '学时',
        `GradeID`     INT(4)      DEFAULT NULL COMMENT '年级编号',
        PRIMARY KEY (`SubjectNo`)
    ) ENGINE = InnoDB
      DEFAULT CHARSET = utf8;
    
    /*Data for the table `subject` */
    
    INSERT INTO `subject`(`SubjectNo`, `SubjectName`, `ClassHour`, `GradeID`)
    VALUES (1, '高等数学-1', 110, 1),
           (2, '高等数学-2', 110, 2),
           (3, '高等数学-3', 100, 3),
           (4, '高等数学-4', 130, 4),
           (5, 'C语言-1', 110, 1),
           (6, 'C语言-2', 110, 2),
           (7, 'C语言-3', 100, 3),
           (8, 'C语言-4', 130, 4),
           (9, 'Java程序设计-1', 110, 1),
           (10, 'Java程序设计-2', 110, 2),
           (11, 'Java程序设计-3', 100, 3),
           (12, 'Java程序设计-4', 130, 4),
           (13, '数据库结构-1', 110, 1),
           (14, '数据库结构-2', 110, 2),
           (15, '数据库结构-3', 100, 3),
           (16, '数据库结构-4', 130, 4),
           (17, 'C#基础', 130, 1);
    
    

    4.2.2,查询语句

    SELECT[ALL|DISTINCT|DISTINCTROW|TOP]
    {*|talbe.*|[table.]field1[AS alias1][,[table.]field2[AS alias2][,…]]}
    FROM tableexpression[,…][IN externaldatabase]
    [WHERE…]
    [GROUP BY…]
    [HAVING…]
    [ORDER BY…]
    

    select

    SELECT * from student s ;
    SELECT StudentNo ,StudentName  from student s ; 
    SELECT distinct StudentNo ,StudentName  from student s ; -- 去重
    SELECT StudentNo as 学号,StudentName as 姓名 from student s ; -- 给字段起别名
    SELECT CONCAT('姓名:',StudentName) from student s ; -- 拼接字符串
    
    SELECT * from `result` r ;
    SELECT StudentNo,StudentResult +1  from `result` r ; -- 结果+1
    
    SELECT VERSION(); -- 查询版本
    
    SELECT 100*3-1 as result ;	-- 运算
    SELECT @@auto_increment_increment; -- 查询自增步长
    
    
    SELECT * from student s where StudentName like '%张%';
    SELECT * from student s where StudentName like '张_';
    SELECT * from student s where StudentName not like '张_';
    SELECT * from student s WHERE StudentName in ('张伟');
    

    where

    作用检索符合条件的值,尽量使用英文字母

    运算符 语法 描述
    and,&& a and b,a && b 逻辑与
    or,|| a or b,a||b 逻辑或
    not,! not a,!a 逻辑非

    连表查询

    本质就是左中右三种,其他的都是条件限制导致

    很多大公司基本上很少使用连表查询,因为不利于后续业务发展需要进行的分库、分表

    -- 连表查询 --
    SELECT s.StudentNo ,s.StudentName ,r.SubjectNo ,r.StudentResult  
    FROM student s inner join `result` r 
    on r.StudentNo = s.StudentNo ;
    
    SELECT s.StudentNo ,s.StudentName ,r.SubjectNo ,r.StudentResult  
    FROM student s right join `result` r 
    on r.StudentNo = s.StudentNo ;
    
    
    SELECT s.StudentNo ,s.StudentName ,r.SubjectNo ,r.StudentResult  
    FROM student s left join `result` r 
    on r.StudentNo = s.StudentNo ;
    
    SELECT s.StudentNo ,s.StudentName ,r.SubjectNo ,r.StudentResult  
    FROM student s left join `result` r on r.StudentNo = s.StudentNo 
    inner join subject s2 on r.StudentNo = s2.SubjectNo ;
    
    类型 描述
    inner join 如果表中至少有一个匹配,就返回
    left join 左表中的所有数据返回,即使有右表中没有匹配
    right join 右表中的所有数据返回,即使有左表中没有匹配

    自连接

    自己的表盒自己的表连接,核心:1张表拆分郑2张一样的表,有父子层级关系

    -- 
    select gdp.code as "父级code",gdp."name" as "父子级名称",gd.code as "子级code",gd."name" as "子级名称"
    from ge_department gd,ge_department gdp
    where gd.parent_code = gdp.code ;
    

    分页

    SELECT *
    from subject s 
    limit 10 offset 10; -- limit<个数> offset<偏移量>
    

    缓解数据库的压力,给人的体验更好,瀑布流

    子查询(qian)

    select *
    from ge_department gd 
    where parent_code in (select code from ge_department gd2 where name = 'xxx');
    

    效率:子查询<关联查询,但是又因为后续业务发展分库、分表,一般又少用连表查

    分组

    group by , having

    SELECT SubjectName  ,AVG(r.StudentResult) as '平均',min(r.StudentResult),max(r.StudentResult)
    FROM `result` r 
    left  join subject s 
    on r.StudentNo = s.SubjectNo 
    GROUP by s.SubjectNo 
    HAVING 平均>10;
    

    递归查询

    4.2.3,函数

    普通函数

    select abs(-8);
    SELECT ceiling (5.2); -- 向上取整
    SELECT FLOOR(5.2) ;	-- 向下取整
    SELECT RAND();	-- 1以内的随机数
    SELECT sign(0);-- 判断负、0、正数
    SELECT CHAR_LENGTH('hello'); -- 获取 长度
    SELECT CONCAT('h','ello') ;
    SELECT insert('hello world!',7,-1,'wanyu');
    SELECT UPPER('hello') ;
    SELECT LOWER('ABC');
    SELECT REPLACE ('hello world','world','wanyu');
    SELECT SUBSTR('hello world',7,5) ; -- 偏移量、个数
    SELECT REVERSE('hello world iloveyou') ;
    
    -- 时间日期
    SELECT NOW() ;
    SELECT CURRENT_TIME() ; 
    SELECT CURRENT_DATE() ; 
    SELECT LOCALTIME();
    SELECT SYSDATE(); 
    
    SELECT YEAR(NOW());
    SELECT month(NOW());
    SELECT day(NOW());
    SELECT HOUR (NOW());
    SELECT MINUTE (NOW());
    SELECT SECOND (NOW());
    
    SELECT SYSTEM_USER();
    

    聚合函数

    Select count(*)、Count(1)、Count(0)的区别和执行效率比较

    函数名称 描述
    count() 计数,列(忽略null)、*、1
    sum() 求和
    avg() 平均值
    max
    min

    数据库级MD5加密

    MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。

    MD5不可逆,MD5破解的原理其实就是一个字典!

    SELECT md5('123456');
    
    INSERT into testmd5 values 
    (1,'wanyu','123456'),
    (2,'zhangsan','123456'),
    (3,'lisi','123456');
    
    UPDATE testmd5  set pwd = MD5(pwd) WHERE id =1;
    SELECT * from testmd5 ;
    INSERT into testmd5 values 
    (4,'wanyu',md5('123456'));
    
    SELECT (md5('123456') = pwd) as flag,testmd5.*
    FROM testmd5;
    

    5,事务

    什么是事务,将一组sql放在一个批次去执行,要么全部成功,要么全部失败

    ACID:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(duration)

    • 原子性(atomicity):普朗克常量、最小不可分

    • 一致性(consistency):事务前后的数据完整性要保证一致性

    • 隔离性(isolation):互斥,多个事务互不干扰

    • 持久性(duration):一旦提交不可逆,事务结束后,数据被持久化

    隔离性导致的问题

    • 脏读:一个事务读取到另外一个未提交事务的数据

    • 不可重复读:在一次事务内多次读取的结果不一样

    • 虚读(幻读):一个事务内读取到别人新插入的数据

    mysql默认是开启事务自动提交的

    -- 事务
    set autocommit=1; -- 0关闭、1开启
    
    start transaction;	-- 事务开始
    insert xx1;
    insert xx2;
    commit;	-- 提交,事务结束
    
    rollback; -- 回滚,返回到原来的情况
    savepoint -- 保存点,设置一个事务保存点
    release savepoint -- 撤销保存点
    

    image-20220306202455407

    6,索引

    索引(index)是帮助数据库更高效的获取数据的数据结构!

    6.1,索引分类

    • 主键索引(primary key)
      • 唯一标识,主键不可重复,一张表中只能有一个主键
    • 唯一索引(unique key)
      • 避免重复的列出现,一张表中可以由多个唯一索引
    • 常规索引(key/index)
      • 默认的,index,key关键字来设置
    • 全文索引(fulltext)
      • 在特定的数据库引擎才支持,myisam

    索引的使用

    1. 创建表的时候给字段添加索引
    2. 创建完毕后,增加索引
    show index from `student`;	-- 查询表中的索引
    alter table student add fulltext  index `studentName`(`studentName`);
    
    -- explain 分析sql执行的状况
    explain select * from student ; -- 非全文索引
    explain SELECT * from student s WHERE MATCH(StudentName)  against('刘');
    

    6.2,测试

    数据准备

    -- 创建表
    CREATE table `app_user` (
    	`id` bigint(20) unsigned not null auto_increment,
    	`name` varchar (50) default ' ',
    	`email` varchar (50) not null ,
    	`phone` varchar (20) default '' ,
    	`gender` tinyint (4) unsigned default 0  ,
    	`password` varchar (100) not null  ,
    	`age` tinyint (4) default 0  ,
    	`create_time` datetime default current_timestamp ,
    	`update_time` timestamp null default current_timestamp on
    UPDATE	current_timestamp ,	
    	primary key(`id`)
    )engine = innodb 
    default charset = utf8 ;
    
    -- 创建function
    delimiter $$
    CREATE function mock_data()
    returns int
    deterministic
    begin
    	declare num int default 1000000;
    	declare i int default 0;
    	while i<num do
    		INSERT	into	app_user (`name`,	email,	phone,	gender,	`password`,	`age`)values ( concat('用户', i),'12345@qq,com',concat('18', floor(rand()*((9999999-100000)+ 10000000000))),floor(rand()* 2),UUID(),floor(rand()* 100));
    		set i = i +1;
    	end while ;
    	return i;
    end;-- mysql-8.x.x版本需要额外加命令deterministic
    
    SELECT mock_data();	-- 执行function
    

    测试数据

    SELECT * FROM app_user au WHERE `name`='用户9999'; -- 耗时0.79s
    explain SELECT * FROM app_user au WHERE `name`='用户9999'; -- 由于没有索引,查询要遍历所有数据!
    
    CREATE index id_app_user_name on app_user (`name`);--创建一个所有
    
    SELECT * FROM app_user au WHERE `name`='用户9999'; -- 9ms
    explain SELECT * FROM app_user au WHERE `name`='用户9999';
    

    6.3,索引原则

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

    索引的数据结构

    hash类型的索引

    Btree:innodb默认的索引类型

    MySQL索引背后的数据结构及算法原理

    7,权限与备份

    7.1,权限

    CREATE USER 'wanyu'@'%' IDENTIFIED BY '123456';-- 创建用户,下面的是给与权限
    grant all privileges on *.* to wanyu; -- 所有的库、所有的表授予全部权限,除了授权权限以外
    show grants for wanyu;	-- 查看某用户权限
    revoke all privileges on *.* from wanyu;	-- 撤销所有权限
    drop user wanyu; -- 删除用户
    
    set password = password('123456');-- 修改当前账户密码
    set password for wanyu = password('123456');-- 修改当前账户密码
    rename user wanyu to wanyu2; -- 修改名称
    show grants for root@localhost;
    

    7.2,备份

    为什么要备份数据:

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

    mysql备份数据的方式:

    • 直接拷贝物理文件(因为数据库存储在硬盘)
    • 使用dbeaver等工具拷贝出
    • 使用命令行导出dump数据
    # 导出多张表 表1 表2 表3
    mysqldump -hlocalhost -uwanyu -p school student > /var/lib/mysql/schoolStudent.sql
    
    # 直接导出数据库
    mysqldump -hlocalhost -uwanyu -p school > /var/lib/mysql/school.sql
    
    # 导入
    # 登录的情况下,切换到指定的数据库,执行如下命令
    source /var/lib/mysql/school.sql
    
    

    8,规约数据库设计

    8.1,数据库设计

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

    糟糕的数据库设计:

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

    良好的数据库设计:

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

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

    • 分析需求:分析业务和需求处理的数据库需求
    • 概要设计:设计关系图、ER图

    设计数据库步骤(类似博客):

    • 收集信息,分析需求

      • 用户表(用户登录注销,个人信息)
      • 分类表(文件分类)
      • 文章表(文章的信息)
      • 评论表(评论信息)
      • 友链表(友链信息)
      • 自定义表(类似redis k-v这种)
    • 标识实体(把需求落实到每个字段)

    • 标识实体之间的关系

      • 写博客:user->blog
      • 创建分类:user->category
      • 关注:user->user
      • 友链:links
      • 评论:user-user-blog

    8.2,三大范式

    为什么需要数据规范化?

    • 信息重复
    • 更新异常
    • 插入异常
      • 无法正常显示信息
    • 删除异常

    三大范式(规范数据库)

    第一范式(1NF

    原子性(最小不可分)

    第二范式(2NF

    每张表只描述一件事情,和主键直接相关(前提满足第一范式)

    第三范式(3NF

    确保数据表中的每一列数据都和主键直接相关,而不能间接相关(前提满足第一、二范式)

    关系型数据库设计:三大范式的通俗理解

    规范与性能的问题:关联的表不得超过3张表

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

    9,jdbc

    9.1,数据库驱动

    驱动:声卡、显卡、数据库

    image-20220306234506554

    我们的程序会通过数据库驱动和数据库连接

    9.2,jdbc

    sun公司为了简化开发人员的(对于数据库的统一)操作,提供了一个(java操作数据库的)规范,俗称JDBC

    这些规范的实现是由具体的厂商去实现,对于开发人员来说,只需要掌握JDBC接口的操作即可

    image-20220306234737572

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version>
    </dependency>
    

    9.3,sql注入

    sql存在漏洞,通过修改传入值获取到非预期数据

    样例:

    String sql = "select * from users where `name`=" +userName;
    
    // 当我们输入具体的账户名预期会有对应的用户信息输出
    // 但是当我们输入如下入参,就会返回所有数据!
    userName = " '' or 1=1";
    

    PreparedStatement 可以防止sql注入

    区别使用占位符防止,手动给参数赋值

    PreparedStatement st = conn.PreparedStatement("select * from users where `name`= ?");
    st.setString(1,"");
    st.executeQuery();
    

    9.4,事务

    try{
        conn.setAutoCommit(false);// 关闭自动提交事务后,就会开启事务
        st = conn.preparedStatement(sql1);
        st.executeUpdate();
        st = conn.preparedStatement(sql2);
        st.executeUpdate();
        conn.commit();// 提交事务
    }catch(Exception e){
        conn.rollback();// 出现问题回滚,其实出现问题会默认回滚,该处为显示回滚
    }
    

    10,集群搭建

    Mysql集群搭建

    mysql各个集群方案的优劣

    参考链接

    MySQL最新教程通俗易懂

    mysql官网

  • 相关阅读:
    国家标准比例尺地形图说明(摘要自SuperMap Objects Document)
    常用日期函数
    CMD执行BCP命令
    如何利用.snk文件生成DLL文件中的Publickeytoken
    SQL SERVER数据库的表中修改字段属性被阻止“Prevent saving changes that require table recreation”
    如何生成DLL文件
    如何反编译DLL文件
    Visual Studio 2022激活密钥
    sqlserver跨数据库查询
    jQuery对象与DOM对象之间的转换
  • 原文地址:https://www.cnblogs.com/Mufasa/p/15974282.html
Copyright © 2020-2023  润新知