MySql from zero foundation to entry

MySql

SQL statement classification

  1. Data Definition Language

    Abbreviated as DDL, data definition language, mainly used for database and table management

  2. Data Manipulation Language

    Abbreviated as DML, data manipulation language, mainly used for table addition, deletion and modification operations

  3. Data Query Language

    Abbreviated as DQL, data query language, mainly used for table query operations

  4. Data Control Language

    Abbreviated as DCL, data control language, mainly used for user authority management

1 DDL

1. DDL operation database

1 创建数据库
	create database db1;
	create database if not exists db2;
	create database db3 charset gbk;
	
2 查看数据库
	show databases; 
	show create database db1;  -- 查看某个数据库的定义信息
	
3 修改数据库
	alter database db3 character set utf8;

4 删除数据库
	drop database db2;

5 使用数据库
 	select database(); 
 	use db1;

2. DDL operation table

1 创建表
	create table student(
         id int,   -- 编号
         name varchar(20),  -- 姓名
         sex char(1),   -- 性别
         birthday date  -- 生日
	);
	
2 查看表结构
	show tables; -- 查看数据库中所有表
	desc 表名; -- 查看表结构
	show create table student; -- 查看创建表的SQL语句,看到的是mysql生成的语句,并不是我们写的,功能是一样的。
	
3 复制表
	create table s1 like student;
	
4 删除表
	drop table s1;	
	drop table if exists s1;
	
5 修改表结构
	alter table 表名 add 列名 数据类型 -- 添加表列ADD
	alter table 表名 modify 列名 数据类型 -- 只修改列的数据类型,不修改列名
	alter table 表名 change 旧列名 新的列名 数据类型 	-- 使用新的列名和新的类型
	alter table 表名 drop 列名  -- 删除列
	rename table 旧的表名 to 新的表名 -- 修改表名

3. Constraints

* 概念: 对表中的数据进行限定,保证数据的正确性、有效性和完整性。	
* 分类:
	1. 主键约束:primary key
	2. 非空约束:not null
	3. 唯一约束:unique
	4. 外键约束:foreign key

* 非空约束:not null,某一列的值不能为null
	1. 创建表时添加约束
		CREATE TABLE stu(
			id INT,
			NAME VARCHAR(20) NOT NULL -- name为非空
		);
	2. 创建表完后,添加非空约束
		ALTER TABLE stu MODIFY NAME VARCHAR(20) NOT NULL;

	3. 删除name的非空约束
		ALTER TABLE stu MODIFY NAME VARCHAR(20);

* 唯一约束:unique,某一列的值不能重复
	1. 注意:
		-- 唯一约束可以有NULL值,在unique的列是可以多次插入空值 (和版本有关)
	2. 在创建表时,添加唯一约束
		CREATE TABLE stu(
			id INT,
			phone_number VARCHAR(20) UNIQUE -- 手机号
		);
	3. 删除唯一约束
		ALTER TABLE stu DROP INDEX phone_number;
	4. 在表创建完后,添加唯一约束
		ALTER TABLE stu MODIFY phone_number VARCHAR(20) UNIQUE;

* 主键约束:primary key。
	1. 注意:
		1. 含义:非空且唯一
		2. 建议: 一张表只能有一个字段为主键, 多个也可以(不推荐使用)
		3. 主键就是表中记录的唯一标识

	2. 在创建表时,添加主键约束
		create table stu(
			id int primary key,-- 给id添加主键约束
			name varchar(20)
		);

	3. 删除主键
		-- 错误 alter table stu modify id int ;
		ALTER TABLE stu DROP PRIMARY KEY;

	4. 创建完表后,添加主键
		ALTER TABLE stu MODIFY id INT PRIMARY KEY;

	5. 自动增长:
		1.  概念:如果某一列是数值类型的,使用 auto_increment 可以来完成值得自动增长

		2. 在创建表时,添加主键约束,并且完成主键自增长
		create table stu(
			id int primary key auto_increment,-- 给id添加主键约束
			name varchar(20)
		);
		
		3. 删除自动增长
		ALTER TABLE stu MODIFY id INT;
		
		4. 添加自动增长
		ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;
		
