目录
1 创建和查看数据库
1.1 创建数据库
CREATE DATABASE 数据库名称;
#创建数据库并设置编码方式
CREATE DATABASE 数据库名称 CHARSET 编码方式;
1.2 查看数据库
#查看已经存在的数据库
SHOW DATABASES;
#查看指定的数据库信息
SHOW CREATE DATABASE 数据库名称;
1.3 修改数据库
#修改数据库编码格式
ALTER DATABASE 数据库名称 DEFAULT CHARACTER SET 编码方式 COLLATE 编码方式_bin;
1.4 删除数据库
#删库
DROP DATABASE 数据库名称;
2 数据类型
- 先讲数据类型,这是创建表的基础
2.1 整数类型
类型 | 大小 | 范围(有符号) | 范围(无符号) |
---|---|---|---|
TINYINT | 1 byte | (-128,127) | (0,255) |
SMALLINT | 2 byte | (-32 768,32 767) | (0,65 535) |
MEDIUMINT | 3 byte | (-8 388 608,8 388 607) | (0,16 777 215) |
INT或INTEGER | 4 byte | (-2 147 483 648,2 147 483 647) | (0,4 294 967 295) |
BIGINT | 8 byte | (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) | (0,18 446 744 073 709 551 615) |
FLOAT | 4 byte | (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 0,(1.175 494 351 E-38,3.402 823 466 E+38) |
DOUBLE | 8 byte | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) |
DECIMAL | 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 | 依赖于M和D的值 | 依赖于M和D的值 |
2.2 日期数据类型
类型 | 大小 (bytes) | 范围 | 格式 | 用途 |
---|---|---|---|---|
DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | ‘-838:59:59’/‘838:59:59’ | HH:MM:SS | 时间值或持续时间 |
YEAR | 1 | 1901/2155 | YYYY | 年份值 |
DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD/HH:MM:SS | 混合日期和时间值 |
TIMESTAMP | 4 | 1970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 | YYYYMMDD HHMMSS | 混合日期和时间值,时间戳 |
2.3 字符串数据类型
类型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255 bytes | 定长字符串 |
VARCHAR | 0-65535 bytes | 变长字符串 |
TINYBLOB | 0-255 bytes | 不超过 255 个字符的二进制字符串 |
TINYTEXT | 0-255 bytes | 短文本字符串 |
BLOB | 0-65 535 bytes | 二进制形式的长文本数据 |
TEXT | 0-65 535 bytes | 长文本数据 |
MEDIUMBLOB | 0-16 777 215 bytes | 二进制形式的中等长度文本数据 |
MEDIUMTEXT | 0-16 777 215 bytes | 中等长度文本数据 |
LONGBLOB | 0-4 294 967 295 bytes | 二进制形式的极大文本数据 |
LONGTEXT | 0-4 294 967 295 bytes | 极大文本数据 |
注意:char(n) 和 varchar(n) 中括号中 n 代表字符的个数。
常用数据类型:
整数类型
- INT - 整数类型
- TINYINT - 一个非常小的整数
- SMALLINT - 一个小的整数
- MEDIUMINT - 一个中等大小的整数
- BIGINT - 一个大的整数
- FLOAT(M,D) - 不能使用无符号的浮点数字,可以定义显示长度(M)和小数位数(D)
- DOUBLE(M,D) - 不能使用无符号的双精度浮点数。可以定义显示长度(M)和小数位数(D)。
- DECIMAL(M,D) - 非压缩浮点数不能是无符号的。在解包小数,每个小数对应于一个字节。定义显示长度(M)和小数(D)的数量是必需的。 NUMERIC是DECIMAL的同义词。
时间类型 - date (只有年月日)
- time (只有时分秒)
- datetime (有年月日时分秒)
- timestamp (时间戳)timestamp 在MySQL中会随着数据的变化,自动修改值。
字符串 - varchar (可变长度,可以自动变小,不能自动变大)
- text (比varchar容量大,且可变长度)
- char (定长的,常用,只要固定长度都要用它)
3表的基本操作
3.1 创建表
CREATE TABLE 表名
(
字段名1 数据类型[完整性约束],
字段名2 数据类型[完整性约束],
......
字段名n 数据类型[完整性约束]
)
注意:最后一行不需要’,'
3.2 查看表
- 查看表的定义语句和表的字符编码
SHOW CREATE TABLE 表名;
- 查看表的字段信息
DESCRIBE 表名;
或(简写)
DESC 表名;
3.3 修改表
3.3.1 修改表名
ALTER TABLE 旧表名 RENAME [TO] 新表名;
例:ALTER TABLE old_table RENAME TO new_table;
注意:[ ]中括号中关键字是可选的,是否出现不会影响语句的执行
3.3.2 修改字段名
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新数据类型;
注意:新数据类型不能为空,即使数据类型和原来的一样。
3.3.3 修改字段的数据类型
ALTER TABLE 表名 MODIFY 字段名 数据类型;
3.3.4 添加字段
ALTER TABLE 表名 ADD 新字段名 数据类型 [约束条件][FIRST|AFTER 已存在字段]
注:FIRST和AFTER为可选参数,用于将新添加的字段设置为表的第一个字段; AFTER用于将新添加的字段添加到自定字段之后。
3.3.5 删除字段
ALTER TABLE 表名 DROP 字段名;
3.3.6 修改字段的排列位置
ALTER TABLE 表名 MODIFY 字段名 1 数据类型 FIRST|AFTER 字段名 2
例1:将字段name设置为表的第一个字段
ALTER TABLE 表名 MODIFY name varchar(20) FIRST;
例2:将id放在name字段后
ALTER TABLE 表名 MODIFY id INT(20) AFTER name;
3.4 删除表
DROP TABLE 表名;
注:如果两张表有主外键关联关系,需要先删除从表中的数据,再删除主表中的数据
4 表的约束
约束条件 | 说明 |
---|---|
primary key | 主键约束(唯一非空) |
foreign key | 外键约束 |
not null | 非空约束 |
unique | 唯一性约束 |
default | 设置默认值 |
4.1 单表约束
4.1.1 设置主键
CREATE TABLE 表名
(
字段名 1 数据类型 primary key
)
注:主键约束:一张表中只能有一个主键,(一个主键可以包含一个或者多个列,包含多个列的主键我们称为组合键或者复合键)
4.1.2 设置外键
create table 表名(
....
外键列
[constraint] [外键名称] foreign key (外键列名称) references 主表名称(主表列名称)
);
CREATE TABLE 表名
(
字段名1 数据类型,
字段名1 数据类型,
primary key (字段名1)
)
4.1.3 非空约束
字段名 数据类型 NOT NULL;
4.1.4 唯一约束
字段名 数据类型 UNIQUE;
4.1.5 默认约束
字段名 数据类型 DEFAULT 默认值;
4.1.6 检测约束
ALTER TABLE 表名 ADD CONSTRAINT <检查约束名> CHECK(<检查约束>)
例:在表(t_admin )中,adm_age列中的值只能是>=18。
ALTER TABLE t_admin ADD CONSTRAINT ck_admin_age CHECK(adm_age>=18)
注:<检查约束名>可以随便取,最好直观一些
4.1.7 使用ALTER TABLE设置约束
ALTER TABLE 表名 ADD 约束类型 列名;
4.1.8 使用ALTER TABLE删除约束
ALTER TABLE 表名 DROP 约束类型;
5 设置表的字段值自动增加
字段名 数据类型 auto_increment;
例:设置自增主键
CREATE TABLE table_name
(
id int(20) primary key auto_increment,
字段名2 数据类型[完整性约束],
......
字段名n 数据类型[完整性约束]
)
6 数据的增、删、改、查
6.1 增加数据
#值和表的列要一一对应
INSERT INTO 表名称 VALUES (值1, 值2,....)
#值和指定的列要一一对应
INSERT INTO 表名称 (列1, 列2,...) VALUES (值1, 值2,....)
#插入多条数据
INSERT INTO 表名称
VALUES
(值1, 值2,....),
(值1, 值2,....),
(值1, 值2,....)
.....
(值1, 值2,....);
6.2 删除数据
6.2.1 DELETE
DELETE FROM 表名[WHERE 条件];
注意:
(1) 如果两张表有主外键关联关系,需要先删除从表中的数据,再删除主表中的数据
(2) Delete 如果不加where条件是删除表中的所有数据,同等于删除整张表
6.2.2 Truncate
- Truncate table语句用来删除/截断表里的所有数据
- 和delete删除所有表数据在逻辑上含义相同,但性能更快
- 执行delete操作时,会写日志。truncate操作不写入日志。
- 类似执行了drop table和create table两个语句
- delete删除的数据可以通过rollback 找回来,而truncate删除的数据不行。
TRUNCATE TABLE 表名;
6.3 修改数据
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
UPDATE 表名称 SET 列1 = 值1,列2 = 值2,..... WHERE 列名称 = 某值
注:如果不加入where条件,所有行的对应列都会被修改。
6.4 查询数据
6.4.1 基本查询
- 显示所有的列
SELECT * FROM 表名;
** ,代表所有的列,但是建议大家在以后的工作中不要使用,号在查询的过程中是最慢的。*
- 显示部分的列
SELECT 列名1 [as 列的别名],列名2 [as 列的别名],列名3 [as 列的别名] FROM 表名;
6.4.2 查询中的四则运算
SELECT 表名.列名1 [as 列的别名] * 表名.列名2 [as 列的别名] FROM 表名;
** 注:null和任何值计算,其结果均为null。**
6.4.3 Distinct (去除查询结果中的重复项)
- Distinct 去掉重复项,去掉查询结果重复的行数据,而不是列数据
SELECT Distinct * FROM 表名;
6.4.4 限定查询 WHERE
SELECT * FROM 表名
WHERE 条件(必须是返回布尔值的判断语句);
** 注:
(1)比较null值,如果是null 使用is null
(2)如果是非null 使用 is not null**
SELECT * FROM 表名
WHERE 列名 IS NULL;
SELECT * FROM 表名
WHERE 列名 IS NOT NULL;
判断是否为空(错误示范):
#以下写法均是错误的,上面的才是对的
SELECT * FROM 表名 WHERE 列名 = NULL;
SELECT * FROM 表名 WHERE 列名 != NULL;
** 注:NOT在SQL中是取反**
6.5 连接符
- 连接符 and 并且 ;or 或者 ; not 取反(如果原来是真的,就变成假的,)
- and对应&&,也就是并
- or对应||,也就是或
- not对应!,也就是取反
6.6 日期
6.6.1 日期的比较
- 日期也可以用来比较大小,(日期越往后越大)
- 日期越往后越大
select * from 表名 where 日期列> '2020-01-12';
6.6.2 日期的查询
- 格式不一致的话,要使用函数规范格式
#查询2013年1月份加入的产品
select * from 表名 where date(add_time) between '2013-01-01' and '2013-01-31';
--你还可以这样写:
select * from 表名 where Year(add_time) = 2013 and Month(add_time) = 1;
查询当天数据
SELECT * FROM `表名` WHERE TO_DAYS(NOW()) - TO_DAYS(`字段`) = 0;
查询昨天数据
SELECT * FROM ``表名`` WHERE TO_DAYS(`字段`) = TO_DAYS(NOW()) -1;
SELECT * FROM ``表名`` WHERE TO_DAYS(`字段`) - TO_DAYS(NOW()) = -1;
SELECT * FROM ``表名`` WHERE TO_DAYS(NOW()) = TO_DAYS(`字段`) +1;
SELECT * FROM ``表名`` WHERE TO_DAYS(NOW()) - TO_DAYS(`字段`) = 1;
查询最近七天数据
SELECT * FROM `表名` WHERE DATE_SUB(CURDATE(),INTERVAL 7 DAY) <= DATE(`字段`);
6.7 Like模糊查询
- %表示0或多个字符
- _表示1个字符
查询第二个字符是苏的字段
SELECT * FROM 表名 WHERE 列名 like '_苏%';
6.8 转义字符(escape )
- escape 可将转义字符转化为普通字符
- escape 只能把一个字符转化为普通字符
查询第一个字符是_的字段
SELECT * FROM 表名 WHERE 列名 like '_%' escape '_';
6.8 Order by 排序
- asc 表示升序
- desc 降序
- Order by后可以有多个排序,以‘,’隔开
降序排列
SELECT * FROM 表名 ORDER BY 列名1,列名2 DESC;
注:若列1值相同,比较列2
6.9 聚合函数
函数名称 | 作用 |
---|---|
count() | 计算数量 |
min() | 最小值 |
max() | 最大值 |
sum() | 求和 |
avg() | 平均值 |
SELECT 函数操作 FROM 表名 ORDER BY 列名1,列名2 DESC;
6.10 分组统计(group by)
一个完整的SQL查询语句结构如下:
# *代表所有字段
SELECT [DISTINCT] *|{字段名1, 字段名2, 字段名3,……}
FROM 表名
[WHERE 条件表达式1]
[GROUP BY 字段名 [HAVING 条件表达式2]]
[ORDER BY 字段名 [ASC|DESC]]
[LIMIT [OFFSET] 记录数]
例: 统计每种图书的数量
SELECT BOOK_TYPE AS 图书分类,COUNT(1) AS 数量 FROM T_BOOK_INFO
GROUP BY BOOK_TYPE;
注意,在select关键字后面,只能出现,聚合函数的列和group by后面的出现列
错误:BOOK_ID
#count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL
#count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL
#count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是表示null)的计数,即某个字段值为NULL时,不统计。
SELECT BOOK_TYPE ,BOOK_ID,COUNT(1) FROM T_BOOK_INFO
GROUP BY BOOK_TYPE;
6.10 having(过滤)
- having一般是group by是组合着用的
查询每个作者中编写不同类型的图书数量,并且出版数量大于1
SELECT BOOK_TYPE ,BOOK_AUTHOR,COUNT(1) FROM T_BOOK_INFO
GROUP BY BOOK_TYPE,BOOK_AUTHOR;
HAVING COUNT(1)>1;
#count(1)改成列名也一样
6.11 分页(limit)
- limit [参数1,]参数2;
- 参数1可以省略
- 参数1用来指定开始索引的序号,参数2是用来限制返回的条数
- 当只有一个参数时,从第一条数据开始索引
第0条开始索引,返回3条数据
SELECT * FROM 表名
LIMIT 0,3
6.11 多表查询
6.11.1 笛卡尔积
得到的数据量是多个表的数据乘积
SELECT * FROM
表1,表2,...,表n;
在乘积表中进行筛选
SELECT * FROM
表1,表2,...,表n
[WHERE 条件]
[GROUP BY列]
[HAVING 条件]
[ORDER BY 列];
6.12 接查询(inner join …. on)
6.12.1 内连接(inner join …. on)
- 内连接一种特殊形式,自连接(自己连接自己,同一个表取不同的表名,当做两张或多张表使用)
select 字段 from 表1 inner join 表2 on 表1.字段1=表2.字段2;
6.12.1 外连接(left/right join …. on)
例如左连接,以左边的值为主,左边的列不会出现NULL
左连接
SELECT * FROM 表名 别名1 LEFT JOIN 表名 别名2 ON 别名1.列1 = 别名2.列2;
右连接
SELECT * FROM 表名 别名1 RIGHT JOIN 表名 别名2 ON 别名1.列1 = 别名2.列2;
6.13 子查询
6.13.1 嵌套查询
- 子查询写在where条件中
- 子查询与表连接可以互换 (子查询返回的是一个表,就是返回表进行表连接)
- 子查询写在from后面
- 子查询写在select后面(表与表之间是一对多的关系,查询结果多余1条就会报错)
写在where条件中(WHERE返回的是布尔值)
例:查询价格大于平均值的书
SELECT * FROM book_info
WHERE book_money>(SELECT avg(book_money)
FORM t_book_info);
查询写在from后面
例:书籍id大于2的平均值,id>2的书的价格大于平均值的书
SELECT * FROM
(SELECT book_info FROM book_info .book_id>2) i
WHERE i.book_money>(SELECT avg(book_money) FORM t_book_info)
FORM t_book_info;
子查询写在select后面
SELECT u.user_name,
(SELECT message_info from t_message WHERE message_to_user_id=u.user_id)
FROM t_user u;
6.13.1 多行一列,使用in关键字
SELECT * FROM t_message
WHERE message_to_user_id in (
SELECT user_id FROM t_user
WHERE user_name='道玄' or user_name='张小凡');
扩展:也可以多行多列
6.13.1 ANY,ALL
- ANY 任意一个符合条件
- ALL全部符合条件
ANY(以下例子是大于两个之中的最小值)
SELECT * FROM t_message
WHERE message_to_user_id>any(select user_id from t_user
where user_name='道玄'oruser_name='张小凡');
ALL(以下例子是大于两个之中的最大值)
SELECT * FROM t_message
WHERE message_to_user_id>any(select user_id from t_user
where user_name='道玄'oruser_name='张小凡');
7 事务
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
事务用来管理 insert,update,delete 语句
一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
1.原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
2.一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
3.隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Readun committed)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
4.持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
7.1 事务的操作
开启事务:
SET autocommit=off;
或
SET autocommit=0;
关闭事务:
SET autocommit=on;
或
SET autocommit=1;
事务回滚(回滚到上一次提交状态)
rollback;
注:提交或回滚都代表事务的结束
8 函数
前面讲过一些聚合函数,因为查询中经常用到,就拎出来先讲了。
下面列出来的是一些常用的函数,详细的去别处看吧,啊哈哈哈
8.1 字符处理函数
函数名称 | 作用 |
---|---|
CONCAT(str1,str2,…,strn) | 将str1,str2,…,strn连接为一个完整的字符串 |
INSERT(str,x,y,instr) | 将字符串str从第x开始,y个字符串长度的子串替换为字符串instr |
LOWER(str) | 将字符串str中的所有字母变成小写 |
UPPER(str) | 将字符串str中的所有字母变成大写 |
LENGTH(str) | 返回字符串str中的字符串长度 |
SEVERSE(str) | 反转字符串str,并返回 |
TRIM(str) | 去除字符串str左右两端的空格 |
REPLACE(str,oldStr,newStr) | 把str中的oldStr替换成newStr,并返回 |
SUBSTR(str,index,length) | 从index位置开始截取字符串str,一共截取length个字符,并返回(如果没有length参数,则默认截取到末尾) |
8.2 数值处理函数
函数名称 | 作用 |
---|---|
CEIL(N) | 返回大于或等于N的最小整数 |
FLOOR(N) | 返回小于或等于N的最大整数 |
ROUND(N,S) | 返回N保留S位小数(会四舍五入),不写参数S默认为0 |
TRUNCATE(N,S) | 返回N保留S位小数(不会四舍五入),不能省略参数S |
RAND() | 返回[0,1)之间的随机数 |
8.2 日期处理函数
函数名称 | 作用 |
---|---|
NOW() | 返回当前的日期和时间,精确到秒 |
CURDATE() | 返回当前时间 |
DATE(date) | 获取日期时间或者日期的日期部分 |
CURTIME() | 返回当前时间的时分秒 |
YEAR(DATE) | 提取日期中的年 |
MONTH(DATE) | 提取日期中的月 |
DAY(DATE) | 提取日期中的天 |
TIME(DATE) | 提取日期中的时分秒 |
TIMESTAMPDIFF(INTERVAL,DATETIME1,DATETIME2) | 比较DATETIME2和DATETIME1的插值,值的类型由INTERVAL绝对(是比较相差多少年还是月的意思) |
DATE_FORMAT(DATE,PATTERN) | 把日期类型根据 PATTERN的格式转换 |
注: PATTERN的格式写法(区分大小写):
%Y | 年 |
---|---|
%m | 月 |
%d | 日 |
%H | 时 |
%i | 分 |
%s | 秒 |
8.3 流程控制函数
函数名称 | 作用 |
---|---|
ifnull(arg1,arg2) | 如果arg1的值为null,则返回arg2,否则返回arg1的值 |
id(flag,arg1,arg2) | 如果flag为true。则返回arg1,否则返回arg2 |
case-when | 判断多个条件(具体直接砍下面例子) |
-- 当满足某一条件时,执行某一result,把该结果赋值到new_name 字段中
case
when condition1 then result1
when condition2 then result2
when condition3 then result3
else result
end new_name;
case val
when 1 then 'val is 1'
when 2 then 'val is 2'
else select 'val is not 1 or 2'
end case;