MySQL基础篇快速记忆和查询

查询

  • 语法:
SELECT   标识选择哪些列
FROM     标识从哪个表中选择

去重(Distinct)

在SELECT语句中使用关键字DISTINCT去除重复行

SELECT DISTINCT department_id
FROM   employees;

过滤(Where)

语法:

SELECT 字段1,字段2
FROM 表名
WHERE 过滤条件
  • 使用WHERE 子句,将不满足条件的行过滤掉
  • WHERE子句紧随 FROM子句

排序(Order by)

使用 ORDER BY 子句排序

  • ASC(ascend): 升序
  • DESC(descend):降序

ORDER BY 子句在SELECT语句的结尾。

SELECT last_name, department_id, salary
FROM   employees
ORDER BY department_id, salary DESC;

分页(Limit)

格式:

LIMIT [位置偏移量,] 行数

第一个“位置偏移量”参数指示MySQL从哪一行开始显示,是一个可选参数,如果不指定“位置偏移量”,将会从表中的第一条记录开始(第一条记录的位置偏移量是0,第二条记录的位置偏移量是1,以此类推);第二个参数“行数”指示返回的记录条数。

操作数据库

CREATE DATABASE 数据库名 IF NOT EXISTS ;  #创建
SHOW DATABASES; #查看,加上括号是查看当前
USE DATABASE; #使用/切换数据库
ALTER DATABASE 数据库名 CHARACTER SET 字符集;  #修改数据库
DROP DATABASE IF EXISTS 数据库名; #删除数据库

操作表

创建表(create)

CREATE TABLE [IF NOT EXISTS] 表名(
	字段1, 数据类型 [约束条件] [默认值],
	字段2, 数据类型 [约束条件] [默认值],
	字段3, 数据类型 [约束条件] [默认值],
	……
	[表约束条件]
);

AUTO_INCREMENT: 自增

边创建边插入

CREATE TABLE dept80
AS 
SELECT  employee_id, last_name, salary*12 ANNSAL, hire_date
FROM    employees
WHERE   department_id = 80;

查看表(show)

SHOW CREATE TABLE 表名

修改表内容(alter)

ALTER TABLE 表名 ADD 字段名 字段类型 【FIRST|AFTER 字段名】;  #追加一个列
ALTER TABLE 表名 MODIFY  字段名1 字段类型 【DEFAULT 默认值】【FIRST|AFTER 字段名2】;  #修改一个列
ALTER TABLE 表名 CHANGE 列名 新列名 新数据类型;#重命名一个列
ALTER TABLE 表名 DROP 字段名 #删除一个列

重命名表(rename)

RENAME TABLE 列名 TO 列名1;#方式一
ALTER table 列名 RENAME 列名1;#方式二

删除表(drop)

DROP TABLE [IF EXISTS] 数据表1 [, 数据表2, …, 数据表n];

清空表(truncate,delete)

TRUNCATE TABLE 表名;
DELETE FROM table_name WHERE condition;
  • 如果你需要删除部分数据、希望可以回滚、或者希望产生更详细的日志,可以使用 DELETE
  • 如果你想快速删除表中的所有数据而不保留表结构,且不需要支持回滚,可以使用 TRUNCATE

约束

约束主要有五种,其中唯一约束和外键约束的删除通常需要通过查找并删除相应的约束名,而主键约束、自增约束、默认值约束可以通过对相应列的属性进行重置来实现。

唯一约束(unique)

建表时

create table 表名称(
	字段名  数据类型,
    字段名  数据类型  unique,  
    字段名  数据类型  unique key,
    字段名  数据类型
);
create table 表名称(
	字段名  数据类型,
    字段名  数据类型,  
    字段名  数据类型,
    [constraint 约束名] unique key(字段名)
);

建表后指定唯一键约束

#字段列表中如果是一个字段,表示该列的值唯一。如果是两个或更多个字段,那么复合唯一,即多个字段的组合是唯一的
#方式1:
alter table 表名称 add unique key(字段列表); 
#方式2:
alter table 表名称 modify 字段名 字段类型 unique;

复合唯一约束

