MySQL教程 你想要的几乎都有
文章目录
- MySQL
- SQL语言
- MySQL应用
- 数据查询
- 数据库表的基本结构
- 基本查询
- 查询部分列
- 对列中数据进行运算
- 排序查询
- 条件查询
- 等值判断
- 不等式判断
- 逻辑判断
- 区间判断
- NULL值判断
- 枚举查询
- 模糊查询
- 分支结构查询
- 时间查询
- 字符串查询
- 字符串应用
- 聚合函数
- 分组查询
- 查询各部门的人口总数
- 查询各部门的平均工资
- 查询各个部门的各个岗位的人数
- 常见问题
- 分组过滤查询
- 限定查询
- 查询总结
- 子查询
- 作为条件判断
- 作为枚举条件
- 作为一张表
- 合并查询
- 合并两张表的结果(去除重复记录)
- 合并两张表的结果(保留重复记录)
- 表连接查询
- 内连接
- 三表连接查询
- 左外连接
- 右外连接
- DML操作
- 新增(INSERT)
- 添加一条信息
- 修改(UPDATE)
- 修改一条信息
- 删除(DELETE)
- 删除一条信息
- 清空数据表(TRUNCATE)
- 清空整张表
- 数据表操作
- 数据类型
- 数值类型
- 日期类型
- 字符串类型
- 数据表的创建
- 创建表
- 数据表的修改(ALTER)
- 约束
- 实体完整性约束
- 主键约束
- 唯一约束
- 自动增长列
- 域完整性约束
- 非空约束
- 默认值约束
- 引用完整性约束
- 事务
- 事务的边界
- 事务的原理
- 事务的特性
- MySQL 临时表
- 实例
- 删除MySQL 临时表
- MySQL 元数据
- MySQL 导出数据
- 使用 SELECT ... INTO OUTFILE 语句导出数据
- SELECT ... INTO OUTFILE 语句
- 导出表作为原始数据
- 导出 SQL 格式的数据
- 将数据表及数据库拷贝至其他主机
MySQL
SQL语言
结构化查询语言 , 用于存取数据 , 更新 , 查询和管理关系数据库系统的程序设计语言.
通常对数据进行"增删改查", 简称CRUD.
MySQL应用
对于数据库的操作 , 需要进入MySql环境下进行指令的输入 , 并在每一句后边加分号.
数据查询
数据库表的基本结构
关系结构数据库是以表格(table)进行数据存储 , 表格由"行"和"列"组成
- 经验 : 执行查询语句返回的结果集是一张虚拟表
基本查询
语法 : SELECT 列名 FROM 表名
关键字 | 描述 |
---|---|
SELECT | 指定要查询的列 |
FROM | 指定要查询的表 |
查询部分列
#查询员工表中所有员工的编号 , 名字 , 邮箱
SELECT employee_id,first_name,email FROM t_employees;
SELECT * FROM t_employees;
使用*的效率很低 , 工程级项目中最好使用列名
对列中数据进行运算
列的别名
列名 as ‘列名’
#查询员工表中所有员工的编号,名字,年薪
select EMPLOYEE_ID as '员工编号', FIRST_NAME , SALARY * 12 as '年薪'
from t_employees;
查询结果去重
distinct 列名
#查询员工表中所有经理的id
select distinct MANAGER_ID
from t_employees;
排序查询
语法: SELECT 列名 FROM 表名 ORDER BY 排序列 [排序规则]
排序规则 | 描述 |
---|---|
ASC | 对前面排序列做升序排序 |
DESC | 对前面排序列做降序排序 |
#按工资进行升序降序排序
select EMPLOYEE_ID,SALARY from t_employees order by SALARY ASC;
- 依据多列排序
#先依据工资降序,再依据编号升序
SELECT EMPLOYEE_ID,SALARY from t_employees order by SALARY DESC ,EMPLOYEE_ID ASC;
条件查询
语法: SELECT 列名 FROM 表名 WHERE 条件
关键字 | 描述 |
---|---|
WHERE 条件 | 在查询结果中 , 筛选符合条件的查询结果 , 条件为布尔表达式 |
等值判断
SELECT employee_id , first_name , salary
from t_employee
where salary = 10000;
与java不同 , mysql等号表示判断
不等式判断
判断符号有 > , < , >= , <= , != , <>
select EMPLOYEE_ID,FIRST_NAME,LAST_NAME,SALARY
from t_employees
where SALARY >= 10000;
逻辑判断
and , or , not
select EMPLOYEE_ID,FIRST_NAME,LAST_NAME,SALARY,COMMISSION_PCT
from t_employees
where COMMISSION_PCT = 0.3 and SALARY < 20000 ;
区间判断
between and (闭区间)
select EMPLOYEE_ID,FIRST_NAME,LAST_NAME,SALARY
from t_employees
where SALARY between 10000 and 20000
order by SALARY;
NULL值判断
is null , is not null
select EMPLOYEE_ID,FIRST_NAME,LAST_NAME,SALARY
from t_employees
where COMMISSION_PCT is null ;
枚举查询
IN (值1 , 值2 , 值3… )
select EMPLOYEE_ID,FIRST_NAME,LAST_NAME,SALARY,DEPARTMENT_ID
from t_employees
where DEPARTMENT_ID in (70 , 80 ,90);
模糊查询
LIKE _ (单个任意字符)
列名 LIKE ‘张_’
% (任意长度任意字符)
列名 LIKE ‘张%’
#定长查询
select EMPLOYEE_ID,FIRST_NAME,LAST_NAME,SALARY,DEPARTMENT_ID
from t_employees
where FIRST_NAME like 'C____';
#不定长查询
select EMPLOYEE_ID,FIRST_NAME,LAST_NAME,SALARY,DEPARTMENT_ID
from t_employees
where FIRST_NAME like 'C%';
分支结构查询
类似于Java的Switch
语法 : CASE
WHEN …THEN…
WHEN …AND…THEN…
WHEN …AND…THEN…
ELSE …
END
select EMPLOYEE_ID,FIRST_NAME,LAST_NAME,SALARY,CASEWHEN SALARY > 20000 THEN 'A'WHEN SALARY > 15000 AND SALARY < 20000 THEN 'B'WHEN SALARY > 10000 AND SALARY < 15000 THEN 'C'WHEN SALARY > 5000 AND SALARY < 10000 THEN 'D'ELSE 'E' END AS 'Salary Level'FROM t_employees
order by SALARY desc ;
时间查询
语法 : SELECT 时间函数([时间参数])
- 执行时间函数查询 , 会自动生成一张虚表(一行一列)
时间函数 | 描述 |
---|---|
SYSDATE() | 当前系统时间(日月年时分秒) |
CURDATE() | 获取当前日期 |
CURTIME() | 获取当前时间 |
WEEK(DATE) | 获取指定日期是第几周 |
YEAR(DATE) | 获取指定日期的年份 |
HOUR(DATE) | 获取指定日期的小时 |
MINUTE(DATE) | 获取指定日期的分钟 |
DATEDIFF(DATE1,DATE2) | 比较两个日期相隔天数 |
ADDDATE(DATE,N) | 计算增加N天后DATE的日期 |
select sysdate();
select curdate();
select curtime();
select week(sysdate());
select hour(sysdate());
select minute(sysdate());
select datediff(sysdate(), '2017-05-04 17:00:00');
select adddate(sysdate(), 1000);
字符串查询
语法 : SELECT 字符串函数 ([参数列表])
字符串函数 | 说明 |
---|---|
CONTACT(str,str2,str3…) | 将多个字符串连接 |
INSERT(str,pos,len,newStr) | 将str指定pos位置开始(起始为1)len长度内容替换为newStr |
LOWER(str) | 将指定字符串转化为小写 |
UPPER(str) | 将指定字符串转化为大写 |
SUBSTRING(str,num,len) | 将str字符串指定num位置开始截取len个内容 |
字符串应用
#拼接字符串
select CONCAT(FIRST_NAME, ' ', LAST_NAME);#字符串替换
SELECT INSERT ('这是一个数据库',3,2,'MySQL');#指定内容转换为小写
SELECT LOWER('MySQL');
#指定内容转换为大写
SELECT UPPER('MYSQl');#指定内容截取
SELECT SUBSTRING('HELLOWORLD',6,5);
聚合函数
语法 : SELECT 聚合函数(列名) FROM 表名;
- 对多条数据的单列进行统计 , 返回统计后的一行结果
聚合函数 | 说明 |
---|---|
SUM() | 求所有行中单列结果的总和 |
AVG() | 平均值 |
MAX() | 最大值 |
MIN() | 最小值 |
COUNT() | 求总行数 |
SELECT SUM(SALARY) FROM t_employees;
SELECT AVG(SALARY) FROM t_employees;
SELECT MAX(SALARY) FROM t_employees;
SELECT MIN(SALARY) FROM t_employees;
SELECT COUNT(EMPLOYEE_ID) FROM t_employees;
#COUNT会自动忽略NULL值
SELECT COUNT(COMMISSION_PCT) FROM t_employees;
- COUNT()会自动忽略NULL值不进行统计
分组查询
语法 : SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组依据 (列);
关键字 | 说明 |
---|---|
GROUP BY | 分组依据 , 必须在WHERE之后生效 |
查询各部门的人口总数
#查询各部门的人员总数,并按人数从小到大排序
SELECT DEPARTMENT_ID, COUNT(EMPLOYEE_ID)
FROM t_employees
GROUP BY DEPARTMENT_ID
ORDER BY count(EMPLOYEE_ID);
查询各部门的平均工资
#查询各部门的平均工资,并从大到小排序
SELECT DEPARTMENT_ID, AVG(SALARY)
FROM t_employees
GROUP BY DEPARTMENT_ID
ORDER BY AVG(SALARY) DESC;
查询各个部门的各个岗位的人数
#查询各个部门各个岗位的人数
SELECT DEPARTMENT_ID, JOB_ID, COUNT(EMPLOYEE_ID)
FROM t_employees
GROUP BY DEPARTMENT_ID, JOB_ID
ORDER BY DEPARTMENT_ID;
常见问题
分组查询中 , SELECT显示的列只能是分组依据 , 或者聚合函数列 , 不能出现其他列
分组过滤查询
语法 : SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组列 HAVING 过滤规则
关键字 | 说明 |
---|---|
HAVING 过滤规则 | 过滤规则定义对分组后的数据进行过滤 |
#筛选出60,70,90部门的最高工资
select DEPARTMENT_ID , max(SALARY)
from t_employees
group by DEPARTMENT_ID
having DEPARTMENT_ID in (60,70,90);
限定查询
SELECT 列名 FROM 表名 LIMIT 起始行 , 查询行数
关键字 | 说明 |
---|---|
LIMIT offset_start, row_count | 限定查询结果的起始行数和总行数 |
#查询前五行记录
#查询第0行之后的五行
select *
from t_employees
limit 0,5;#查询范围记录
#查询第6行之后的五行
select *
from t_employees
limit 6,5;# LIMIT典型应用
#分页查询,一页显示10条,一共查询三页
select *
from t_employees
limit 0,10;
select *
from t_employees
limit 10,10;
select *
from t_employees
limit 20,10;
查询总结
SELECT 列名
FROM 表名
WHERE 条件
GROUP BY 分组
HAVING 过滤条件
ORDER BY 排序列
LIMIT 起始行 , 总行数
执行顺序:
- FROM : 指定元素来源
- WHERE : 对查询数据做第一次过滤
- GROUP BY : 分组
- HAVING : 对分组后的数据做第二次过滤
- SELECT : 查询各字段的值
- ORDER BY : 排序
- LIMIT : 限定查询结果
子查询
作为条件判断
将查询结果作为条件的查询称为子查询
语法 : SELECT 列名 FROM 表名 WHERE 条件(子查询结果)
#查询工资大于Bruce的人
select *
from t_employees
where SALARY > (SELECT SALARYfrom t_employeeswhere FIRST_NAME = 'Bruce');#工资高于60部门所有人的所有人信息
SELECT *
FROM t_employees
WHERE SALARY > (SELECT MAX(SALARY)FROM t_employeesWHERE DEPARTMENT_ID = 60
);
- 注意 : 将子查询"一行一列"的结果作为外部查询的条件 , 作第二次查询
- 子查询得到一行一列的结果才能作为外部查询的等值判断条件
作为枚举条件
#查询名字为KING的人所在部门的所有员工
SELECT *
FROM t_employees
WHERE DEPARTMENT_ID IN (SELECT DEPARTMENT_IDFROM t_employeesWHERE LAST_NAME = 'King'
);#工资高于60部门所有人的所有人信息
SELECT *
FROM t_employees
WHERE SALARY > (SELECT MAX(SALARY)FROM t_employeesWHERE DEPARTMENT_ID = 60
);#大于全部60部门人员工资
SELECT *
FROM t_employees
WHERE SALARY > ALL (SELECT SALARYFROM t_employeesWHERE DEPARTMENT_ID = 60);#大于部分60部门人员工资
SELECT *
FROM t_employees
WHERE SALARY > ANY(SELECT SALARYFROM t_employeesWHERE DEPARTMENT_ID = 60
);
- 将子查询"多行一列"的结果作为查询条件,做第二次查询
- 子查询结果为多行单列时可以用ANY或者ALL关键字
作为一张表
SELECT 列名 FROM (子查询的结果集) WHERE 条件;
#工资排名前五的人员所有信息
SELECT *
FROM (SELECT * FROM t_employees ORDER BY SALARY DESC ) AS TEMP
LIMIT 0,5;
- 将子查询"多行多列"的结果作为外部查询的一张表 , 做第二次查询
- 注意 : 子查询为临时表 , 或者说是一张虚拟表 , 是不存在的 , 就类似于变量 , 你必须给它一个名字
合并查询
SELECT * FROM 表名1 UNION SELECT * FROM 表名2
SELECT * FROM 表名1 UNION ALL SELECT * FROM 表名2
合并两张表的结果(去除重复记录)
SELECT * FROM 表名1 UNION SELECT * FROM 表名2
- 合并结果的两张表 , 列数必须相同 , 列的数据类型可以不同
- 合并结果的列名会以第一张表的列明为准 , 进行数据的纵向拼接
合并两张表的结果(保留重复记录)
SELECT * FROM 表名1 UNION ALL SELECT * FROM 表名2
表连接查询
SELECT 列名 FROM 表1 连接方式 表2 ON 连接条件
- 不指定条件 , 则会造成笛卡尔积的结果
内连接
#内连接 SQL标准
SELECT *
FROM t_employeesINNER JOIN t_jobs ON t_employees.JOB_ID = t_jobs.JOB_ID;#上边其实等同于在MySQL中下列代码
SELECT *
FROM t_employees,t_jobs
WHERE t_jobs.JOB_ID = t_employees.JOB_ID;
由于SQL标准中没有下边的表达方式 , 所有上边的表达方式在SQL中是通用的.
三表连接查询
#查询所有员工工号 , 名字 , 部门名称 , 部门所在国家id
SELECT EMPLOYEE_ID, CONCAT(FIRST_NAME, LAST_NAME) AS NAME, DEPARTMENT_NAME, COUNTRY_ID
FROM t_employees eINNER JOIN t_departments dON e.DEPARTMENT_ID = d.DEPARTMENT_IDINNER JOIN t_locations tON d.LOCATION_ID = t.LOCATION_ID;
左外连接
#查询所有员工信息,以及所对应的部门名称(没有部门的员工,也在查询结果中,部门名称以NULL填充)
SELECT *
FROM t_employees eLEFT JOIN t_departments td on e.DEPARTMENT_ID = td.DEPARTMENT_ID;
- 左外连接 , 是以左表为主表 , 依次向右匹配 , 匹配到 返回结果, 匹配不到 , 则都返回NULL补全
右外连接
#查询所有员工信息,以及所对应的部门名称(没有员工的部门,也在查询结果中,员工名称以NULL填充)
SELECT *
FROM t_employees ERIGHT JOIN t_departments td on E.DEPARTMENT_ID = td.DEPARTMENT_ID;
- 右外连接 , 是以右表为主表 , 依次向左匹配 , 匹配到 返回结果, 匹配不到 , 则都返回NULL补全
DML操作
新增(INSERT)
INSERT INTO 表名(列1,列2,列3,…) VALUES(值1,值2,值3…)
添加一条信息
#添加一条工作岗位信息
INSERT INTO t_jobs (JOB_ID, JOB_TITLE, MIN_SALARY, MAX_SALARY)
VALUES ('ST_MA', 'Programmer', 15000, 36000);#添加一条员工信息
INSERT INTO t_employees (EMPLOYEE_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB_ID, SALARY, COMMISSION_PCT, MANAGER_ID, DEPARTMENT_ID)
VALUES ('996', 'Jason', 'James', 'JAMES', '999.999.9999', '1996-11-01', 'ST_MA', 36000, '0.4', '111', '001');
- 注意表名后的列名和values里的值要一一对应(个数, 顺序, 类型)
修改(UPDATE)
UPDATE 表名 SET 列1=新值1, 列2=新值2, 列3=新值3…WHERE 条件
修改一条信息
#修改员工编号为100的员工工资为25000
UPDATE t_employees SET SALARY = 25000
WHERE EMPLOYEE_ID = '100';#修改编号为135的员工信息岗位编号为 ST_MAN ,工资为3500
UPDATE t_employees
SET SALARY=3500,JOB_ID='ST_MAN'
WHERE EMPLOYEE_ID = '135';
- SET后多个列名=值 , 绝大多数情况下都要加WHERE条件来限定修改的目标 , 否则就变成了全表更新
删除(DELETE)
DELETE FROM 表名 WHERE 条件;
删除一条信息
#删除编号为135的员工
DELETE FROM t_employees
WHERE EMPLOYEE_ID = '135';#删除姓Peter,名为Hall的员工
DELETE FROM t_employees
WHERE FIRST_NAME = 'Peter' AND LAST_NAME = 'Hall';
- 注意: 删除时没有WHERE条件可就全删了删库跑路预备
- 是对数据操作
清空数据表(TRUNCATE)
删库跑路预警
TRUNCATE TABLE 表名;
清空整张表
#清空国家信息表
TRUNCATE TABLE t_countries;
- 与DELETE不同 , 这个会删除表然后照着原来再生成一张新表(跟原来表结构一样)
- 是对表得操作
数据表操作
数据类型
数值类型
类型 | 大小 | 范围(有符号) | 范围(无符号) | 用途 |
---|---|---|---|---|
INT | 4字节 | (-2147483648, 2147483647) | (0, 4294967295) | 大整数值 |
DOUBLE | 8字节 | 不记了 反正你用的肯定在范围内 | 同左 | 双精度浮点数 |
DOUBLE(M, D) | 8字节(M表示长度, D表示小数位数) | 同上 | 同上 | 双精度浮点数 |
DECIMAL(M, D) | DECIMAL(M, D) | 依赖于M和D的值,M最大为65 | 依赖于M和D的值,M最大为65 | 小数值 |
日期类型
类型 | 大小 | 范围 | 格式 | 用途 |
---|---|---|---|---|
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 | 省略 | 著名的千禧年bug的来源 |
字符串类型
类型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255字符 | 定长字符串cha(10)10个字符 |
VARCHAR | 0-65535字节 | 变长字符串varchar(10)10个字符 |
BLOB | 0-65535字节 | 二进制类型长文本数据 |
TEXT | 0-65535字节 | 长文本数据 |
- CHAR和VARCHAR类型类似, 但是它们的保存和索引方式不同, 它们的最大长度和是否尾部空格被保留等方面也不同, 在存储或检索过程中不进行大小写转换
- BLOB是一个二进制大对象, 可以容纳可变数量的数据, 有4中BLOB类型: TINYBLOB, BLOB, MEDIUMBLOB和LONGBLOB, 它们可容纳的长度不同
数据表的创建
CREATE TABLE 表名 (列名 数据类型 [约束],列名 数据类型 [约束],列名 数据类型 [约束],......#最后一列不加逗号列名 数据类型 [约束]#设置编码类型
) charset=utf8
创建表
列名 | 数据类型 | 说明 |
---|---|---|
subject_ID | INT | 课程编号 |
subject_Name | VARCHAR(20) | 课程名称 |
subject_Hours | INT | 课时 |
CREATE TABLE Subject_db
(subject_ID INT,subject_Name VARCHAR(20),subject_Hours INT) CHARSET = UTF8;INSERT INTO Subject_db(SUBJECT_ID, SUBJECT_NAME, SUBJECT_HOURS) VALUES (001,'离散数学',48);
INSERT INTO Subject_db(SUBJECT_ID, SUBJECT_NAME, SUBJECT_HOURS) VALUES (002,'C 语言',36);
INSERT INTO Subject_db(SUBJECT_ID, SUBJECT_NAME, SUBJECT_HOURS) VALUES (003,'数据结构',48);
INSERT INTO Subject_db(SUBJECT_ID, SUBJECT_NAME, SUBJECT_HOURS) VALUES (004,'计算机网络',36);
INSERT INTO Subject_db(SUBJECT_ID, SUBJECT_NAME, SUBJECT_HOURS) VALUES (005,'计算机组成原理',48);
INSERT INTO Subject_db(SUBJECT_ID, SUBJECT_NAME, SUBJECT_HOURS) VALUES (006,'操作系统',24);
INSERT INTO Subject_db(SUBJECT_ID, SUBJECT_NAME, SUBJECT_HOURS) VALUES (007,'面向对象编程',48);
INSERT INTO Subject_db(SUBJECT_ID, SUBJECT_NAME, SUBJECT_HOURS) VALUES (008,'Java程序设计基础',48);
INSERT INTO Subject_db(SUBJECT_ID, SUBJECT_NAME, SUBJECT_HOURS) VALUES (001,'软件体系结构',48);
INSERT INTO Subject_db(SUBJECT_ID, SUBJECT_NAME, SUBJECT_HOURS) VALUES (001,'人工智能概论',48);
数据表的修改(ALTER)
ALTER TABLE 表名 操作;
#向现有表中添加列
ALTER TABLE Subject_dbADD SUBJECT_GRADE INT;#修改现有表中的列
ALTER TABLE Subject_dbMODIFY subject_Name VARCHAR(10);#删除表中的列
ALTER TABLE Subject_dbDROP SUBJECT_GRADE;#修改表中列名
ALTER TABLE Subject_dbCHANGE subject_Hours ClassHours INT;#删除表
DROP TABLE Subject_db;
- 修改表中某列时也要写上列的全称, 数据类型, 约束
- 删除列时每次只能删除一列
- 修改列名时也要表名列的数据类型, 约束
约束
能否在表中插入相同的两行数据 ?
如果可以有什么弊端?
就如同上边的单位人员编号一样 , 就会出现两个一样的人的概念
显然是不正确的 , 所以就需要对数据加以约束
实体完整性约束
表中的每一行元素代表一个整体 , 实体完整性的作用即是标识每一行元素不重复
主键约束
PRIMARY KEY 唯一 , 标识表中的一行数据 , 此列值不可重复且不能为NULL
#为表中适用于主键约束列添加约束
CREATE TABLE Subject_db
(subject_ID INT PRIMARY KEY,subject_Name VARCHAR(20),subject_Hours INT) CHARSET = UTF8;
唯一约束
UNIQUE 唯一 , 标识表中的一行数据 , 不可重复 , 可以为NULL
#失败已存在
ALTER TABLE Subject_dbCHANGE subject_Name subject_Name VARCHAR(30) UNIQUE;
#成功,课程名为空
INSERT INTO Subject_db
VALUES (011,null,36);
自动增长列
AUTO_INCREMENT 自动增长 , 给主键数值添加自动增长 . 从1开始 , 每次加1. 不能单独使用 , 和主键配合
#修改约束
ALTER TABLE Subject_db
CHANGE subject_ID subject_ID INT AUTO_INCREMENT;
INSERT INTO Subject_db (subject_Name,subject_Hours) VALUES ('高等数学',36);
SELECT * FROM Subject_db;
域完整性约束
限制单元格数据的正确性
非空约束
NOT NULL 非空 , 此列必须有值
#修改课程名称约束为唯一且非空
ALTER TABLE Subject_dbCHANGE subject_Name subject_Name VARCHAR(20) UNIQUE NOT NULL ;
默认值约束
DEAUFLT 值 为列赋予默认值 , 当新增数据不指定值时 , 书写DEAUFLT , 以指定的默认值写入
ALTER TABLE Subject_db CHANGE subject_Hours subject_Hours INT DEFAULT 24;
INSERT INTO Subject_db(SUBJECT_NAME, SUBJECT_HOURS) VALUES ('LLL',DEFAULT);
引用完整性约束
语法 : CONSTRAINT 引用名 FOREIGEN KEY (列名) REFERENCES 被引用表名(列名)
详解 : FOREIGEN KEY 引用外部表某个列的值 , 新增数据时 , 约束此列的值必须是约束列中存在的值
首先第一种 , 在创建表的时候 , 我们就赋予某个表完整性约束.
CREATE TABLE STUDENT(StuNo INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10) NOT NULL,ClassId INT NOT NULL,CONSTRAINT fk_subjectId FOREIGN KEY STUDENT(ClassId) REFERENCES Subject_db(subject_ID)
)CHAR SET UTF8;
那么这个表后续添加元素的时候 , ClassId这一列就只能存在于subject_ID之中 , 否者就会添加列失败
但是如果 , 你想把已经创建好的表的某个列添加引用完整性约束 , 而外表已经创建好并且有元素 . 那就不能直接添加一个空列在进行连接 , 因为所有数据类型的默认初始值在外表中并不存在 , 而你新生成的列要么赋值完再约束 , 要么修改外表被引用的值(比如加个空值 , 或者数值类型的初始值) , 才能引用.并且赋值后再引用也要注意不重复的值 , 如果新列中包含引用列没有的值 , 那么也不能引用约束成功
- 当两张表存在引用关系 , 执行删除操作时 , 一定要先删除从表(引用表) , 再删除主表.
事务
首先模拟一个问题 , 银行转账
我们先建一个表来显示账户 , 以及余额
#创建银行账户表
CREATE TABLE BankCustomer(ID INT PRIMARY KEY AUTO_INCREMENT,Name VARCHAR(10) NOT NULL,Money DOUBLE(10,2) NOT NULL)CHAR SET UTF8;
给表中添加两个客户 , 模拟一下客户1给客户2转账
INSERT INTO TABLE BankCustomer(Name,Money) VALUES('Cenarius',10000.00);
INSERT INTO TABLE BankCustomer(Name,Money) VALUES('Jack',1000.00);
#转出客户扣钱
UPDATE BankCustomer SET Money = Money-1000.00 WHERE ID = 1;
#转入客户加钱
UPDATE BankCustomer SET Money = Money+1000.00 WHERE ID = 2;
现在假如执行完客户扣钱DML操作之后 , 系统出现异常中断 , 那么后边的DML操作未执行 , 就会出现账户错误
所以我们要保证一些操作的原子性 , 如果整个流程没有执行完就回到执行前的状态 , 这样的流程就叫做事务. 跟线程一个道理.
事务 : 事务是一个原子操作 , 是一个执行单位的最小单元 . 可以由一个或多个SQL语句构成 , 在同一个事务中当所有语句都执行成功时 , 整个事务成功 , 否则失败
事务的边界
- 开始 : 连接到数据库
- 结束
- 提交
- 显式提交 commit
- 隐式提交 一条创建 删除的语句 正常退出;
- 回滚
- 显式回滚 rollback
- 隐式回滚 非正常退出 , 执行了无效的语句 , 为这条语句执行回滚
事务的原理
数据库会为每一个客户端都维护一个空间独立的缓存区(回滚段),一个空间独立的缓存区(回滚段),一个事务中所有的增删改语句的执行结果都会缓存在回滚段中,只有当事务中所有SQL 语句均正常结束 (commit),才会将回滚段中的数据同步到数据库. 否则无论因为哪种原因失败,整个事务将回滚 (rollback).
事务的特性
原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
一致性(Consistency)
一致性是指事务必须使用数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行后都必须处于一致性的状态。
隔离性(Isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启一个事务,不能被其他的操作所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即使是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
MySQL 临时表
MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。
MySQL临时表只在当前连接可见,如果你使用PHP脚本来创建MySQL临时表,那每当PHP脚本执行完成后,该临时表也会自动销毁。
如果你使用了其他MySQL客户端程序连接MySQL数据库服务器来创建临时表,那么只有在关闭客户端程序时才会销毁临时表,当然你也可以手动销毁。
实例
以下的SQL代码可以适用于PHP脚本的mysql_query()函数。
CREATE TEMPORARY TABLE SalesSummary (product_name VARCHAR(50) NOT NULLtotal_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);INSERT INTO SalesSummary
(product_name, total_sales, avg_unit_price, total_units_sold)
VALUES
('cucumber', 100.25, 90, 2);SELECT * FROM SalesSummary;
当你使用 SHOW TABLES命令显示数据表列表时,你将无法看到 SalesSummary表。
如果你退出当前MySQL会话,再使用 SELECT命令来读取原先创建的临时表数据,那你会发现数据库中没有该表的存在,因为在你退出时该临时表已经被销毁了。
删除MySQL 临时表
默认情况下,当你断开与数据库的连接后,临时表就会自动被销毁。当然你也可以在当前MySQL会话使用 DROP TABLE 命令来手动删除临时表。
以下是手动删除临时表的实例:
CREATE TEMPORARY TABLE SalesSummary (
product_name VARCHAR(50) NOT NULL
total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);INSERT INTO SalesSummary(product_name, total_sales, avg_unit_price, total_units_sold)VALUES('cucumber', 100.25, 90, 2);SELECT * FROM SalesSummary;DROP TABLE SalesSummary;
MySQL 元数据
你可能想知道MySQL以下三种信息:
- 查询结果信息: SELECT, UPDATE 或 DELETE语句影响的记录数。
- 数据库和数据表的信息: 包含了数据库及数据表的结构信息。
- MySQL服务器信息: 包含了数据库服务器的当前状态,版本号等。
在MySQL的命令提示符中,我们可以很容易的获取以上服务器信息。
以下命令语句可以在 MySQL 的命令提示符使用,也可以在脚本中使用,如PHP脚本。
命令 | 描述 |
---|---|
SELECT VERSION( ) | 服务器版本信息 |
SELECT DATABASE( ) | 当前数据库名 (或者返回空) |
SELECT USER( ) | 当前用户名 |
SHOW STATUS | 服务器状态 |
SHOW VARIABLES | 服务器配置变量 |
MySQL 导出数据
MySQL中你可以使用SELECT…INTO OUTFILE语句来简单的导出数据到文本文件上。
使用 SELECT … INTO OUTFILE 语句导出数据
以下实例中我们将数据表 runoob_tbl 数据导出到 /tmp/runoob.txt 文件中:
SELECT * FROM runoob_tbl
INTO OUTFILE '/tmp/runoob.txt';
你可以通过命令选项来设置数据输出的指定格式,以下实例为导出 CSV 格式:
SELECT * FROM passwd INTO OUTFILE '/tmp/runoob.txt'
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n';
生成一个文件,各值用逗号隔开。这种格式可以被许多程序使用。
SELECT a,b,a+b INTO OUTFILE '/tmp/result.text'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;
SELECT … INTO OUTFILE 语句
- LOAD DATA INFILE是SELECT … INTO OUTFILE的逆操作,SELECT句法。为了将一个数据库的数据写入一个文件,使用SELECT … INTO OUTFILE,为了将文件读回数据库,使用LOAD DATA INFILE。
- SELECT…INTO OUTFILE 'file_name’形式的SELECT可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有FILE权限,才能使用此语法。
- 输出不能是一个已存在的文件。防止文件数据被篡改。
- 你需要有一个登陆服务器的账号来检索文件。否则 SELECT … INTO OUTFILE 不会起任何作用。
- 在UNIX中,该文件被创建后是可读的,权限由MySQL服务器所拥有。这意味着,虽然你就可以读取该文件,但可能无法将其删除。
导出表作为原始数据
mysqldump 是 mysql 用于转存储数据库的实用程序。它主要产生一个 SQL 脚本,其中包含从头重新创建数据库所必需的命令 CREATE TABLE INSERT 等。
使用 mysqldump 导出数据需要使用 –tab 选项来指定导出文件指定的目录,该目标必须是可写的。
以下实例将数据表 runoob_tbl 导出到 /tmp 目录中:
$ mysqldump -u root -p --no-create-info \--tab=/tmp RUNOOB runoob_tbl
password ******
导出 SQL 格式的数据
导出 SQL 格式的数据到指定文件,如下所示:
$ mysqldump -u root -p RUNOOB runoob_tbl > dump.txt
password ******
以上命令创建的文件内容如下:
-- MySQL dump 8.23
--
-- Host: localhost Database: RUNOOB
---------------------------------------------------------
-- Server version 3.23.58--
-- Table structure for table `runoob_tbl`
--CREATE TABLE runoob_tbl (runoob_id int(11) NOT NULL auto_increment,runoob_title varchar(100) NOT NULL default '',runoob_author varchar(40) NOT NULL default '',submission_date date default NULL,PRIMARY KEY (runoob_id),UNIQUE KEY AUTHOR_INDEX (runoob_author)
) TYPE=MyISAM;--
-- Dumping data for table `runoob_tbl`
--INSERT INTO runoob_tbl VALUES (1,'Learn PHP','John Poul','2007-05-24');
INSERT INTO runoob_tbl VALUES (2,'Learn MySQL','Abdul S','2007-05-24');
INSERT INTO runoob_tbl VALUES (3,'JAVA Tutorial','Sanjay','2007-05-06');
如果你需要导出整个数据库的数据,可以使用以下命令:
$ mysqldump -u root -p RUNOOB > database_dump.txt
password ******
如果需要备份所有数据库,可以使用以下命令:
$ mysqldump -u root -p --all-databases > database_dump.txt
password ******
–all-databases 选项在 MySQL 3.23.12 及以后版本加入。
该方法可用于实现数据库的备份策略。
将数据表及数据库拷贝至其他主机
如果你需要将数据拷贝至其他的 MySQL 服务器上, 你可以在 mysqldump 命令中指定数据库名及数据表。
在源主机上执行以下命令,将数据备份至 dump.txt 文件中:
$ mysqldump -u root -p database_name table_name > dump.txt
password *****
如果完整备份数据库,则无需使用特定的表名称。
如果你需要将备份的数据库导入到MySQL服务器中,可以使用以下命令,使用以下命令你需要确认数据库已经创建:
$ mysql -u root -p database_name < dump.txt
password *****
你也可以使用以下命令将导出的数据直接导入到远程的服务器上,但请确保两台服务器是相通的,是可以相互访问的:
$ mysqldump -u root -p database_name \| mysql -h other-host.com database_name
以上命令中使用了管道来将导出的数据导入到指定的远程主机上。
MySQL教程 你想要的几乎都有相关推荐
- 是什么包_包粽子教程,喜欢的收藏,以后想吃什么样的都可以自己包
包粽子,就是这2步难,学会了这个技巧,轻松包出好吃的糯米粽子,大家好我是傻姐,今天端午习俗是吃粽子和鸡蛋,小时候每到端午节,小孩子都会在书包里带几个鸡蛋,到学校里,吃之前先和小伙伴碰鸡蛋,谁的蛋壳先碎 ...
- 史上最简单MySQL教程详解(进阶篇)之存储引擎介绍及默认引擎设置
什么是存储引擎? MySQL存储引擎种类 MyISAM 引擎 InnoDB引擎 存储引擎操作 查看存储引擎 存储引擎的变更 修改默认引擎 什么是存储引擎? 与其他数据库例如Oracle 和SQL Se ...
- 史上最简单MySQL教程详解(进阶篇)之索引及失效场合总结
史上最简单MySQL教程详解(进阶篇)之索引及其失效场合总结 什么是索引及其作用 索引的种类 各存储引擎对于索引的支持 简单介绍索引的实现 索引的设置与分析 普通索引 唯一索引(Unique Inde ...
- PHP/MySQL教程
PHP/MySQL教程(一) 本文介绍堪称Web数据库黄金组系腜HP/MySQL如何构筑一个网络数据库应用的方法,PHP是一个类似微软ASP的服务器端的嵌入式超文本处理语言,是建立动态网站的强大工具. ...
- Linux(CentOS)安装MySQL教程
1. 准备工作 1.1 安装CentOS虚拟机 教程[点击跳转] 1.2 将CentOS虚拟机设置为静态IP,否则你每次重启虚拟机后连接数据库都要重新查IP 教程[点击跳转] 1.3 如果有安装过My ...
- (B站动力节点老杜MySQL教程)MySQL课堂笔记-day03.txt
文章目录 文件来源/资料下载: MySQL课堂笔记-day03.txt 1.约束 1.1.唯一性约束(unique) 1.2.主键约束 1.3.外键约束 2.存储引擎?(整个内容属于了解内容) 2.1 ...
- MySQL 教程基础介绍
MySQL 教程基础介绍 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库. 每个数据库都有一个或多个不同的 API 用于创建,访问,管理,搜索和复制所保存的数据. ...
- MySQL 教程---菜鸟教程
文章目录 MySQL 教程 登录 MySQL 数据库操作 数据类型 创建数据表 删除数据表 插入数据 查询数据 WHERE 子句 UPDATE 更新 DELETE 子句 LIKE 子句 UNION 操 ...
- 【MySQL教程(一)】安装和初步使用
1. 数据库基本概念和分类 2. Centos安装MySQL 3. 云服务器访问 MySQL 服务器配置 4. 数据库操作语法 5. MySQL客户端安装使用 6. MySQL Workbench数据 ...
最新文章
- java解析五元组_pcap文件解析,并且按照五元组分类
- 【基础练习】【拓扑排序】codevs3294 车站分级题解
- 个人对继承理解以及虚析构函数的理解
- 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续2篇-模板导出综合示例)...
- sersync进行实时同步数据
- java字符串操作_Java的字符串操作
- python3的3D实战 -基于panda3d(4)
- python tfidf特征变换_使用sklearn提取文本的tfidf特征
- 的使用两个数据集拼接_使用Scikit Learn的分类器探索Iris数据集
- WEB标准学习路程之CSS:7.表格,滚动条,打印
- java包含某个字符串_JavaScript判断一个字符串是否包含指定子字符串的方法
- CART决策树算法的Python实现(注释详细)
- 航旅纵横被质疑泄露用户数据;杭州网警破获67万台电脑数据遭黑客偷窃案;简历倒卖黑产:低至3毛一条,700元买采集器可无限量导数据...
- 解决 java 程序中 CPU 占用率过高问题
- 【R语言】创建空的dataframe
- 中南大学计算机学院2021复试名单,2021年中南大学研究生拟录取名单整理汇总(各学院)...
- 在树莓派中Linux环境下rpm包的安装
- 每日一算法:冒泡排序
- linux脚本if eq 0,Shell常用的逻辑判断 -lt -eq 等使用及举例说明
- 网络抓包-抓包工具tcpdump的使用与数据分析
热门文章
- 美团token解决思路
- iOS11界面交互设计规范(iOS 11 Human Interface Guidelines)
- java structs,国内最早Struts专题Java - 解道Jdon
- 解构企业实名认证的几大「名场面」
- python批量处理图片属性_python PIL 批量处理处理图片
- 采集人物经历来佐证子平术
- Yuga Labs「高处不胜寒」
- c语言中数的表示 叙述正确,关于C语言中数的表示,以下叙述正确的是(
- 操作性条件作用和经典性条件作用中,刺激分化和泛化的区别是?|小白心理-312/347考研答疑
- 传感器连接mysql_获取传感器数据并传入数据库-HTTP/POST/ASP.NET