* 外键约束:foreign key,让表于表产生关系,从而保证数据的正确性。
	1. 在创建表时,可以添加外键
		* 语法:
			create table 表名(
				....
				外键列
				constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称)
			);

	2. 删除外键
		ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

	3. 创建表之后,添加外键
		ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键列名) REFERENCES 主表名称(主表列名称);
	4. 级联操作  -- 了解
			1. 添加级联操作
				语法:ALTER TABLE 表名 ADD CONSTRAINT 外键名称 
						FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称) ON UPDATE CASCADE ON DELETE CASCADE  ;
			2. 分类:
				1. 级联更新:ON UPDATE CASCADE 
				2. 级联删除:ON DELETE CASCADE 

2 DML

1 插入记录
	insert into 表名 values(第1列的值, 第2列的值, ...)
	insert into 表名 (列名1,列名2)values(第1列的值,第2列的值)
	insert into 表名 values(第1列的值, 第2列的值, ...),(第1列的值, 第2列的值, ...)...;
	
2 更新表记录
	update 表名 set 列名=值
	update 表名 set 列名=值 where 条件
	
3 删除表记录
	delete from 表名
	delete from 表名 where 条件
	truncate 表名;

3 DQL

* select * from 表名;

1. 语法:
	select
		字段列表
	from
		表名列表
	where
		条件列表
	group by
		分组字段
	having
		分组之后的条件
	order by
		排序
	limit
		分页限定
		
2. 基础查询
	1. 多个字段的查询
		select 字段名1,字段名2... from 表名;
		* 注意:
			* 如果查询所有字段,则可以使用*来替代字段列表。
	2. 去除重复:
		* distinct
	3. 计算列
		* 一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)
		* ifnull(表达式1,表达式2):null参与的运算,计算结果都为null
			* 表达式1:哪个字段需要判断是否为null
			* 表达式2: 如果该字段为null后的替换值。
	4. 起别名:
		* as:as也可以省略
		
3. 条件查询
	1. where子句后跟条件
	2. 运算符
		* > 、< 、<= 、>= 、= 、<>
		* BETWEEN...AND  含头含尾
		* IN( 集合) 
		* LIKE:模糊查询
			* 占位符:
				* _:单个任意字符
				* %:多个任意字符
		* IS NULL  为NULL
		* and  或 &&
		* or  或 || 
		* not  或 !
		
4. 排序查询
	* 语法:order by 子句
		* order by 排序字段1 排序方式1 ,  排序字段2 排序方式2...

	* 排序方式:
		* ASC:升序,默认的。
		* DESC:降序。

	* 注意:
		* 如果有多个排序条件,则当前边的条件值一样时,才会判断第二条件。
		
5. 聚合函数:将一列数据作为一个整体,进行纵向的计算。
	1. count:计算个数
		1. 一般选择非空的列:主键
		2. count(*)
		演示:
			SELECT COUNT(*) FROM student;
            SELECT COUNT(id) FROM student;
            SELECT COUNT(1) FROM student;  其中: 数字任意都可以.
	2. max:计算最大值
	3. min:计算最小值
	4. sum:计算和
	5. avg:计算平均值
	* 注意:聚合函数的计算,排除null值。
		解决方案:
			1. 选择不包含非空的列进行计算
			2. IFNULL函数

6. 分组查询:
	1. 语法:group by 分组字段;
	2. 注意:
		1. 分组之后查询的字段:分组字段、聚合函数
            2. where 和 having 的区别?
                1. where 在分组之前进行限定,如果不满足条件,则不参与分组。having在分组之后进行限定,如果不满足结果,则不会被查询出来
                2. where 后不可以跟聚合函数,having可以进行聚合函数的判断。
                
7. 分页查询
	1. 语法:limit 开始的索引,每页查询的条数;
	2. 公式:开始的索引 = (当前的页码 - 1) * 每页显示的条数  ✔✔✔
		-- 每页显示3条记录 
		SELECT * FROM student LIMIT 0,3; -- 第1页
		SELECT * FROM student LIMIT 3,3; -- 第2页
		SELECT * FROM student LIMIT 6,3; -- 第3页

	3. limit 是一个MySQL"方言"