create table 表名称(
	字段名  数据类型,
    字段名  数据类型,  
    字段名  数据类型,
    unique key(字段列表) #字段列表中写的是多个字段名,多个字段名用逗号分隔,表示那么是复合唯一,即多个字段的组合是唯一的
);

删除唯一约束

  • 添加唯一性约束的列上也会自动创建唯一索引。
  • 删除唯一约束只能通过删除唯一索引的方式删除。
  • 删除时需要指定唯一索引名,唯一索引名就和唯一约束名一样。
  • 如果创建唯一约束时未指定名称,如果是单列,就默认和列名相同;如果是组合列,那么默认和()中排在第一个的列名相同。也可以自定义唯一性约束名。
SELECT * FROM information_schema.table_constraints WHERE table_name = '表名'; #查看都有哪些约束
ALTER TABLE USER 
DROP INDEX uk_name_pwd;

外键约束(Foreign key)

限定某个表的某个字段的引用完整性。

比如:员工表的员工所在部门的选择,必须在部门表能找到对应的部分。

  • (从表的某个字段)的数据类型必须与主表名(被参考字段)的数据类型一致,逻辑意义也一样
  • (从表的某个字段)的字段名可以与主表名(被参考字段)的字段名一样,也可以不一样

(1)建表时

create table 主表名称(
	字段1  数据类型  primary key,
    字段2  数据类型
);

create table 从表名称(
	字段1  数据类型  primary key,
    字段2  数据类型,
    [CONSTRAINT <外键约束名称>] FOREIGN KEY(从表的某个字段) references 主表名(被参考字段)
);
-- FOREIGN KEY: 在表级指定子表中的列
-- REFERENCES: 标示在父表中的列
create table dept( #主表
	did int primary key,		#部门编号
    dname varchar(50)			#部门名称
);

create table emp(#从表
	eid int primary key,  #员工编号
    ename varchar(5),     #员工姓名
    deptid int,				#员工所在的部门
    foreign key (deptid) references dept(did)   #在从表中指定外键约束
    #emp表的deptid和和dept表的did的数据类型一致,意义都是表示部门的编号
);

说明:
(1)主表dept必须先创建成功,然后才能创建emp表,指定外键成功。
(2)删除表时,先删除从表emp,再删除主表dept

(2)建表后

一般情况下,表与表的关联都是提前设计好了的,因此,会在创建表的时候就把外键约束定义好。不过,如果需要修改表的设计(比如添加新的字段,增加新的关联关系),但没有预先定义外键约束,那么,就要用修改表的方式来补充定义。

格式:

ALTER TABLE 从表名 ADD [CONSTRAINT 约束名] FOREIGN KEY (从表的字段) REFERENCES 主表名(被引用字段) [on update xx][on delete xx];

举例:

alter table emp add foreign key (deptid) references dept(did);

删除

SELECT * FROM information_schema.table_constraints WHERE table_name = 'emp';#先查找约束名
alter table emp drop foreign key emp_ibfk_1;#再删除

主键约束(primary)

用来唯一标识表中的一行记录。相当于唯一约束+非空约束的组合,主键约束列不允许重复,也不允许出现空值。

实现方法和上述unique类似,将关键词改为primary

create table temp(
	id int primary key,
    name varchar(20)
);

删除主键约束

alter table 表名称 drop primary key;

自增约束(auto_increment)

create table employee(
	eid int primary key auto_increment,
    ename varchar(20)
);

删除

#alter table 表名称 modify 字段名 数据类型 auto_increment;#给这个字段增加自增约束

alter table 表名称 modify 字段名 数据类型; #去掉auto_increment相当于删除

默认值约束(Default)

给某个字段/某列指定默认值,一旦设置默认值,在插入数据时,如果此字段没有显式赋值,则赋值为默认值。

create table 表名称(
	字段名  数据类型  primary key,
    字段名  数据类型  unique key not null,  
    字段名  数据类型  unique key,
    字段名  数据类型  not null default 默认值, 
);
create table 表名称(
	字段名  数据类型 default 默认值 ,
    字段名  数据类型 not null default 默认值,  
    字段名  数据类型 not null default 默认值,
    primary key(字段名),
    unique key(字段名)
);

删除

alter table 表名称 modify 字段名 数据类型 ;#删除默认值约束,也不保留非空约束

