MySQL笔记整理
Posted 偷咬月亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL笔记整理相关的知识,希望对你有一定的参考价值。
mysql数据库
1.数据库的基本概念
-
数据库的英文单词:DataBase 简称:DB
-
什么是数据库?
- 用于存储和管理数据的仓库
-
数据库的特点
- 持久化存储数据。其实数据库就是一个文件系统
- 方便存储和管理数据
- 使用了统一的方式操作数据库——SQL
-
什么是DBMS:
- DataBaseManagementSystem 数据库管理系统(软件),用于管理保存数据的,用于和程序员进行交互,怎么操作数据库。
-
什么是sql:
- 结构化查询语言,用于程序员和DBMS进行交互,用于程序员告诉DBMS到底对数据库进行什么操作的
-
数据库的分类?
-
关系型数据库
经过数学理论验证,可以将现实生活中的各种关系保存到数据库里,这种就称为关系型数据库,特点:保存数据以表为单位
-
非关系型数据库
一般为了解决特定场景的问题,比如:缓存(将数据保存在内存中),高并发访问。Redis数据库
-
-
常见的数据库软件
- Oracle:收费的大型数据库,市场占有率排名第一,Oracle公司的产品
- MySQL:开源免费的数据库,小型的数据库,MySQL6.x版本也开始收费。后来sun公司收购了MySQL,而Sun公司又被Oracle收购
- SQL Server:Microsoft公司收费的中型数据库。C#、.net等语言常使用
- DB2:IBM(国际商业机器公司)公司的数据库产品,收费的。常应用在银行系统中。
2.Mysql数据库软件
-
安装:详见回放——11
-
卸载:详见回放——11
-
启动
- 手动 win+R 输入cmd命令打开小黒窗 输入services.msc 打开服务器窗口
- 自动使用管理员打开cmd:(右键—>以管理员身份运行)
- net start mysql:启动mysql的服务
- net stop mysql:停止mysql的服务
-
登录
-
mysql -uroot -p自己密码(root)
例:mysql -uroot -proot
-
mysql -hip -uroot -p连接目标密码
例:mysql -h127.0.0.1 -uroot -proot
-
-
退出:exit
-
MySQL的目录结构
- Mysql安装目录:C:\\Program Files\\MySQL\\MySQL Server 5.5
配置文件:my.ini - Mysql数据目录:C:\\Program Files\\MySQL\\MySQL Server 5.5\\data
- 几个概念:
- 数据库(文件夹)默认4个数据
- 表(文件)
- 数据
- Mysql安装目录:C:\\Program Files\\MySQL\\MySQL Server 5.5
3.SQL的基本概念
Structured Query Language:结构化查询语言
其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为“方言”。
4.SQL的语法
-
SQL语句可以单行或多行书写,以分号结尾。(必须是英文符号)
-
可使用空格和缩进增强来增强语句的可读性
-
MySQL数据库的SQL语句不区分大小写,关键字建议使用大写
-
三种注释
-
单行注释:
-
-- 注释内容
例: show databases;-- 显示所有数据库
-
注释内容(MySQL特有)
例: show databases;#显示所有数据库
-
-
多行注释
例: show databases;/*显示所有数据库*/
-
5.表的引擎
- innodb
- 支持数据库的高级操作,如:外键,事物等,默认引擎
- myisam
- 只支持基础的增删改查操作
6.SQL的分类
- DDL(Data Definition Language)数据库定义语言
- 用来定义数据库对象:数据库,表,列等。
- 关键字:create,drop,alter 等
- DML(Data Manipulation Language) 数据库操作语言
- 用来对数据库中表的数据进行增删改。
- 关键字:insert,delete,update 等
- DQL(Data Query Language) 数据查询语言
- 用来查询数据库中的记录(数据)。
- 关键字:select,where 等
- DCL(Data Control Language)数据控制语言(了解)
- 用来定义数据库的访问权限和安全级别,及创建用户
- 关键字:GRANT,REVOKE 等
7.DDL(数据定义语言)
-
操作数据库:增删改查(CRUD)
-
C(create):创建
-
创建数据库:
create database 数据库名称; 例: create database db1;
-
创建数据库,先判断是否存在,再创建:
create database if not exists 数据库名称; 例: create database if not exists db1;
-
创建数据库并且指定字符集:
create database [if not exists] 数据库名称 character set 字符集; 例: create database if not exists db1 character set gbk; create database db2 character set utf8;
-
-
R(retrieve):查询
-
查询所有数据库名称:
show database;
-
查询某个数据库的字符集:
show create database 数据库名称; (实际上是查询某个数据库的创建语句) 例: show create database db1;
-
-
U(update):修改
-
修改数据库的字符集:
alter database 数据库名称 character set 字符集名称; 例: alter database db1 character set gb2312;
-
-
D(delete):删除
-
删除数据库:
drop database [if exists] 数据库名称; 例: drop database if exists db3; drop database db1;
-
-
查询正在使用的数据库:
select database();
-
使用数据库
use 数据库名称; 例: use db2;
-
-
操作表:增删改查(CRUD)
-
C (create):创建
-
语法:
create table 表名( 字段名1 数据类型1, 字段名2 数据类型2, ... ... 字段名n 数据类型n); //注意:最后一列不需要加逗号 例: create table stu( id int, name varchar(20), age int, address varchar(50));
-
创建表时指定字符集
create table 表名(字段名 数据类型 ... )engine=引擎类型 charset=字符集; 例: create table stu( id int, name varchar(20), age int, address varchar(50)) engine=myisam charset=gb2312;
-
-
R (retrieve):查询
-
查询某个数据库中所有表名称:
show tables;
-
查询表结构:
desc 表名; 例: desc stu;
-
查询表的字符集:
show create table 表名; -- 实际上是查询表的创建语句 例: show create table stu;
-
-
U (update):修改
-
修改表名:
alter table 表名 rename [to] 新表名; 例: alter table stu rename to student; alter table stu rename student; rename table 原表名 to 新表名; 例: rename table stu to student;
-
修改表的字符集:
alter table 表名 character set 字符集; 例: alter table stu character set gbk;
-
修改表的引擎和字符集
alter table 表名 engine=引擎 charset=字符集; 例: alter table stu engine=innodb charset=utf8;
-
添加字段:
-
在表最后添加字段:
alter table 表名 add 字段名 字段类型; 例: alter table stu add Chinese int;
-
在表最前添加字段:
alter table 表名 add 字段名 字段类型 first; 例: alter table stu add Chinese int first;
-
在某个字段后添加字段:
alter table 表名 add 字段名 字段类型 after 字段名; 例: alter table stu add Chinese int after age;
-
-
修改字段名/类型:
alter table 表名 change 字段名 新字段名 新数据类型; 例: alter table stu change Chinese math int;
-
删除字段:
alter table 表名 drop 字段名; 例: alter table stu drop math;
-
复制表:
create table 表名 like 被复制的表名; 例: create table student like stu;
-
-
D (delete):删除
-
删除表:
drop table [if exists] 表名; 例: drop table stu; drop table if exists stu;
-
-
数据类型
- int(11),bigint(20):整数类型 age int
- double:小数类型 score double(3,2)//不能超过3位数,保留2位小数
- varchar, char,text:字符串 name varchar(20)//姓名最大不能超过20个字符 最大长度是65535,char:固定长度,执行效率高,长度255,如果超过255建议用text
- date:日期 只包含年月日 yyyy-MM-dd
- time:时间 包含时分秒 HH:mm:ss
- datetime:日期 包含年月日时分秒 yyyy-MM-dd HH:mm:ss
- timestamp:时间戳类型 包含年月日时分秒 yyyy-MM-dd HH:mm:ss //如果将来不给这个字段复制,则默认使用当前系统时间来自动赋值
-
8.DML(数据操作语言)
-
添加数据
-
给某些字段一次性插入多条数据
insert into 表名(字段名1,字段名2,. . .,字段名n) values (值1,值2,. . .,值n), (值1,值2,. . .,值n); 例: insert into stu(id,name,age) values (1,\'jack\',18), (2,\'tom\',18), (3,\'bob\',18);
-
给所有字段一次性插入数据
insert into 表名 values(值1,值2, ... ,值n); 例: insert into stu values(1,\'jack\',18,\'湖南\',98);
-
注意:
- 列名和值要一一对应
- 如果表名后不定义列名,则默认给所有列添加值
- 除了数字类型,其他类型都要用引号(单双都行)引起来
-
删除表中数据
delete from 表名 [where 条件]; 例: delete from stu where id = 1; -- 删除id为1的所有数据 delete from stu; -- 删除表的所有数据
-
注意:
-
如果不添加条件则删除表中的所有记录
-
如果删除所有记录
-
delete from 表名;-- 不推荐使用。有多少条记录就会执行多少条
-
TRUNCATE TABLE 表名;-- 推荐使用,效率高,先删除表,再创建一张一样的表
TRUNCATE TABLE stu;
-
-
-
-
修改表中的数据
-
语法:
update 表名 set 列名1=值1,列名2=值2,. . . [where 条件]; 例: update stu set name=\'张三\' where id=1;
- 注意:如果不添加任何条件则会将表中的记录全部修改
-
-
解决字符集问题
set names 字符集; 例: set names gbk;
9.DQL(数据查询语言)
-
掌握查询表中记录
-
语法
select 字段列表 from 表名列表 where 条件列表 group by 字段分组 having 分组之后的条件 order by 排序 limit 分页限定
-
-
掌握基础查询
-
多个字段查询:
select 字段名1,字段名2, . . .from 表名; 例: select id,name,age from stu;
- 注意:如果查询所有字段,则可以使用*来代替字段列表
-
去除重复:
select distinct 字段名1,字段名2, . . . from 表名; 例: select distinct address from stu;
-
计算列:
-
一般使用四则运算计算一些列的值。(一般只会进行数值型运算)
-
ifnull(表达式1,表达式2):null参与的运算结果都为null
-
表达式1:哪个字段需要判断是否为null
-
表达式2:如果该字段为null后的替换值
例: select if null(math,0); //如果数学成绩为空,数学成绩就等于0
-
-
-
起别名:
select 字段名 as 别名; (as可以省略) 例: select name 姓名,age 年龄,address 地址 from stu; select name as 姓名,age as 年龄,address as 地址 from stu;
-
-
掌握条件查询
- where子句后跟条件
- 运算符
- 比较运算符:>、<、<=、>=、=、<>、!=
- 范围运算符:between . . . and
- 列表运算符:in(集合)
- 字符匹配:like(也叫模糊查询)
- 占位符:
- _:单个任意字符
- %:多个任意字符
- 空值:isnull
- 逻辑运算符:
- and或&&
- or或||
- not或!
-
掌握排序查询
-
order by 字段列表 排序方式;
例: SELECT * FROM stu1 ORDER BY math; -- 不写排序方式默认是升序 SELECT * FROM stu1 ORDER BY math desc;
-
排序方式:
-
ASC:升序,默认的。
-
DESC:降序。
-
注意: 如果有多个排序条件,则当前面的条件一样时,才会判断第二条件
-
-
-
聚合查询
-
概念:将一个数据作为一个整体,进行纵向的计算。
-
count:计算个数
-
一般选择非空列:主键
例: select count(*) from stu;-- 统计所有 select count(id) from stu;-- -- 注意:有null值不参与计数 可以用ifnull解决,如下 SELECT COUNT(IFNULL(id,0)) FROM stu;
-
-
max:计算最大值
-
min:计算最小值
-
sum:计算和
-
avg:计算平均值
-
注意:聚合函数的计算排除null值,解决方案,ifnull函数,如上
-
-
分组查询
-
语法:
group by 分组字段; 例: -- 安装性别分组,分别查询男女同学的数据平均分,人数 select sex,AVG(math),count(id) from stu1 group by sex;
-
注意:
- 分组之后查询的字段:分组字段,聚合字段
- where和having的区别?
- where在分组之前进行限定,如果条件不满足,则不参与分组。having在分组之后进行限定,如果不满足结果,则不会被查询出来
- where后不可以跟聚合函数,having可以进行聚合函数的判断
例: -- 按照性别分组,分别查询男女同学的数学平均分,人数,要求分数低于70分的不参与分组,人数大于两人 select sex,avg(math),count(id) from stu1 where math>70 group by sex having count(id)>2;
-
-
分页查询
-
语法:limit 开始的索引,每页查询的条数。
-
公式:开始索引=(当前的页码-1)* 每页显示的条数
例: -- 每页显示三条数据 select * from limit 0,3;-- 第1页 select * from limit 3,3;-- 第2页 select * from limit 6,3;-- 第3页
-
limit是一个MySQL“方言”
-
10.注释:comment
-
创建表时添加注释:
ceate table 表名( 字段名1 类型2 comment ‘注释内容’, 字段名2 类型2, . . .,字段名n 类型n); 例: create table stu( id int comment \'主键\', name varchar(20) comment \'姓名\' );
11.concat()函数
-
将两个字符串连接起来,形成一个单一的字符串。
例: mysql> select concat(\'aaa\',\'bbb\'); +---------------------+ | concat(\'aaa\',\'bbb\') | +---------------------+ | aaabbb | +---------------------+ 1 row in set (0.00 sec)
12.日期函数
-
获取当前年月日时分秒:select now();
mysql> select now(); +---------------------+ | now() | +---------------------+ | 2020-12-11 20:19:55 | +---------------------+ 1 row in set (0.01 sec)
-
获取当前日期:select curdate();
mysql> select curdate(); +------------+ | curdate() | +------------+ | 2020-12-11 | +------------+ 1 row in set (0.00 sec)
-
获取当前时间:select curtime();
mysql> select curtime(); +-----------+ | curtime() | +-----------+ | 20:21:42 | +-----------+ 1 row in set (0.01 sec)
-
从当前年月日时分秒中提取年月日:select date(now());
mysql> select date(now()); +-------------+ | date(now()) | +-------------+ | 2020-12-11 | +-------------+ 1 row in set (0.00 sec)
-
从当前年月日时分秒中提前时分秒:select time(now());
mysql> select time(now()); +-------------+ | time(now()) | +-------------+ | 20:31:45 | +-------------+ 1 row in set (0.01 sec)
-
从表字段中获取年月日:select date(字段名) from 表名;
mysql> select * from d; #d表中的数据 +---------------------+ | time | +---------------------+ | 2020-12-11 20:28:58 | +---------------------+ 1 row in set (0.00 sec) mysql> select date(time) from d;-- 从time字段中获取年月日 +------------+ | date(time) | +------------+ | 2020-12-11 | +------------+ 1 row in set (0.00 sec)
-
从表字段中提前时分秒:select time(字段名) from 表名;
mysql> select * from d; #d表中的数据 +---------------------+ | time | +---------------------+ | 2020-12-11 20:28:58 | +---------------------+ 1 row in set (0.00 sec) mysql> select time(time) from d;-- 从time字段中提取时分秒 +------------+ | time(time) | +------------+ | 20:28:58 | +------------+ 1 row in set (0.00 sec)
-
从当前年月日时分秒中提取时间分量:select extract(格式 from now());
-
year:select extract(year from now());
mysql> select extract(year from now()); +--------------------------+ | extract(year from now()) | +--------------------------+ | 2020 | +--------------------------+ 1 row in set (0.00 sec)
-
month:select extract(month from now());
mysql> select extract(month from now()); +---------------------------+ | extract(month from now()) | +---------------------------+ | 12 | +---------------------------+ 1 row in set (0.00 sec)
-
day:select extract(day from now());
mysql> select extract(day from now()); +-------------------------+ | extract(day from now()) | +-------------------------+ | 11 | +-------------------------+ 1 row in set (0.00 sec)
-
hour:select extract(hour from now());
mysql> select extract(hour from now()); +--------------------------+ | extract(hour from now()) | +--------------------------+ | 20 | +--------------------------+ 1 row in set (0.00 sec)
-
minute:select extract(minute from now());
mysql> select extract(minute from now()); +----------------------------+ | extract(minute from now()) | +----------------------------+ | 38 | +----------------------------+ 1 row in set (0.00 sec)
-
second:select extract(second from now());
mysql> select extract(second from now()); +----------------------------+ | extract(second from now()) | +----------------------------+ | 46 | +----------------------------+ 1 row in set (0.00 sec)
-
13.日期格式化
-
date_format(时间,格式); 用于以不同的格式显示日期/时间
- %Y:四位年
- %y:两位年
- %m:两位月
- %c:一位月
- %d:日
- %H:24时
- %h:12时
- %i:分钟
- %s:秒钟
例1: mysql> select date_format(now(),\'%Y年-%c月-%d日 %H时:%i分:%s秒\'); +----------------------------------------------------+ | date_format(now(),\'%Y年-%c月-%d日 %H时:%i分:%s秒\') | +----------------------------------------------------+ | 2020年-12月-11日 20时:45分:42秒 | +----------------------------------------------------+ 1 row in set (0.00 sec) 例2: mysql> select date_format(now(),\'%Y.%m.%d %h:%i:%s\'); +----------------------------------------+ | date_format(now(),\'%Y.%m.%d %h:%i:%s\') | +----------------------------------------+ | 2020.12.11 08:53:52 | +----------------------------------------+ 1 row in set (0.00 sec)
-
把字符串转化为时间格式
-
str_to_date(字符串,格式);
例:-- 将2020.01.01 5:32:40转换成时间格式 mysql> select str_to_date(\'2020.01.01 5:32:40\',\'%Y.%m.%d %h:%i:%s\'); +-------------------------------------------------------+ | str_to_date(\'2020.01.01 5:32:40\',\'%Y.%m.%d %h:%i:%s\') | +-------------------------------------------------------+ | 2020-01-01 05:32:40 | +-------------------------------------------------------+ 1 row in set (0.00 sec)
-
14.字符串
-
查询字符串的长度:select char_length(str);
例: mysql> select char_length("abcdefg"); +------------------------+ | char_length("abcdefg") | +------------------------+ | 7 | +------------------------+ 1 row in set (0.01 sec)
-
查询字符串出现的位置:select instr(str,substr);
- srt:字符串
- substr:要查询的字符串
例: mysql> select instr(\'张三李四王五\',\'李\'); +----------------------------+ | instr(\'张三李四王五\',\'李\') | +----------------------------+ | 3 | +----------------------------+ 1 row in set (0.01 sec)
-
截取字符串(左边):select left(str,num);
- str:字符串
- num:要截取的长度
例: mysql> select left(\'abcdefg\',3); +-------------------+ | left(\'abcdefg\',3) | +-------------------+ | abc | +-------------------+ 1 row in set (0.01 sec)
-
截取字符串(右边):select right(str,num);
- str:字符串
- num:要截取的长度
例: mysql> select right(\'abcdefg\',3); +--------------------+ | right(\'abcdefg\',3) | +--------------------+ | efg | +--------------------+ 1 row in set (0.00 sec)
-
插入字符串:select insert(str,start,length,newstr);
- str:目标字符串
- start:插入的位置
- length:占用的长度
- newstr:要插入的字符串
例: mysql> select insert(\'abcdefg\',3,2,\'m\'); +---------------------------+ | insert(\'abcdefg\',3,2,\'m\') | +---------------------------+ | abmefg | +---------------------------+ 1 row in set (0.00 sec)
-
替换:select replace(str,old,nowstr);
- str:目标字符串
- old:被替换的字符串
- newstr:替换的字符串
例: mysql> select replace(\'abcdefg\',\'abc\',\'m\'); +------------------------------+ | replace(\'abcdefg\',\'abc\',\'m\') | +------------------------------+ | mdefg | +------------------------------+ 1 row in set (0.00 sec)
-
大小写转换
-
小写转大写:select upper(str);
例: mysql> select upper(\'abc\'); +--------------+ | upper(\'abc\') | +--------------+ | ABC | +--------------+ 1 row in set (0.01 sec)
-
大写转小写:select lower(str);
例: mysql> select lower(\'ABC\'); +--------------+ | lower(\'ABC\') | +--------------+ | abc | +--------------+ 1 row in set (0.00 sec)
- 去空格:select trim(str); 注意:只能去字符串两边的空格
例: mysql> select trim(\' abbb dcefg \'); -- 注意:只能去字符串两边的空格 +-------------------------------+ | trim(\' abbb dcefg \') | +-------------------------------+ | abbb dcefg | +-------------------------------+ 1 row in set (0.00 sec)
-
-
重复输出:select repeat(str,num);
- str:要重复输出的字符串
- num:重复输出的次数
例: mysql> select repeat(\'abcd\',4); +------------------+ | repeat(\'abcd\',4) | +------------------+ | abcdabcdabcdabcd | +------------------+ 1 row in set (0.01 sec)
-
反转(反向输出):select reverse(str);
例: mysql> select reverse(\'abcdefg\'); +--------------------+ | reverse(\'abcdefg\') | +--------------------+ | gfedcba | +--------------------+ 1 row in set (0.00 sec)
-
向下取整:select floor(num);
例: mysql> select floor(5.9876);-- 将小数点直接抹去 +---------------+ | floor(5.9876) | +---------------+ | 5 | +---------------+ 1 row in set (0.01 sec)
-
四舍五入
- 不保留小数:select round(num);
例1: mysql> select round(5.678); +--------------+ | round(5.678) | +--------------+ | 6 | +--------------+ 1 row in set (0.00 sec) 例2: mysql> select round(5.345); +--------------+ | round(5.345) | +--------------+ | 5 | +--------------+ 1 row in set (0.00 sec)
-
保留小数:select round(num,m);
- m为保留的小数位数
例1: mysql> select round(5.345,2); +----------------+ | round(5.345,2) | +----------------+ | 5.35 | +----------------+ 1 row in set (0.00 sec) 例2: mysql> select round(5.67,1); +---------------+ | round(5.67,1) | +---------------+ | 5.7 | +---------------+ 1 row in set (0.00 sec)
-
随机数:select rand();
mysql> select rand(); -- 随机生成0-1之间的数 +--------------------+ | rand() | +--------------------+ | 0.5215437528877926 | +--------------------+ 1 row in set (0.00 sec) mysql> select floor(rand()*10)+1;-- 随机生成1-10的随机数 +--------------------+ | floor(rand()*10)+1 | +--------------------+ | 8 | +--------------------+ 1 row in set (0.00 sec)
15. 约束
-
约束:对表中的数据进行限定,保证数据的正确性,有效性和完整性
-
非空约束:not null,某一列的值不能为空
- 创建表时添加约束
create table 表名( 字段名1 类型1, 字段名2 类型2 not null, . . . 字段名n 类型n); 例: create table s( id int, name varchar(20) not null, age int);
- 创建表后添加非空约束
alter table 表名 modify 字段名 字段类型 not null; 例: alter table s modify id int not null;
- 删除非空约束
alter table 表名 modify 字段名 字段类型; 例: alter table s modify name varchar(20);
-
唯一约束:unique,某一字段的值不能重复
- 创建表示时添加唯一约束
create table 表名( 字段名1 字段类型1, 字段名2 字段类型2 unique, . . . 字段名n 字段类型n ); 例: create table s( id int, phone_number varchar(20) unique,-- 手机号不能为空 age int );
- 创建表后添加唯一约束
alter table 表名 modify 字段名 字段类型 unique; 例: alter table s modify phone_number varchar(20) unique;
- 删除唯一约束
alter table 表名 drop index 字段名; 例: alter table s drop index phone_number;
-
主键约束
- 含义:非空且唯一
- 一张表只有一个字段为主键
- 主键就是表中记录的唯一标识
- 创建表时添加主键[自增]
create table 表名( 字段名1 字段类型1 primary key [auto_increment],-- 中括号里可写可不写 字段名2 字段类型2, . . . 字段名n 字段类型n ); 例: create table s( id int primary key,-- 创建表时添加主键 name varchar(20), age int); create table s( id int primary key auto_increment,-- 创建表时添加主键自增 name varchar(20), age int);
- 创建表后添加主键(自增)
alter table 表名 modify 字段名 数据类型 primary key [auto_increment]; 例: alter table s modify id int primary key;-- 创建表后添加主键 alter table s modify id int primary key auto_increment;-- 创建表后添加主键自增
-
注意:在建表的时候,一定要给表定义一个主键,这样才能保证数据的完整性
-
外键约束:foreign key
- 作用:让表与列产生关系,从而保证数据的正确性
- 语法
create table 表名( 字段名1 数据类型1, 字段名2 数据类型2, . . . 字段名n 数据类型n,-- 外键列 constraint 外键名称 foreign key(外键列名称)references 主表名称(主表列名称) );-- constraint 外键名称 可以不写,默认有一个
- 创建表时添加外键约束
例: create table employee( id int primary key auto_increment, name varchar(20), age int, dep_id int,-- 外键对应主表的主键 constraint emp_dep foreign key(dep_id) references department(id) );
- 创建表后添加外键约束
alter table 表名 add constraint 外键名 foreign key (外键列名称) references 主表名称(主表列名称) 例: alter table employee add constraint emp_dep foreign key(dep_id) references department(id);
- 删除外键约束
alter table 表名 drop foreign key 外键名 例: alter table employee drop foreign key emp_dep;
-
检查约束
- 创建表时添加检查约束
create table tb_emp7( id int primary key, name varchar(25), salary float, CHECK(salary>0 AND salary<100));
- 创建表后添加检查约束
alter table 表名 add constraint 检查约束名 check(约束条件); 例: alter table tb_emp7 add constraint check_id check(id>0);
- 删除检查约束
alter table 表名 drop constraint 检查约束名; 例: alter table tb_emp7 drop constraint check_id;
-
默认约束
- 创建表时添加默认约束
create table 表名( 字段名1 字段类型1, 字段名2 字段类型2 default \'默认内容\', . . . 字段名n 字段类型n ); create table tb_emp8( id primary key, -- 主键约束 name varchar(20) not null unique, -- 唯一约束 address varchar(50) not null default\'未填写\', -- 非空约束,默认约束 favor varchar(50) );
- 创建表后添加默认约束
alter table 表名 add constraint 默认约束名 default \'默认内容\' for 字段名 例: alter table tb_emp8 add constraint emp_address default \'未填写\' for address;
- 删除默认约束
alter table 表名 drop constraint 约束名 例: alter table tb_emp8 drop constraint emp_address;
16.多表关系
- 一对一
- 一对多
- 多对多
- 实现关系
- 一对一(了解)
- 如:人和身份证 实现方式:一对一关系实现,可以任意一方添加唯一外外键指向另一方主键
- 一对多(多对一)
- 如:部门和员工 实现方式:在多的一方建立外键,指向另一方的主键
- 多对多
- 如:学生和课程 实现方式:多对多关系实现需要借助第三张中见表,中间至少包含两个字段,这两个字段作为第三张的外键,分别指向两张表的主键
- 一对一(了解)
- 创建复合主键
- primary key(字段名1,字段名2)
17.多表查询
-
笛卡儿积
- 有两个集合A,B取这两集合的所有组合情况,要完成多表查询,需要消除无用的数据
-
多表查询分类
-
内连接
- 隐式内连接,使用where条件消除无用数据
select 字段列表 from 表名列表 where 条件; 例1:-- 隐式内连接 -- 查询所有员工的信息和对应的部门信息 select * from emp,dept where emp.dept_id=dept.id; 例2:-- 查询员工表的名称,性别,部门表的名称 select emp.name,emp.gender,dept.name from emp,dept where emp.dept_id=dept.id; -- 查询员工表的名称,性别,部门表的名称 select t1.name,-- 员工姓名 t1.gender,-- 员工性别 t2.name,-- 部门名称 from emp t1,dept t2 where t1.dept_id=t2.id;
- 显示内连接
- 语法
select 字段列表 from 表名1[inner] join 表名2 on 条件 例: select * from emp inner join dept on emp.dept_id=dept.id; select * from emp join dept on emp.dept_id=dept.id;
-
外连接
- 左外连接
select 字段列表 from 表名1 left [outer] join 表名2 on条件 例:-- 查询员工的所有信息,有部门的显示部门信息,没有则不显示 select emp.*,dept.name from emp left join dept on emp.detp_id=dept.id;
- 右外连接
select 字段列表 from 表名1 right [outer] join 表名2 on 条件 例:-- 查询员工的所有信息,有部门的显示部门信息,没有则不显示 select emp.*,dept.name from dept right join emp on emp.dept_id=dept.id;
-
-
子查询
- 概念:查询中嵌套查询,称嵌套查询为子查询
例:-- 查询最高工资的员工信息 #先查询最高工资 select max(salary) from emp; -- 9000 #查询最高工资的员工信息 select * from emp where salary=9000; -- 子查询实现 select * from emp where salary=(select max(salary) from emp);
-
子查询的不同情况
- 子查询的结果是单行单列的
例:-- 查询员工工资小于平均工资的人 SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
- 子查询的结果是单行多列的(子查询可以作为条件,使用运算符in来判断)
-- 查询财务部和市场部所有的员工信息 SELECT dept.id FROM dept WHERE dept.`name`=\'市场部\' OR dept.`name`=\'财务部\'; WHERE * FROM emp WHERE dept_id=2 OR dept_id=3; -- 通过子查询一步完 SELECT * FROM emp WHERE dept_id IN(SELECT dept.id FROM dept WHERE dept.`name`=\'市场部\' OR dept.`name`=\'财务部\');
- 子查询结果是多行多列的(子查询可以作为一张虚拟表参与查询)注意:虚拟表一定要取别名
-- 查询员工入职日期是2011-11-11之后的员工信息和部门信息 #SELECT * FROM emp WHERE join_date>\'2011-11-11\' t1;-- 虚拟表 SELECT * FROM dept,(SELECT * FROM emp WHERE join_date>\'2011-11-11\') t1 WHERE t1.dept_id=dept.id;
- 创建表时使用子查询
create table 表名 as 子查询; 例: -- 将emp表中工资大于5000的员工信息存入t_emp create table t_emp as(select * from emp where salary>5000);
19.存储过程
- 存储过程是以一个名称存储,并作为一个单元进行处理,存储过程存储在数据库内。
- 语法结构:
create proceduer proc_name(参数)
过程体
-
什么是过程体
- 由合法的SQL语句构成
- 可以是任意SQL语句
- 过程体如果为复合结构则使用 begin . . . end语句
例1: -- 创建一个查询员工编号deptno,姓名name和工资salary的存储过程 create procedure a() select deptno,name,salary from emp; -- 调用存储过程 call a(); 例2: -- 创建一个查询id=1的商品名称和价格的存储过程 create procedure b(x int) select deptno,name,salary from emp where deptno=x; -- 调用存储过程 call b(num); call b(2); 例3: -- 创建一个删除name为张三的数据,并且输出剩余多少条数据的存储过程 delimiter // create procedure c(x varchar(20)) begin delete from emp where name=x; select count(*) from emp; end// -- 调用存储过程 call c(\'张三\');
20.事物
-
概念:如果一个包含多个步骤的业务操作,被事物关联,那么这些操作要么同时成功,要么同时失败。
-
操作:
- 开启事物:
start transaction
- 回滚
rollback
- 提交
commit
-
事物提交的两种方式:
-
自动提交:
- mysql就是自动提交的
- 一条DML(增删改)会自动提交一次事物
-
手动提交:
- Oracle数据库默认是手动提交事物,需要先开启事物,再提交
- 查看事物的默认提交方式:
select @@autocommit; -- 1代表自动提交 -- 0代表手动提交
- 修改默认提交方式:
set @@autocommit=0;
-
-
事物的四大特征:
- 原子性(atomicity):是不可分割的最小操作单位,要么同时成功,要么同时失败
- 持久性(durability):当事物提交或回滚后,数据库会持久化保存数据
- 隔离性(isolation):多个事物之间,相互独立
- 一致性(consistency):事物操作前后,数据总量不变
-
事物的隔离级别(了解)
- 概念:多个事物之间隔离的,相互独立的,但是如果多个事物操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题
- 存在的问题:
- 脏读:一个事物,读取到另一个事务中没有提交的事物
- 虚读(不可重复读):在同一个事务中,两次读到的数据不一样
- 幻读:一个事物操作(DML)数据表中所有记录,另一个添加一条数据,则第一个事物查询不到自己的修改
- 丢失更新:事物t1读取数据,并且执行一些操作,然后更新数据,事物t2也做了同样的事情,则t1和t2更新数据时可能回覆盖对方数据,从而引起错误
-
设置隔离级别
- read uncommitted:读未提交
- 产生问题:脏读,不可重复,幻读
- read committed:读已提交
- 产生问题:不可重复读,幻读
- repeatable read:可重复读(Mysql默认)
- 产生问题:幻读
- serializable:串行化
- 可以解决所有问题
- 注意:隔离级别从小到大,安全性越来越高,但是效率越来越低
- read uncommitted:读未提交
-
数据库查询隔离级别:
select @@tx_isolation
-
数据库设置隔离级别:
set global transaction isolation level 级别字符串; 例: set global transaction isolation level read committed;-- 设置隔离级别
21.DCL:数据控制语言(了解)
-
DCL管理用户
- 添加用户
create user \'用户名\'@\'主机名\' identified by \'密码\'; 例:-- 创建张三用户 create user \'zhangsan\'@\'localhost\' identified by \'123\';
- 删除用户
drop user \'用户名\'@\'主机名\'; 例:-- 删除张三用户 drop user \'zhangsan\'@\'localhost\';
- 修改密码
set password for \'用户名\'@\'主机名\'=password(\'新密码\'); 例:-- 修改张三的密码为456; set password for \'zhangsan\'@\'localhost\'=password(\'456\');
- 如果忘记数据库密码怎么办?
- 用管理员身份运行cmd,停止mysql服务
- 使用无验证方式启动mysql服务,mysqld --skip-grant-tables
- 打开新的窗口,直接输入mysql命令,敲回车,登录成功
- 使用mysql数据库:use mysql
- update user set password=password(\'新密码\') where user=\'root\';
- 关闭这两个窗口
- 打开任务管理器,手动结束mysql的进程
- 启动mysql服务
- 使用新密码登录
- 查询用户
- 切换到mysql数据库 -- use mysql
- 查询user表 -- select * from user;
- % 表示可以在任意主机使用用户登录数据库
-
DCL权限管理
- 查询权限
SHOW GRANTS FOR\'用户名\'@\'主机名\'; 例: show grants for \'root\'@\'localhost\';
- 授权给用户
GRANT 权限列表 ON 数据库名.表名 TO \'用户名\'@\'主机名\'; 例:-- 给张三用户对数据库dept表的查询和修改权限 grant select,update on db2.dept to \'zhangsan\'@\'localhost\';
- 授予全部权限给用户
GRANT ALL ON *.* TO \'用户名\'@\'主机名\'; 例: grant all on *.* to \'zhangsan\'@\'localhost\';
- 撤销用户权限
REVOKE 权限列表 ON 数据库名.表名 FROM \'用户名\'@\'主机名\'; 例:-- 撤销张三用户对数据库db2中dept表的修改权限 revoke update on db2.dept from \'zhangsan\'@\'localhost\';
以上是关于MySQL笔记整理的主要内容,如果未能解决你的问题,请参考以下文章