4 database design

  1. Multi-table relationship

    1 一对一 : 可以在任意一方添加唯一外键指向另一方的主键实现
    2 一对多 : 在多的一方建立外键,指向一的一方的主键。
    3 多对多 : 多对多关系实现需要借助第三张中间表。中间表至少包含两个字段,这两个字段作为第三张表的外键,			分别指向两张表的主键
    
  2. Paradigm

    		1. 第一范式(1NF):每一列都是不可分割的原子数据项
    		2. 第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)
    				* 几个概念:
    					1. 函数依赖:A-->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A
    						例如:学号-->姓名。  (学号,课程名称) --> 分数
    					2. 完全函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定需要依赖于A属性组中所有的属性值。
    						例如:(学号,课程名称) --> 分数
    					3. 部分函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定只需要依赖于A属性组中某一些值即可。
    						例如:(学号,课程名称) -- > 姓名
    					4. 传递函数依赖:A-->B, B -- >C . 如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,则称 C 传递函数依赖于A
    						例如:学号-->系名,系名-->系主任
    					5. 码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
    						例如:该表中码为:(学号,课程名称)
    						* 主属性:码属性组中的所有属性
    						* 非主属性:除过码属性组的属性
    						
    		3. 第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
    
  3. Database backup and restore

    1. 命令行:
    	* 语法:
    		* 备份: mysqldump -u用户名 -p密码 数据库名称 > 保存的路径
    		* 还原:
    			1. 登录数据库
    			2. 创建数据库
    			3. 使用数据库
    			4. 执行文件。source 文件路径
    

5 multiple tables

1 Inner join query