alter table 表名称 modify 字段名 数据类型  not null; #删除默认值约束,保留非空约束

操作数据

插入数据(insert)

INSERT INTO 表名 VALUES (value1,value2,....);

INSERT INTO 表名(column1 [, column2, …, columnn]) VALUES (value1 [,value2, …, valuen]);#指定字段

INSERT INTO table_name 
VALUES 
(value1 [,value2, …, valuen]),
(value1 [,value2, …, valuen]),
……
(value1 [,value2, …, valuen]);#同时插入多条

值列表中需要为表的每一个字段指定值,并且值的顺序必须和数据表中字段定义时的顺序相同。

插入查询结果:

INSERT INTO 目标表名
(tar_column1 [, tar_column2, …, tar_columnn])
SELECT
(src_column1 [, src_column2, …, src_columnn])
FROM 源表名
[WHERE condition]

更新数据(update)

UPDATE table_name
SET column1=value1, column2=value2, … , column=valuen
[WHERE condition]
  • 可以一次更新多条数据。
  • 如果需要回滚数据,需要保证在DML前,进行设置:SET AUTOCOMMIT = FALSE;

删除数据(delete)

DELETE FROM table_name [WHERE <condition>];

计算列(Always as)

CREATE TABLE tb1(
id INT,
a INT,
b INT,
c INT GENERATED ALWAYS AS (a + b) VIRTUAL
);#创建时计算
ALTER TABLE tb1 MODIFY c INT GENERATED ALWAYS AS (a + b) VIRTUAL;#修改时计算

流程控制

IF: 条件语句

LOOP:一般用于实现简单的"死"循环
WHILE:先判断后执行
REPEAT:先执行后判断,无条件至少执行一次

LEAVE:用于跳出循环(break)

ITERATE: 用于返回开始处继续循环(continue)

游标: 遍历选出的列表,每次使用按顺序提供一行的值(迭代器)

触发器:由事件来触发某个操作,这些事件包括INSERTUPDATEDELETE事件

IF

IF 表达式1 THEN 操作1
[ELSEIF 表达式2 THEN 操作2]……
[ELSE 操作N]
END IF

Case

CASE 表达式
WHEN 值1 THEN 结果1或语句1(如果是语句,需要加分号) 
WHEN 值2 THEN 结果2或语句2(如果是语句,需要加分号)
...
ELSE 结果n或语句n(如果是语句,需要加分号)
END [case](如果是放在begin end中需要加上case,如果放在select后面不需要)

LOOP

加上THEN LEAVE的结构怎么表示
[loop_label:] LOOP
循环执行的语句
END LOOP [loop_label]

WHILE

[while_label:] WHILE 循环条件  DO
	循环体
END WHILE [while_label];

REPEAT

[repeat_label:] REPEAT
    循环体的语句
UNTIL 结束循环的条件表达式
END REPEAT [repeat_label]

LEAVE

LEAVE 标记名

实现跳出循环(break)

ITERATE

ITERATE label

游标

DECLARE cursor_name CURSOR FOR select_statement; #声明游标
OPEN cursor_name; #打开游标
FETCH cursor_name INTO var_name [, var_name] ... #使用游标
CLOSE cursor_name;

触发器(Trigger)

CREATE TRIGGER 触发器名称 
{BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON 表名 
FOR EACH ROW 
触发器执行的语句块;

举例:

DELIMITER //

CREATE TRIGGER before_insert
BEFORE INSERT ON test_trigger 
FOR EACH ROW
BEGIN
	INSERT INTO test_trigger_log (t_log)
	VALUES('before_insert');

END //

DELIMITER ;

查看/删除触发器

SHOW TRIGGERS #查看当前数据库中全部触发器的定义
SHOW CREATE TRIGGER 触发器名 #查看当前数据库中某个触发器的定义
SELECT * FROM information_schema.TRIGGERS; #从系统库information_schema的TRIGGERS表中查询“salary_check_trigger”触发器的信息。


DROP TRIGGER  IF EXISTS 触发器名称;#删除触发器

视图

创建视图(Create)

CREATE VIEW 视图名称 
AS 查询语句

修改视图(Alter)

方式1:使用CREATE OR REPLACE VIEW 子句修改视图

CREATE OR REPLACE VIEW empvu80
(id_number, name, sal, department_id)
AS 
SELECT  employee_id, first_name || ' ' || last_name, salary, department_id
FROM employees
WHERE department_id = 80;

说明:CREATE VIEW 子句中各列的别名应和子查询中各列相对应。

方式2:ALTER VIEW

修改视图的语法是:

ALTER VIEW 视图名称 
AS
查询语句

删除视图(Drop)

  • 删除视图只是删除视图的定义,并不会删除基表的数据。

  • 删除视图的语法是:

    DROP VIEW IF EXISTS 视图名称;
    
    DROP VIEW IF EXISTS 视图名称1,视图名称2,视图名称3,...;
    
  • 举例:

    DROP VIEW empvu80;
    
  • 说明:基于视图a、b创建了新的视图c,如果将视图a或者视图b删除,会导致视图c的查询失败。这样的视图c需要手动删除或修改,否则影响使用。

变量、存储过程与函数

变量(@)

系统变量

#查看所有全局变量
SHOW GLOBAL VARIABLES;

#查看所有会话变量
SHOW SESSION VARIABLES;
或
SHOW VARIABLES;

#查看满足条件的部分系统变量。
SHOW GLOBAL VARIABLES LIKE '%标识符%';

#查看满足条件的部分会话变量
SHOW SESSION VARIABLES LIKE '%标识符%';

#查看指定的系统变量的值
SELECT @@global.变量名;

#查看指定的会话变量的值
SELECT @@session.变量名;
#或者
SELECT @@变量名;

举例:

SHOW GLOBAL VARIABLES LIKE 'admin_%';
  • 修改系统变量的值

有些时候,数据库管理员需要修改系统变量的默认值,以便修改当前会话或者MySQL服务实例的属性、特征。具体方法:

方式1:修改MySQL配置文件,继而修改MySQL系统变量的值(该方法需要重启MySQL服务)

方式2:在MySQL服务运行期间,使用“set”命令重新设置系统变量的值

#为某个系统变量赋值
#方式1:
SET @@global.变量名=变量值;
#方式2:
SET GLOBAL 变量名=变量值;


为某个会话变量赋值
#方式1:
SET @@session.变量名=变量值;
#方式2:
SET SESSION 变量名=变量值;

用户变量

#方式1:“=”或“:=”
SET @用户变量 = 值;
SET @用户变量 := 值;

#方式2:“:=” 或 INTO关键字
SELECT @用户变量 := 表达式 [FROM 等子句];
SELECT 表达式 INTO @用户变量  [FROM 等子句];

SELECT @用户变量#查看用户变量的值 (查看、比较、运算等)

局部变量

定义:可以使用DECLARE语句定义一个局部变量

作用域:仅仅在定义它的 BEGIN ... END 中有效

位置:只能放在 BEGIN ... END 中,而且只能放在第一句

BEGIN
	#声明局部变量
	DECLARE 变量名1 变量数据类型 [DEFAULT 变量默认值];
	DECLARE 变量名2,变量名3,... 变量数据类型 [DEFAULT 变量默认值];

	#为局部变量赋值
	SET 变量名1 = 值;
	SELECT 值 INTO 变量名2 [FROM 子句];

	#查看局部变量的值
	SELECT 变量1,变量2,变量3;
END

存储过程(Procedure)

关键字 调用语法 返回值 应用场景
存储过程 PROCEDURE CALL 存储过程() 理解为有0个或多个 一般用于更新
存储函数 FUNCTION SELECT 函数() 只能是一个 一般用于查询结果为一个值并返回时

此外,存储函数可以放在查询语句中使用,存储过程不行。反之,存储过程的功能更加强大,包括能够执行对表的操作(比如创建表,删除表等)和事务操作,这些功能是存储函数不具备的。

语法:

DELIMITER $  #为了避免与存储过程中SQL语句结束符相冲突,需要使用DELIMITER改变存储过程的结束符。
CREATE PROCEDURE 存储过程名(IN|OUT|INOUT 参数名  参数类型,...)
[characteristics ...]
BEGIN
	sql语句1;
	sql语句2;

END $

类似于Java中的方法:

修饰符 返回类型 方法名(参数类型 参数名,...){

	方法体;
}

约束条件

characteristics 表示创建存储过程时指定的对存储过程的约束条件,其取值信息如下:

LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'
  • LANGUAGE SQL:说明存储过程执行体是由SQL语句组成的,当前系统支持的语言为SQL。
  • [NOT] DETERMINISTIC:指明存储过程执行的结果是否确定。DETERMINISTIC表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出。NOT DETERMINISTIC表示结果是不确定的,相同的输入可能得到不同的输出。如果没有指定任意一个值,默认为NOT DETERMINISTIC。
  • { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }:指明子程序使用SQL语句的限制。
    • CONTAINS SQL表示当前存储过程的子程序包含SQL语句,但是并不包含读写数据的SQL语句;
    • NO SQL表示当前存储过程的子程序中不包含任何SQL语句;
    • READS SQL DATA表示当前存储过程的子程序中包含读数据的SQL语句;
    • MODIFIES SQL DATA表示当前存储过程的子程序中包含写数据的SQL语句。
    • 默认情况下,系统会指定为CONTAINS SQL。
  • SQL SECURITY { DEFINER | INVOKER }:执行当前存储过程的权限,即指明哪些用户能够执行当前存储过程。
    • DEFINER表示只有当前存储过程的创建者或者定义者才能执行当前存储过程;
    • INVOKER表示拥有当前存储过程的访问权限的用户能够执行当前存储过程。
    • 如果没有设置相关的值,则MySQL默认指定值为DEFINER。
  • COMMENT 'string':注释信息,可以用来描述存储过程。

调用

存储过程有多种调用方法。存储过程必须使用CALL语句调用,并且存储过程和数据库相关,如果要执行其他数据库中的存储过程,需要指定数据库名称,例如CALL dbname.procname。

CALL 存储过程名(实参列表)

1、调用in模式的参数:

CALL sp1('值');

2、调用out模式的参数:

SET @name;
CALL sp1(@name);
SELECT @name;

3、调用inout模式的参数:

SET @name=值;
CALL sp1(@name);
SELECT @name;

存储函数(Function)

语法格式:

CREATE FUNCTION 函数名(参数名 参数类型,...) 
RETURNS 返回值类型
[characteristics ...]
BEGIN
	函数体   #函数体中肯定有 RETURN 语句

END

调用:

SET @dept_id = 50;
SELECT count_by_id(@dept_id);

处理程序(Condition,handler)

定义条件是事先定义程序执行过程中可能遇到的问题,处理程序定义了在遇到问题时应当采取的处理方式,并且保证存储过程或函数在遇到警告或错误时能继续执行。这样可以增强存储程序处理问题的能力,避免程序异常停止运行。

定义条件使用DECLARE语句,语法格式如下:

DECLARE 错误名称 CONDITION FOR 错误码(或错误条件)

可以为SQL执行过程中发生的某种类型的错误定义特殊的处理程序。定义处理程序时,使用DECLARE语句的语法如下:

DECLARE 处理方式 HANDLER FOR 错误类型 处理语句
  • 处理方式:处理方式有3个取值:CONTINUE、EXIT、UNDO。
    • CONTINUE:表示遇到错误不处理,继续执行。
    • EXIT:表示遇到错误马上退出。
    • UNDO:表示遇到错误后撤回之前的操作。MySQL中暂时不支持这样的操作。
  • 错误类型(即条件)可以有如下取值:
    • SQLSTATE '字符串错误码':表示长度为5的sqlstate_value类型的错误代码;
    • MySQL_error_code:匹配数值类型错误代码;
    • 错误名称:表示DECLARE ... CONDITION定义的错误条件名称。
    • SQLWARNING:匹配所有以01开头的SQLSTATE错误代码;
    • NOT FOUND:匹配所有以02开头的SQLSTATE错误代码;
    • SQLEXCEPTION:匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码;
  • 处理语句:如果出现上述条件之一,则采用对应的处理方式,并执行指定的处理语句。语句可以是像“SET 变量 = 值”这样的简单语句,也可以是使用BEGIN ... END编写的复合语句。

热门相关:混在三国当军阀   唐朝小官人   总裁大人,又又又吻我了   锦桐   玉堂金闺