1 隐式内连接
		SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`;
2 显示内连接
		select 字段列表 from 表名1 [inner] join 表名2 on 条件

2 External link query

1 左外连接查询 select 字段列表 from 表1 left [outer] join 表2 on 条件;
2 右外连接查询 select 字段列表 from 表1 right [outer] join 表2 on 条件;

3 subqueries

* 概念:查询中嵌套查询,称嵌套查询为子查询。

1. 子查询的结果是单行单列的:
		* 子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =
		* -- 查询员工工资小于平均工资的人
			SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);

2. 子查询的结果是多行单列的:
			* 子查询可以作为条件,使用运算符in来判断
			-- 查询'财务部'和'市场部'所有的员工信息
			SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部';
			SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;
			-- 子查询
			SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');

3. 子查询的结果是多行多列的:
			* 子查询可以作为一张虚拟表参与查询
			-- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
			-- 子查询
			SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2
			WHERE t1.id = t2.dept_id;
				
			-- 普通内连接可以代替
			SELECT * FROM emp t1,dept t2 WHERE t1.`dept_id` = t2.`id` AND t1.`join_date` >  '2011-11-11'

6 affairs

* 事物的基本操作
	1. 开启事务: start transaction;
	2. 回滚:rollback;
	3. 提交:commit;
	
* 事务提交的两种方式:
			* 自动提交:
				* mysql就是自动提交的
				* 一条DML(增删改)语句会自动提交一次事务。
			* 手动提交:
				* Oracle 数据库默认是手动提交事务
				* 需要先开启事务,再提交

* 修改事务的默认提交方式:
			* 查看事务的默认提交方式:SELECT @@autocommit; -- 1 代表自动提交  0 代表手动提交
			* 修改默认提交方式: set @@autocommit = 0;
			
* 事务的四大特征:
	1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
	2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
	3. 隔离性:多个事务之间。相互独立。
	4. 一致性:事务操作前后,数据总量不变.
	
* 事物的隔离级别
	* 存在问题:
		1. 脏读:一个事务,读取到另一个事务中没有提交的数据
		2. 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
		3. 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
	* 隔离级别:
		1. read uncommitted:读未提交
			* 产生的问题:脏读、不可重复读、幻读
		2. read committed:读已提交 (Oracle)
			* 产生的问题:不可重复读、幻读
		3. repeatable read:可重复读 (MySQL默认)
			* 产生的问题:幻读
		4. serializable:串行化
			* 可以解决所有的问题

		* 注意:隔离级别从小到大安全性越来越高,但是效率越来越低
		* 数据库查询隔离级别:
			* select @@tx_isolation;
		* 数据库设置隔离级别:
			* set global transaction isolation level  级别字符串;

7 DCL

* DCL:管理用户,授权
	1. 管理用户
		1. 添加用户:
			* 语法:CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
		2. 删除用户:
			* 语法:DROP USER '用户名'@'主机名';
		3. 修改用户密码:
			
			-- UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';
			UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi';
			
			-- SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');
			SET PASSWORD FOR 'root' @ 'localhost' = PASSWORD('123');

			* mysql中忘记了root用户的密码?
				1. cmd -- > net stop mysql 停止mysql服务
					* 需要管理员运行该cmd
				2. 使用无验证方式启动mysql服务: mysqld --skip-grant-tables
				3. 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功
				4. use mysql;
				5. update user set password = password('你的新密码') where user = 'root';
				6. 关闭两个窗口
				7. 打开任务管理器,手动结束mysqld.exe 的进程
				8. 启动mysql服务
				9. 使用新密码登录。
		4. 查询用户:
			-- 1. 切换到mysql数据库
			USE mysql;
			-- 2. 查询user表
			SELECT * FROM USER;
			
			* 通配符: % 表示可以在任意主机使用用户登录数据库

	2. 权限管理:
		1. 查询权限:
			-- 查询权限
			SHOW GRANTS FOR '用户名'@'主机名';
			SHOW GRANTS FOR 'lisi'@'%';

		2. 授予权限:
			-- 授予权限
			grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
			-- 给张三用户授予所有权限,在任意数据库任意表上
			
			GRANT ALL ON *.* TO 'zhangsan'@'localhost';
		3. 撤销权限:
			-- 撤销权限:
			revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
			REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%';

Attention (interview questions)

  1. The difference between varchar and char

       CHAR: 固定长度的字符串,可以不指定长度,默认长度1。如果存入字符串达不到指定长度,后面自动用空格补全。检索效率极高,占用空间大  char(1)  男  
       		常用于保存一些固定长度的数据: 性别
       VARCHAR:不固定长度的字符串,必须指定长度,否则报错。如果存入字符串达不到指定长度,也不补全。占用空间小
       		常用于保存一些可变长度的数据: 用户名、密码
    
  2. The difference between where and having

    having与where的区别:
    	1 having是在分组后对数据进行过滤
    	  where是在分组前对数据进行过滤
    	  
    	2 having后面可以使用聚合函数
     	  where后面不可以使用聚合
    
    
    在查询过程中执行顺序:from>where>group(含聚合)>having>order>select。
    
    所以聚合语句(sum,min,max,avg,count)要比having子句优先执行,而where子句在查询过程中执行优先级别优先于聚合语句(sum,min,max,avg,count)。
    
    where是在判断数据从磁盘读入内存的时候,而having是判断分组统计之前的所有条件,所以having是在对select查询的字段中进行的操作
    
  3. Four characteristics of things

    1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
    2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
    3. 隔离性:多个事务之间。相互独立。
    4. 一致性:事务操作前后,数据总量不变.
    
  4. The difference between multi-table query

    方式一: 内连接查询, 查询两张表交互部分
    	1. 隐式内连接查询
    		语法: select * from A,B where 条件
    		例如: SELECT * FROM dept d ,emp e WHERE d.id = e.dept_id;
    	2. 显式内连接查询
    		语法: select * from A inner join B ON 条件
    		例如: SELECT * FROM dept d INNER JOIN  emp e ON  d.id = e.dept_id;
    方式二: 外连接查询
    	1. 左外连接查询
    		语法: select * from A left outer join B ON 条件
    		特点: 主要查询左表的数据,若右表有数据则显示,没有显示为NULL
    		例如: SELECT * FROM dept d LEFT JOIN  emp e ON  d.id = e.dept_id;
    	2. 右外连接查询
    		语法: select * from A RIGHT outer join B ON 条件
    		特点: 主要查询右表的数据,若左表有数据则显示,没有显示为NULL
    		例如: SELECT * FROM dept d RIGHT JOIN  emp e ON  d.id = e.dept_id;
    	结论: 左外连接和右外连接查询,可以互换.
    

Guess you like

Origin blog.csdn.net/lunatic__/article/details/110678248