序章–MySQL介绍以及安装
JavaEE:企业级Java开发 web
- 前端(页面:展示,数据)
- 后台(连接点:连接数据库JDBC,连接前端(控制视图跳转,和前端传递数据));
- 数据库(存数据)
1、为什么学习数据库?
原因:
- 岗位需求;
- 现在的世界,大数据时代;
- 被迫需求:存数据,去IOE
- 数据库是所有软件体系中最核心的存在
2、什么是数据库
数据库(DB,DataBase)
概念:数据仓库,软件;安装在操作系统之上(window,Linux,Mac、、、、);SQL,可以存储大量数据;
作用:存储数据,管理数据
3、数据库分类
DBMS:数据库管理系统
关系型数据库(SQL):
- MySQL,Oracle,Sql Server,DB2,SQLlite。
- 通过表和表之间,行和列之间的关系进行数据的存储,
非关系型数据库(NoSQL ):
NO:not only
- Redis,MongDB;
- 非关系型数据库,对象存储,通过对象的自身的属性来决定;
DBMS(数据库管理系统)
- 数据库的管理软件,科学有效的管理我们的数据。维护和获取数据;
- MySQL本质就是一个数据库管理系统。
4、MySQL简介
- MySQL是一个关系型数据库管理系统;
- MySQL是最好的RDMBS(relational database management system,数据库管理系统)应用软件之一。
特点:体积小,速度快,总体拥有成本低;
中小型网站或者大型网站
5、安装MySQL
安装建议:
1.尽量不要使用exe安装,
2.尽可能使用压缩包安装
教程:https://www.cnblogs.com/hellokuangshen/p/1024958.html
步骤:
1、解压
2、把这个包放到自己的电脑环境目录下
3、配置环境变量
4、新建MySQL配置文件ini
[mysqld]
#目录一定要换成自己的
basedir=F:\\MySQL\\mysql-8.0.22-winx64
datadir=F:\\MySQL\\mysql-8.0.22-winx64\\Data
port=3306
skip-grant-tables
5、启动管理员模式下的CMD,运行所有的命令
6、安装MySQL服务
7、初始化数据库文件
8、启动MySQL,进去修改密码
9、进入MySQL,通过命令行,修改密码(sql语句后面一定要加上分号)
10、注释掉ini文件中的跳过密码
11、重启MySQL,连接测试,如果连接成功就Ok了
建议:
可能遇到的问题:
1、缺少dll组件
2、命令输入出错(大小写问题在MySQL8.0中比较重要)
sc delete mysql;清空服务
6、安装Navicate
https://blog.csdn.net/WeiHao0240/article/details/110950197
https://blog.csdn.net/qq_42767653/article/details/106118313
所有建立的数据库都是会在data目录下面
新建一个数据库SCHOOL
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z5segQoM-1632238468605)(C:\Users\Administrator\Desktop\QQ截图20210215180023.png)]
注意:
- 其中的字符集是(utf8)以及排序规则(utf8_general_ci);
- Navicate 的每一个执行操作,本质上都是对应一个sql语句,可以在软件的历史日志中查看。
新建一张表student(id,name)
7、连接数据库
命令行连接
mysql -uroot -p123456
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';
flush privileges;
show databases;
use database;
show tables;
describe table;
create database test;
exit;
数据库语言—本质CRUD(增删改查)
DDL 定义语言
DML 操作语言
DQL 查询语言
DCL 控制语言
注意点:
- ``,字段名使用table键进行包裹;
- 注释:“–”或者是/**/;
- sql关键字大小写不敏感,建议大家写小写;
- 所有符号全部用英文。
1、MySQL8.0的新特性
2、数据库的基本操作
操作数据库>操作数据库中表>操作数据库中表的数据
注意:MySQL不区分大小写(8.0之前版本)
2.1、操作数据库
注意:其中"[]"代表的是可写可不写
2.1.1、创建数据库
create database [if not exists] database_name;
show databases;
| Database |
+
| information_schema |
| mysql |
| performance_schema |
| school |
| sys |
+
create database if not exists `db1`;
+
| Database |
+
| db1 |
| information_schema |
| mysql |
| performance_schema |
| school |
| sys |
+
2.1.2、使用数据库
use `database_name`;
mysql> use `db1`;
Database changed
注意事项:必须使用tab键上方的反引号用来修饰数据库名、表名、列名…否则会出现语法错误
> 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''db1'' at line 1
反引号与单引号,双引号的区别
https://blog.csdn.net/CHCH998/article/details/105611745
作为表名或者是字段名,最好还是加上反引号。而作为值,加上单引号即可。(大概率上会提高效率)
2.1.3、删除数据库
drop database [if exists] test;
show databases;
| Database |
+
| db1 |
| information_schema |
| mysql |
| performance_schema |
| school |
| sys |
+
drop database if exists db1;
> OK
> 时间: 0.009s
show databases;
+
| Database |
+
| information_schema |
| mysql |
| performance_schema |
| school |
| sys |
+
注意:使用drop命令删除数据库时要谨慎,MySQL不会提示。如果删除数据库的话,数据库中所有的数据表以及数据也会一同删除,而且不能恢复。
2.1.4、查看数据库
show databases;
show create database database_name;
注意事项:只能查看创建的语句,暂时无法查看删除的语句,会出现语法错误。
eg:show delete database database_name;
mysql> show create database db1;
+
| Database | Create Database |
+
| db1 | CREATE DATABASE `db1` |
+
1 row in set (0.00 sec)
学习思路:
- 对照可视化工具历史记录查看;
- 固定的语法或者关键字必须要记住。
学习案例:
C:\Users\Administrator>mysql -u root -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.0.22 MySQL Community Server - GPL
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
具体语句:
mysql> show databases;
+
| Database |
+
| information_schema |
| mysql |
| performance_schema |
| school |
| sys |
+
5 rows in set (0.00 sec)
mysql> create database if not exists db_demo;
Query OK, 1 row affected (0.05 sec)
mysql> show databases;
+
| Database |
+
| db_demo |
| information_schema |
| mysql |
| performance_schema |
| school |
| sys |
+
6 rows in set (0.00 sec)
mysql> use `db_demo`;
Database changed
mysql> show create database db_demo\G
*************************** 1. row ***************************
Database: db_demo
Create Database: CREATE DATABASE `db_demo`
1 row in set (0.00 sec)
mysql> drop database if exists db_demo;
Query OK, 0 rows affected (0.01 sec)
mysql> show databases;
+
| Database |
+
| information_schema |
| mysql |
| performance_schema |
| school |
| sys |
+
2.2、数据库的列类型
数值
tinyint
smallint
mediumint
int
bigint
float
double
decimal
注意:int以及decimal
字符串
char
varchar
tinytext
text
时间日期
data
time
datatime
timestamp
year
null
- 没有值,未知
- >注意,不要使用null进行运算,结果为null
2.3、数据库的字段属性(重点)
Unsigned:
zerofill:
自增:
- 通常理解为自增,自动在上一条记录的基础上+1(默认);
- 通常用来设计唯一的主键,必须是整数类型;
- 可以自定义设计主键自增的起始值和步长;
非空 not null
- 假设设置为not null,如果不给他赋值,就会报错!(相当于添加一个限制);
- Null,如果不填写值,默认就是null.
默认:
- 设置默认的值;
- sex,如果默认的值为“男”,那么即使不赋值。初始值还是“男”;
3、数据表的基本操作
3.1、创建数据表
3.1.1、语法格式
CREATE TABLE [IF NOT EXISTS] `表名`(
`字段名` 数据类型 [属性] [注释],
`字段名` 数据类型 [属性] [注释],
......
`字段名` 数据类型 [属性] [注释]
)[表类型][字符集设置][注释];
注意事项:
- 表名不区分大小写,但是不能使用SQL语言中的关键字,如drop,alert等
- 数据表中的每一列(字段)的名称和数据类型,如果创建多列,需要使用逗号隔开。
案例
员工表tb_emp1结构
字段名称 | 数据类型 | 备注 |
---|
id | int(11) | 员工编号 | name | varchar(25) | 员工名称 | deptId | int(11) | 所在部门编号 | salary | float | 工资 |
create database if not exists test_db;
use test_db;
create table if not exists tb_emp1(
`id` int(11) comment '员工编号',
`name` varchar(25) comment '员工名称',
`deptId` int(11) comment '所在部门编号',
`salary` float comment '工资'
);
> OK
> 时间: 0.462s
show tables;
+
| Tables_in_test_db |
+
| tb_emp1 |
+
注意:使用英文模式下面的“()”。而且表名和字段名尽量使用==(反引号``)==来括起来。
3.1.2、使用主键约束
- 主键:又称主码,是表中一列或多列的组合,即主键可以是单一的一列也可以是多列,但是常用的还是单列作为主键约束,主键类型分为单字段主键以及多字段联合主键。
- 而主键约束,要求主键列的数据唯一,并且不为空。
- 主键可以结合外键来定义不同的数据表之间的关系,以此来加快数据库查询的速度。但是现在不推荐使用外键查询,推荐使用联表查询。
单字段主键
注意:单字段主键分为两种:
1.定义列的同时指定主键
2.定义列之后再指定主键
字段名 数据类型 primary key [默认值]
create table if not exists `tb_emp2`(
`id` int(11) primary key comment '学生id',
`name` varchar(25) comment '学生姓名',
`deptId` int(11) comment '部门编号',
`salary` float comment '工资'
);
[constraint <约束名>] primary key(字段名)
create table if not exists `tb_emp3`(
`id` int(11) comment '学生id',
`name` varchar(25) comment '学生姓名',
`deptId` int(11) comment '部门编号',
`salary` float comment '工资',
primary key(id)
);
多字段主键
多字段主键由多个字段联合组成。
primary key(字段1,字段2....字段n)
create table if not exists `tb_emp4`(
`name` varchar(25) comment '员工姓名',
`deptId` int(11) comment '部门编号',
`salary` float comment '工资',
primary key(`name`,`deptId`)
);
+
| Tables_in_db_demo |
+
| tb_emp2 |
| tb_emp3 |
| tb_emp4 |
+
结果
3.1.3、使用外键约束(建议不使用)
- 外键是用来在两个表的数据之间建立连接,可以是单列,也可以是多列。
- 一个表可以有一个或者多个外键。
- 外键对应的参照完整性,一个表的外键可以是空值
- 若外键不为空值,则每一个外键必须等于另一个表中主键的某个值。
- 外键可以不是本表的主键,但是要对应另外一个表的主键。(同4相同概念)
空值和null的区别
https://blog.csdn.net/Crystalqy/article/details/114088403
语法格式
[constraint <外建名>] foreign key 字段名1.... references <主表名>(主键列1...)
- 主表(父表):对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表;
- 从表(子表):对于两个具有关联关系的表而言,相关联字段中外键所在的表就是从表。
子表的外键必须关联父表的主键,且数据类型必须相同。
注意:
- 外键的主要作用就是保证数据引用的完整性,定义外键后,不允许删除在另一个表中具有关联关系的字段。
- 如果要删除主表,要事先断开与从表之间的关联—删除外键。
eg:部门表td_dept的主键是id,而员工表tb_emp4中有一个字段(deptId)与这个id关联。
字段名称 | 数据类型 | 备注 |
---|
id | int(10) | 部门编号 | name | varchar(25) | 部门名称 | location | varchar(50) | 部门位置 |
? sql语句
create table if not exists `tb_dept`(
`id` int(10) comment '部门编号',
`name` varchar(20) comment '部门姓名',
`location` varchar(50) comment '部门地址',
primary key(`id`)
);
create table if not exists `tb_emp`(
`id` int(10) comment '员工编号',
`name` varchar(25) comment '员工姓名',
`deptId` int(10) comment '部门编号',
`salary` float comment '工资',
constraint fk_emp_dept foreign key(`deptId`) references `tb_dept`(`id`)
);
alter table `tb_emp` add foreign key(`deptId`) references `tb_dept`(`id`);
3.1.4、使用非空约束
非空约束(not null constraint)指的是字段的值不能为空。
对于使用了非空约束的字段,如果用户在添加数据时没有指定值,数据库系统就会报错。
字段名 数据类型 not null
create table if not exists `tb_emp5`(
`id` int(10) comment '员工编号',
`name` varchar(25) not null comment '员工姓名',
`deptId` int(10) comment '部门编号',
`salary` float comment '工资',
primary key(`id`)
);
使用非空约束,用户在添加数据时没有指定值
3.1.5、使用唯一约束
唯一性约束(unique constraint)要求该列唯一,允许为空,但只能出现一个空值。
作用:可以确保一列或者多列不会出现重复值。
1、定义完列之后,直接指定唯一约束。
create table if not exists `tb_dept2`(
`id` int(10) unique not null comment '部门编号',
`name` varchar(25) unique comment '部门名称',
`location` varchar(50) comment '部门地址',
primary key(`id`)
)
> OK
> 时间: 0.037s
2、定义完所有列之后,指定唯一约束。
create table if not exists `tb_dept2`(
`id` int(10) comment '部门编号',
`name` varchar(25) comment '部门名称',
`location` varchar(50) comment '部门地址',
constraint sth unique(`name`)
)
> OK
> 时间: 0.036s
- 如果重复就会出现1062错误,重复使用。
- 观察图片2和图片3可得,如果出现约束名,直接是以约束名替代字段名。
3、unique和primary key的区别
- 一个表中可以有多个字段声明为unique,但只能有一个primary声明。
- 声明为primary key 的字段不允许有空值,但是声明unique的字段可以有空值
4、与hashSet()一样,如果是在JDBC中设置如何,是否会繁琐
3.1.6、使用默认约束
默认约束(default constraint)就是指定某列的默认值。
eg:age 的默认值都设置为22,则新增一个,年龄还是22
字段名 数据类型 default 默认值
create table if not exists `tb_emp6`(
`id` int(10) comment '员工编号',
`name` varchar(25) not null comment '员工姓名',
`deptId` int(10) default 1111 comment '部门编号',
`salary` float comment '员工工资',
primary key(`id`)
)
> OK
> 时间: 0.038s
3.1.7、设置表的属性值自动增加
- 在MySQL中,auto_increment的初始值为1,每次新增一条记录,字段值自动加一;
- 一个表中,只能有一个字段使用auto_incement,且该字段必须为主键或者是主键的一部分;
- auto_increment约束的字段可以是任何整数类型(tinyint,smallint,int,bigint)
字段名 数据类型 auto_increment
create table if not exists `tb_emp7`(
`id` int(10) auto_increment comment '员工编号',
`name` varchar(25) not null comment '员工姓名',
`deptId` int(10) comment '部门编号',
`salary` float comment '工资',
PRIMARY KEY(`id`)
)
> OK
> 时间: 0.031s
insert into `tb_emp7` (`name`,`salary`) values('zhangsan',1000),('lisi',1500),('zhaowu',2000);
select * from tb_emp7;
+
| id | name | deptId | salary |
+
| 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 |
| 3 | 3 | 3 | 3 |
| 4 | zhangsan | NULL | 1000 |
| 5 | lisi | NULL | 1500 |
| 6 | zhaowu | NULL | 2000 |
+
6 rows in set (0.00 sec)
id是自增,即使是设置为0,也会在初始数据为1的情况下,自增1后再自增1,回归设定好的数值。
3.2、查看数据表结构
在MySQL中,查看表结构,可以使用describe和show create table语句
3.2.1、查看表基本结构 语句–describe
describe/desc语句可以查看表的字段信息,其中包括字段名、字段数据类型、是否为主键、是否有默认值等。
describe 表名;/ desc 表名;
mysql> describe `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| location | varchar(50) | YES | | NULL | |
+
3 rows in set (0.00 sec)
mysql> desc `tb_emp`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | YES | | NULL | |
| name | varchar(25) | YES | | NULL | |
| deptId | int | YES | MUL | NULL | |
| salary | float | YES | | NULL | |
+
4 rows in set (0.00 sec)
各个字段的含义: NULL:表示该列是否可以储存null值
Key:表示该列是否已经编制索引。
- 其中,PRI代表的该列是主键或者是主键的一部分;
- UNI表示该列是unique索引的一部分;
- MUL表示在列中某个给定值允许出现多次。
Default:表示该列是否有默认值,有的话则指定默认值是多少
Extra:表示可以获取的与给定列有关的附加信息,例如:auto_increment
3.2.2、查看表详细结构语句show create table
show create table语句可以用来显示创建表时的语句----create table 语句
show create table table_name\G
注意:
- 使用show create table table_name 语句,可以查看表创建时候的详细语句,还可以查看存储引擎和字符编码。
- 如果不加“\G”参数,显示结果可能会非常杂乱,加上“\G”之后,可以使显示结果整洁。
- 注意,\G或者是\g本身原理相当于结束命令(send commander to server)。所以\G和\g之后就不需要加上分号了
- \G只能在命令行界面使用,在navicate中暂时无法使用
对比\g,\G的区别以及作用
https://blog.csdn.net/daofengsuoxiang/article/details/103067025
mysql> show create table `tb_emp7`;
+
| Table | Create Table
+
| tb_emp7 | CREATE TABLE `tb_emp7` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '员工编号',
`name` varchar(25) NOT NULL COMMENT '员工姓名',
`deptId` int DEFAULT NULL COMMENT '部门编号',
`salary` float DEFAULT NULL COMMENT '工资',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
+
1 row in set (0.00 sec)
mysql> show create table `tb_emp7`\G
*************************** 1. row ***************************
Table: tb_emp7
Create Table: CREATE TABLE `tb_emp7` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '员工编号',
`name` varchar(25) NOT NULL COMMENT '员工姓名',
`deptId` int DEFAULT NULL COMMENT '部门编号',
`salary` float DEFAULT NULL COMMENT '工资',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
3.3、修改数据表
MySQL使用alter table语句修改表。
常用的修改表操作包括:
-
修改表名; -
修改字段数据类型或字段名; -
增加和删除字段; -
修改字段的排列位置; -
更改表的存储引擎; -
删除表的外键约束等等
3.3.1、修改表名
alter TABLE 旧表名 rename as/to 新表名
mysql> show tables;
+
| Tables_in_db_demo |
+
| tb_dept |
| tb_dept2 |
| tb_dept3 |
+
10 rows in set (0.05 sec)
mysql> alter table `tb_dept2` rename `tb_deptment2`;
Query OK, 0 rows affected (0.48 sec)
mysql> alter table `tb_deptment2` rename to `tb_dept2`;
Query OK, 0 rows affected (0.03 sec)
mysql> alter table `tb_dept2` rename as `tb_deptment2`;
Query OK, 0 rows affected (0.03 sec)
mysql> desc `tb_dept2`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | YES | | NULL | |
| name | varchar(25) | YES | UNI | NULL | |
| location | varchar(50) | YES | | NULL | |
+
3 rows in set (0.00 sec)
mysql> desc `tb_deptment2`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | YES | | NULL | |
| name | varchar(25) | YES | UNI | NULL | |
| location | varchar(50) | YES | | NULL | |
+
3 rows in set (0.00 sec)
注意:
- 其中修改表名,既可以加上to/as,也是可以直接省略掉;
- 修改表名是alter,而不是alert;
- 修改表名但是不会修改表的基本结构(修改前和修改后的表结构都是相同的)。
3.3.2、修改字段的数据类型
修改数据类型就是将字段的数据类型转换成另外的数据类型。
alter table table_name modify 字段名 数据类型
其中table_name,指的是要修改字段数据类型的所属的表 字段名 :指的是要修改的字段 数据类型:指的是要修改后的数据类型
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| location | varchar(50) | YES | | NULL | |
+
3 rows in set (0.00 sec)
mysql> alter table `tb_dept` modify `name` varchar(30);
Query OK, 0 rows affected (0.44 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(30) | YES | | NULL | |
| location | varchar(50) | YES | | NULL | |
+
3 rows in set (0.00 sec)
3.3.3、修改字段名
alter table table_name change 旧字段名 新字段名 新数据类型;
- 其中,“旧字段名”指的是修改前的字段名;
- “新字段名”指的是修改后的字段名;
- “新数据类型”指修改后的数据类型,如果不需要修改数据类型,那么就将新数据类型设置成与原来的一样,但是数据类型不能为空。
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(30) | YES | | NULL | |
| location | varchar(50) | YES | | NULL | |
+
3 rows in set (0.00 sec)
mysql> alter table `tb_dept` change `location` `loc` varchar(50);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(30) | YES | | NULL | |
| loc | varchar(50) | YES | | NULL | |
+
3 rows in set (0.00 sec)
1、change 和modify修改数据类型对比
change 也是可以修改数据类型(保证两个字段名相同即可)
mysql> desc tb_dept;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| location | varchar(30) | YES | | NULL | |
+
3 rows in set (0.00 sec)
mysql> alter table `tb_dept` modify `location` varchar(50);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| location | varchar(50) | YES | | NULL | |
+
3 rows in set (0.00 sec)
mysql> alter table `tb_dept` change `location` `location` varchar(30);
Query OK, 0 rows affected (0.13 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| location | varchar(30) | YES | | NULL | |
+
3 rows in set (0.00 sec)
2、注意:change 和modify的区别
https://blog.csdn.net/qq_37618361/article/details/104778615
相同点:都可以改变表中字段的数据类型;
不同点:
- change既可以修改字段的数据类型,同样也是可以修改字段名。而且change要修改数据类型(保证字段名不变)的情况下,需要写两次字段名;
- 而modify修改字段的数据类型,只需要写出一次字段名。
注意事项:由于不同类型的数据在机器中的存储的方式以及长度并不相同。所以,修改数据类型可能会影响到数据表中已有的数据记录。因此,当数据库表中已经有数据的时候,不要轻易的修改数据类型。
3.3.4、添加字段
alter table <表名> add <新字段名> <数据类型> [约束条件] [first | after 已经存在的字段名];
- 其中,<>代表的必选项,而[]是可选项。
- “first”为可选参数,其作用是将新添加到的字段设置为表的第一个字段;
- “after”也是可选参数,其作用是将新添加的字段放置到指定的 “已存在的字段名” 后面;
- 如果没有 “first” 和 “after 已经存在的字段名" ,则新添加的字段设置为数据表的最后列。
1、添加无完整性约束条件的字段
mysql> alter table `tb_dept` add `managerId` int(10);
Query OK, 0 rows affected, 1 warning (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| location | varchar(30) | YES | | NULL | |
| managerId | int | YES | | NULL | |
+
4 rows in set (0.00 sec)
2、添加有完整性约束条件的字段
mysql> alter table `tb_dept` add `column1` varchar(12) not null;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| location | varchar(30) | YES | | NULL | |
| managerId | int | YES | | NULL | |
| column1 | varchar(12) | NO | | NULL | |
+
5 rows in set (0.00 sec)
3、在表的第一列添加一个字段
mysql> alter table `tb_dept` add `column2` int(11) first;
Query OK, 0 rows affected, 1 warning (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| column2 | int | YES | | NULL | |
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| location | varchar(30) | YES | | NULL | |
| managerId | int | YES | | NULL | |
| column1 | varchar(12) | NO | | NULL | |
+
6 rows in set (0.00 sec)
4、在表的指定列之后添加一个字段
mysql> alter table `tb_dept` add `column3` int(11) after `name`;
Query OK, 0 rows affected, 1 warning (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| column2 | int | YES | | NULL | |
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| column3 | int | YES | | NULL | |
| location | varchar(30) | YES | | NULL | |
| managerId | int | YES | | NULL | |
| column1 | varchar(12) | NO | | NULL | |
+
7 rows in set (0.00 sec)
3.3.5、删除字段
删除字段是将字段从数据表中移除。(不知道备份是否有用,)
alter table 表名 drop 字段名;
mysql> alter table `tb_dept` drop `column2`;
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| column3 | int | YES | | NULL | |
| location | varchar(30) | YES | | NULL | |
| managerId | int | YES | | NULL | |
| column1 | varchar(12) | NO | | NULL | |
+
6 rows in set (0.00 sec)
3.3.6、修改字段的排列位置
数据表的结构在创建的时候就以及确定(字段在表中的排列顺序以及确定),但是表的结构 不是不可以改变的。
alter table 表名 modify 字段1 数据类型 first |after 字段2;
其中,“字段1”指的是要修改位置的字段;
“first” 为可选参数,指将 “字段1”修改为表的第一个字段;
“after 字段2”指的是将 “字段1” 插入到 ”字段2“ 后面。
1、修改字段为表的第一个字段
mysql> alter table `tb_dept` modify `column1` varchar(12) first;
Query OK, 0 rows affected (0.49 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| column1 | varchar(12) | YES | | NULL | |
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| column3 | int | YES | | NULL | |
| location | varchar(30) | YES | | NULL | |
| managerId | int | YES | | NULL | |
+
6 rows in set (0.01 sec)
2、修改字段到表的指定列之后
mysql> alter table `tb_dept` modify `column1` varchar(12) after `location`;
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `tb_dept`;
+
| Field | Type | Null | Key | Default | Extra |
+
| id | int | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| column3 | int | YES | | NULL | |
| location | varchar(30) | YES | | NULL | |
| column1 | varchar(12) | YES | | NULL | |
| managerId | int | YES | | NULL | |
+
6 rows in set (0.00 sec)
3.3.7、更改表的存储引擎
MySQL中主要的存储引擎有MyISAM、InnoDB、MEMORY(HEAP)、BDB、FEDERATED等。
可以使用show engines;语句查询系统支持的存储引擎。
MySQL支持的存储引擎
引擎名 | 是否支持 |
---|
FEDERATED | 否 | MRG_MYISAM | 是 | MyISAM | 是 | BLACKHOLE | 是 | CSV | 是 | MEMORY | 是 | ARCHIVE | 是 | InnoDB | 是,默认的存储引擎 | PERFORMANCE_SCHEMA | 是 |
alter table 表名 engine =更改后的存储引擎名;
mysql> show create table `tb_dept`\G
*************************** 1. row ***************************
Table: tb_dept
Create Table: CREATE TABLE `tb_dept` (
`id` int NOT NULL COMMENT '部门编号',
`name` varchar(20) DEFAULT NULL,
`column3` int DEFAULT NULL,
`location` varchar(30) DEFAULT NULL,
`column1` varchar(12) DEFAULT NULL,
`managerId` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> alter table `tb_dept` engine=MyISAM;
ERROR 3776 (HY000): Cannot change table's storage engine because the table participates in a foreign key constraint.
mysql> show create table `tb_emp3`\G
*************************** 1. row ***************************
Table: tb_emp3
Create Table: CREATE TABLE `tb_emp3` (
`id` int NOT NULL COMMENT '学生id',
`name` varchar(25) DEFAULT NULL COMMENT '学生姓名',
`deptId` int DEFAULT NULL COMMENT '部门编号',
`salary` float DEFAULT NULL COMMENT '工资',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> alter table `tb_emp3` engine=MyISAM;
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table `tb_emp3`\G
*************************** 1. row ***************************
Table: tb_emp3
Create Table: CREATE TABLE `tb_emp3` (
`id` int NOT NULL COMMENT '学生id',
`name` varchar(25) DEFAULT NULL COMMENT '学生姓名',
`deptId` int DEFAULT NULL COMMENT '部门编号',
`salary` float DEFAULT NULL COMMENT '工资',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
3.3.8、删除表的外键约束
对于数据库中定义的外键,如果不需要可以直接删除。删除之后,就会解除主表和从表间的关联关系。
alter table 表名 drop foreign key 外键约束名;
create table if not exists `tb_emp8`(
`id` int(11) not null auto_increment comment '员工编号',
`name` varchar(20) not null comment '员工姓名',
`deptId` int(11) not null comment '部门编号',
`salary` float not null comment '工资',
primary key(`id`)
);
alter table `tb_emp8` add constraint fk_emp_dept2 foreign key(`deptId`) references `tb_dept`(`id`);
mysql> show create table `tb_emp8`\G
*************************** 1. row ***************************
Table: tb_emp8
Create Table: CREATE TABLE `tb_emp8` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '员工编号',
`name` varchar(20) NOT NULL COMMENT '员工姓名',
`deptId` int NOT NULL COMMENT '部门编号',
`salary` float NOT NULL COMMENT '工资',
PRIMARY KEY (`id`),
KEY `fk_emp_dept2` (`deptId`),
CONSTRAINT `fk_emp_dept2` FOREIGN KEY (`deptId`) REFERENCES `tb_dept` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
alter table `tb_emp8` drop foreign key `fk_emp_dept2`;
mysql> show create table `tb_emp8`\G
*************************** 1. row ***************************
Table: tb_emp8
Create Table: CREATE TABLE `tb_emp8` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '员工编号',
`name` varchar(20) NOT NULL COMMENT '员工姓名',
`deptId` int NOT NULL COMMENT '部门编号',
`salary` float NOT NULL COMMENT '工资',
PRIMARY KEY (`id`),
KEY `fk_emp_dept2` (`deptId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
3.4、删除数据表
在删除表的同时,表的定义和表中所有的数据都会被删除。因此,在删除操作前,最好对表中的数据做一个备份。
3.4.1、删除没有被关联的表
drop table [if exists] 表1,表2,表3......;
mysql> drop table if exists `tb_dept2`;
Query OK, 0 rows affected (0.06 sec)
mysql> show tables;
+
| Tables_in_db_demo |
+
| tb_dept |
| tb_dept3 |
......省略部分内容.....
+
11 rows in set (0.00 sec)
注意:
- 所有的创建和删除操作尽量加上判断 [if (not) exists],以免报错。
- if exists 用于判断表是否存在。加上该参数,即使表不存在,SQL也是会继续执行,但是会发出warning
- 可以同时删除多个表,只需要将表的名字依次写在后面即可,相互之间用逗号隔开。
3.4.2、删除被其他表关联的表
在数据表之间存在外键关联的情况下,如果直接删除父表,结果会显示错误;
原因是直接删除将破坏表的参照完整性。
mysql> drop table if exists `tb_dept`;
ERROR 3730 (HY000): Cannot drop table 'tb_dept' referenced by a foreign key constraint 'fk_emp_dept' on table 'tb_emp'.
解决办法:
1、如果必须要删除主表,则直接删除子表(与主表关联),再删除主表。—结果:同时删除主表和从表数据
2、保留子表,单独删除主表。将从表的外键约束条件删除,即可删除主表。
create table if not exists `tb_dept2`(
`id` int(10) auto_increment not null comment '部门编号',
`name` varchar(20) not null comment '部门姓名',
`location` varchar(50) not null comment '部门地址',
primary key(`id`)
)
> OK
> 时间: 0.03s
create table if not exists `tb_emp10`(
`id` int(10) auto_increment not null comment '员工编号',
`name` varchar(20) not null comment '员工姓名',
`deptId` int(10) not null comment '部门编号',
`salary` float not null comment '员工工资',
primary key(`id`),
constraint `fk_emp_dept2` foreign key(`deptId`) references `tb_dept2`(`id`)
)
> OK
> 时间: 0.426s
mysql> show create table `tb_emp10`\G
*************************** 1. row ***************************
Table: tb_emp10
Create Table: CREATE TABLE `tb_emp10` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '员工编号',
`name` varchar(20) NOT NULL COMMENT '员工姓名',
`deptId` int NOT NULL COMMENT '部门编号',
`salary` float NOT NULL COMMENT '员工工资',
PRIMARY KEY (`id`),
KEY `fk_emp_dept2` (`deptId`),
CONSTRAINT `fk_emp_dept2` FOREIGN KEY (`deptId`) REFERENCES `tb_dept2` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> drop table if exists `tb_dept2`;
ERROR 3730 (HY000): Cannot drop table 'tb_dept2' referenced by a foreign key constraint 'fk_emp_dept2' on table 'tb_emp10'.
mysql> alter table `tb_emp10` drop foreign key `fk_emp_dept2`;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> drop table if exists `tb_dept2`;
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
+
| Tables_in_db_demo |
+
| tb_dept |
| tb_dept3 |
| tb_emp |
| tb_emp10 |
.....省略其他内容......
| tb_emp8 |
| tb_emp9 |
+
12 rows in set (0.00 sec)
3.5、综合案例----数据表的基本操作
案例目的:创建、修改和删除数据表,掌握表的基本操作。
创建数据库company,创建表offices以及employees,完成基本操作
offices表结构
字段名 | 数据类型 | 主键 | 外键 | 非空 | 唯一 | 自增 |
---|
officeCode | int(10) | 是 | 否 | 是 | 是 | 否 | city | varchar(50) | 否 | 否 | 是 | 否 | 否 | address | varchar(50) | 否 | 否 | 否 | 否 | 否 | country | varchar(50) | 否 | 否 | 是 | 否 | 否 | postalCode | varchar(5) | 否 | 否 | 否 | 是 | 否 |
employees表结构
字段名 | 数据类型 | 主键 | 外键 | 非空 | 唯一 | 自增 |
---|
employeeNumber | int(11) | 是 | 否 | 是 | 是 | 是 | lastName | varchar(50) | 否 | 否 | 是 | 否 | 否 | firstName | varchar(50) | 否 | 否 | 是 | 否 | 否 | mobile | varchar(25) | 否 | 否 | 否 | 是 | 否 | officeCode | int(10) | 否 | 是 | 是 | 否 | 否 | jobTitle | varchar(50) | 否 | 否 | 是 | 否 | 否 | birth | datetime | 否 | 否 | 是 | 否 | 否 | note | varchar(255) | 否 | 否 | 否 | 否 | 否 | sex | varchar(5) | 否 | 否 | 否 | 否 | 否 |
3.5.1、连接MySQL
C:\Users\Administrator>net start mysql
请求的服务已经启动。
C:\Users\Administrator>mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.22 MySQL Community Server - GPL
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
3.5.2、创建数据库
mysql> create database if not exists `company`;
Query OK, 1 row affected (0.01 sec)
mysql> use `company`;
Database changed
3.5.3、创建表offices
create table if not exists `offices`(
`officeCode` int(10) not null unique comment '办公代码',
`city` varchar(50) not null comment '公司所在城市',
`address` varchar(50) comment '公司详细地址',
`country` varchar(50) not null comment '公司所在国家',
`postalCode` varchar(15) unique comment '邮政编码',
primary key(`officeCode`)
)
> OK
> 时间: 0.466s
show tables;
+
| Tables_in_company |
+
| offices |
+
1 row in set (0.00 sec)
3.5.4、创建表employees
create table if not exists `employees`(
`employeeNumber` int(11) not null unique auto_increment comment '员工编号',
`lastName` varchar(50) not null comment '员工姓氏',
`firstName` varchar(50) not null comment '员工第一个名字',
`mobile` varchar(25) unique comment '员工电话',
`officeCode` int(10) not null comment '办公代码',
`jobTitle` varchar(50) not null comment '职称',
`birth` datetime not null comment '出生日期',
`note` varchar(255) ,
`sex` varchar(5) comment '性别',
primary key(`employeeNumber`),
constraint fk_offices_employees foreign key(`officeCode`) references `offices`(`officeCode`)
)
> OK
> 时间: 0.081s
mysql> show tables;
+
| Tables_in_company |
+
| employees |
| offices |
+
2 rows in set (0.00 sec)
mysql> desc `offices`;
+
| Field | Type | Null | Key | Default | Extra |
+
| officeCode | int | NO | PRI | NULL | |
| city | varchar(50) | NO | | NULL | |
| address | varchar(50) | YES | | NULL | |
| country | varchar(50) | NO | | NULL | |
| postalCode | varchar(15) | YES | UNI | NULL | |
+
5 rows in set (0.01 sec)
mysql> desc `employees`;
+
| Field | Type | Null | Key | Default | Extra |
+
| employeeNumber | int | NO | PRI | NULL | auto_increment |
| lastName | varchar(50) | NO | | NULL | |
| firstName | varchar(50) | NO | | NULL | |
| mobile | varchar(25) | YES | UNI | NULL | |
| officeCode | int | NO | MUL | NULL | |
| jobTitle | varchar(50) | NO | | NULL | |
| birth | datetime | NO | | NULL | |
| note | varchar(255) | YES | | NULL | |
| sex | varchar(5) | YES | | NULL | |
+
9 rows in set (0.00 sec)
3.5.5、修改mobile字段的排列位置
mysql> alter table `employees` modify `mobile` varchar(25) after `officeCode`;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `employees`;
+
| Field | Type | Null | Key | Default | Extra |
+
| employeeNumber | int | NO | PRI | NULL | auto_increment |
| lastName | varchar(50) | NO | | NULL | |
| firstName | varchar(50) | NO | | NULL | |
| officeCode | int | NO | MUL | NULL | |
| mobile | varchar(25) | YES | UNI | NULL | |
| jobTitle | varchar(50) | NO | | NULL | |
| birth | datetime | NO | | NULL | |
| note | varchar(255) | YES | | NULL | |
| sex | varchar(5) | YES | | NULL | |
+
9 rows in set (0.00 sec)
3.5.6、修改birth字段的字段名
mysql> alter table `employees` change `birth` `employee_birth` datetime;
Query OK, 0 rows affected (0.54 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `employees`;
+
| Field | Type | Null | Key | Default | Extra |
+
| employeeNumber | int | NO | PRI | NULL | auto_increment |
| lastName | varchar(50) | NO | | NULL | |
| firstName | varchar(50) | NO | | NULL | |
| officeCode | int | NO | MUL | NULL | |
| mobile | varchar(25) | YES | UNI | NULL | |
| jobTitle | varchar(50) | NO | | NULL | |
| employee_birth | datetime | YES | | NULL | |
| note | varchar(255) | YES | | NULL | |
| sex | varchar(5) | YES | | NULL | |
+
9 rows in set (0.00 sec)
3.5.7、修改sex字段的数据类型
mysql> alter table `employees` modify `sex` varchar(1);
Query OK, 0 rows affected (0.51 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> alter table `employees` modify `sex` varchar(1) not null;
Query OK, 0 rows affected (0.54 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `employees`;
+
| Field | Type | Null | Key | Default | Extra |
+
| employeeNumber | int | NO | PRI | NULL | auto_increment |
| lastName | varchar(50) | NO | | NULL | |
| firstName | varchar(50) | NO | | NULL | |
| officeCode | int | NO | MUL | NULL | |
| mobile | varchar(25) | YES | UNI | NULL | |
| jobTitle | varchar(50) | NO | | NULL | |
| employee_birth | datetime | YES | | NULL | |
| note | varchar(255) | YES | | NULL | |
| sex | varchar(1) | NO | | NULL | |
+
9 rows in set (0.00 sec)
3.5.8、删除字段note
mysql> alter table `employees` drop note;
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `employees`;
+
| Field | Type | Null | Key | Default | Extra |
+
| employeeNumber | int | NO | PRI | NULL | auto_increment |
| lastName | varchar(50) | NO | | NULL | |
| firstName | varchar(50) | NO | | NULL | |
| officeCode | int | NO | MUL | NULL | |
| mobile | varchar(25) | YES | UNI | NULL | |
| jobTitle | varchar(50) | NO | | NULL | |
| employee_birth | datetime | YES | | NULL | |
| sex | varchar(1) | NO | | NULL | |
+
8 rows in set (0.00 sec)
3.5.9、添加字段favoriate_activity
mysql> alter table `employees` add `favoriate_activity` varchar(100);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc `employees`;
+
| Field | Type | Null | Key | Default | Extra |
+
| employeeNumber | int | NO | PRI | NULL | auto_increment |
| lastName | varchar(50) | NO | | NULL | |
| firstName | varchar(50) | NO | | NULL | |
| officeCode | int | NO | MUL | NULL | |
| mobile | varchar(25) | YES | UNI | NULL | |
| jobTitle | varchar(50) | NO | | NULL | |
| employee_birth | datetime | YES | | NULL | |
| sex | varchar(1) | NO | | NULL | |
| favoriate_activity | varchar(100) | YES | | NULL | |
+
9 rows in set (0.00 sec)
3.5.10、删除表offices
因为表employees设置了外键,关联了主表offices的officeCode字段(主键)。
如果想要删除offices表,就必须要删除从表employees或者是删除外键约束
mysql> show create table `employees`\G
*************************** 1. row ***************************
Table: employees
Create Table: CREATE TABLE `employees` (
`employeeNumber` int NOT NULL AUTO_INCREMENT COMMENT '员工编号',
`lastName` varchar(50) NOT NULL COMMENT '员工姓氏',
`firstName` varchar(50) NOT NULL COMMENT '员工第一个名字',
`officeCode` int NOT NULL COMMENT '办公代码',
`mobile` varchar(25) DEFAULT NULL,
`jobTitle` varchar(50) NOT NULL COMMENT '职称',
`employee_birth` datetime DEFAULT NULL,
`sex` varchar(1) NOT NULL,
`favoriate_activity` varchar(100) DEFAULT NULL,
PRIMARY KEY (`employeeNumber`),
UNIQUE KEY `employeeNumber` (`employeeNumber`),
UNIQUE KEY `mobile` (`mobile`),
KEY `fk_offices_employees` (`officeCode`),
CONSTRAINT `fk_offices_employees` FOREIGN KEY (`officeCode`) REFERENCES `offices` (`officeCode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> alter table `employees` drop foreign key `fk_offices_employees`;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> drop table if exists `offices`;
Query OK, 0 rows affected (0.02 sec)
mysql> show tables;
+
| Tables_in_company |
+
| employees |
+
1 row in set (0.00 sec)
3.5.11、修改表employees存储引擎为MyISAM
mysql> alter table `employees` engine=MyISAM;
Query OK, 0 rows affected (0.48 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table `employees`\G
*************************** 1. row ***************************
Table: employees
Create Table: CREATE TABLE `employees` (
`employeeNumber` int NOT NULL AUTO_INCREMENT COMMENT '员工编号',
`lastName` varchar(50) NOT NULL COMMENT '员工姓氏',
`firstName` varchar(50) NOT NULL COMMENT '员工第一个名字',
`officeCode` int NOT NULL COMMENT '办公代码',
`mobile` varchar(25) DEFAULT NULL,
`jobTitle` varchar(50) NOT NULL COMMENT '职称',
`employee_birth` datetime DEFAULT NULL,
`sex` varchar(1) NOT NULL,
`favoriate_activity` varchar(100) DEFAULT NULL,
PRIMARY KEY (`employeeNumber`),
UNIQUE KEY `employeeNumber` (`employeeNumber`),
UNIQUE KEY `mobile` (`mobile`),
KEY `fk_offices_employees` (`officeCode`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
3.5.12、修改表employees的表名
mysql> alter table `employees` rename to `employees_info`;
Query OK, 0 rows affected (0.02 sec)
mysql> show tables;
+
| Tables_in_company |
+
| employees_info |
+
1 row in set (0.00 sec)
3.6、注意事项
3.6.1、表删除操作需谨慎
- 表删除操作将表的定义和表中数据一起从数据库中删除,而且,MySQL中删除操作之前没有任何的提示。
- ==删除操作前,最好还是对表中的数据进行备份,==这样当操作失误时,可以对数据进行恢复。
- 同理,alter table在进行基本修改操作时,也应该备份(数据库的操作是无法撤销的)。
3.6.2、每一个表中是否都需要主键?
不是每一个表都是需要主键的,一般多个表之间进行连续操作时需要用到主键。因此,不用为每个表设置主键,有些情况最好不用主键。
3.6.3、并不是每个表都可以任意选择存储引擎
MySQL可以支持多种存储引擎,每一个表都可以任意指定不同的存储引擎。
外键约束,不能跨引擎使用。
需要注意:外键约束是保证数据的参照完整性。如果表之间需要关联外键,但是表选择使用不同的存储引擎的话,那么这些表是不能创建外键约束的。因此,表的存储引擎的选择也不是随意的。
mysql> show create table customers_info\G
*************************** 1. row ***************************
Table: customers_info
Create Table: CREATE TABLE `customers_info` (
`c_num` int NOT NULL AUTO_INCREMENT,
`c_name` varchar(70) DEFAULT NULL,
`c_birth` datetime NOT NULL,
`c_phone` varchar(50) DEFAULT NULL,
`c_gender` varchar(1) DEFAULT NULL,
PRIMARY KEY (`c_num`),
UNIQUE KEY `c_num` (`c_num`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
create table `order`(
`o_num` int(11) not null unique auto_increment,
`o_date` date ,
`c_id` int(11),
primary key(`o_num`),
constraint `fk_orders_customers_info` foreign key(`c_id`) references `customers_info`(`c_num`)
);
ERROR 1824 (HY000): Failed to open the referenced table 'customers_info'
mysql> alter table `customers_info` engine=InnoDB;
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table `customers_info`\G
*************************** 1. row ***************************
Table: customers_info
Create Table: CREATE TABLE `customers_info` (
`c_num` int NOT NULL AUTO_INCREMENT,
`c_name` varchar(70) DEFAULT NULL,
`c_birth` datetime NOT NULL,
`c_phone` varchar(50) DEFAULT NULL,
`c_gender` varchar(1) DEFAULT NULL,
PRIMARY KEY (`c_num`),
UNIQUE KEY `c_num` (`c_num`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> create table `order`(
-> `o_num` int(11) not null unique auto_increment,
-> `o_date` date ,
-> `c_id` int(11),
-> primary key(`o_num`),
-> constraint `fk_orders_customers_info` foreign key(`c_id`) references `customers_info`(`c_num`)
-> );
Query OK, 0 rows affected, 2 warnings (0.04 sec)
3.6.4、auto_increment初始值是否为1
==在MySQL中,auto_increment的默认初始值是1,==每增加一次记录,字段值加1。
但是,也是可以自定义设置auto_increment的初始值。
eg:在tb_emp中插入第一条记录,同时指定id的值为5,则之后的id都是从5开始增加。
添加唯一性的主键约束时,往往需要设置字段值自动递增。
create table `tb_emp`(
`id` int(10) not null unique auto_increment primary key
);
4、MySQL数据管理–DML语言(全部记住)
数据库意义:数据存储,数据管理
4.1、添加
insert into 表名(字段1,字段2....) values('值1','值2'.....);
注意:值必须与字段一一对应
insert into 表名 values('值1','值2'.....);
添加多个字段
insert into 表名(字段名) values(值1),(值2)....;
注意事项:
1、字段和字段之间使用英文逗号隔开
2、字段名可以省略,但是值与字段必须是一一对应
3、可以同时插入多条数据,values后面的值,需要使用英文逗号隔开。
4.2、修改–update
修改表的操作包括:
修改表名;
修改字段数据类型;
修改字段名
修改单个属性
update 表名 set `字段名` = 值 [where 条件判断];
update `student` set `name` = '长江七号';
修改多个属性
update 表名 set 字段名 = 值,字段名2= 值2....[where 条件判断];
条件判断:where 子句 运算符 id等于某个值,大于某个值,在某个区间内修改…。操作符会返回布尔值。
操作符 | 含义 | 范围 | 结果 |
---|
= | | | | <>或者 != | | | | > | | | | < | | | | <= | | | | >= | | | | between … and … | 在某个范围内 | [2,5] | | and | 我和你 && | 5>1 and 1>2 | false | or | 我或你 || | 5>1 and 1>2 | true |
通过多个条件修改数据
update 表名 set 列名 =值,列名2 = 值2....where 条件判断语句;
update `student` set `name`='长江7号' and `sex`='女';
注意:
- 条件判断,如果没有条件判断,则会修改所有列;**
- value,是一个具体的值,也可以是一个变量*
- 多个设置的属性之间,使用英文逗号隔开。
update `student` set `birthday`=CURRENT_TIME where `name` ='长江七号' and `sex` ='女';
4.3、删除
delete命令
delete from 表名 where 条件判断;
delete from 表名;
truncate命令
作用:完全清空一个数据库表,表的结构和索引约束不会变。
truncate table 表名;
truncate 和 delete区别
相同点:都能删除数据,都不会删除表结构
不同点:
? truncate 重新设置 自增列 计数器会归零;
? truncate 不会影响事务;
create table `order`(
`id` int(11) not null unique auto_increment,
`order_time` date ,
primary key(`o_num`)
)engine=InnoDB default charset=utf8;
insert into `order`(`id`) values('10'),('12');
delete from `order`;
truncate table `order`;
delete删除的问题:(可能会以面试题出现)
- 如果重启数据库,根据存储引擎不同,会有不同现象。
- 存储引擎是InnoDB的话, 自增列会从1开始(存在内存当中的,断电即失);
- 如果存储引擎是MyISAM,则将继续从上一个自增量开始(存在文件中的,不会丢失);
5、DQL查询数据(最重点)
5.1、DQL
DQL:data query language:数据查询语言
- 所有的查询操作都用select
- 简单的查询,复杂的查 询都可以
- 数据库中最核心的语言
- 使用频率最高的语句
5.1.1、select语法
select [distinct | all ]
要查询的字段
from 表名
xxx join 要连接的表 on 等值判断(这个表的主键等于另一张表的外键)
where (具体的值,子查询语句)
group by(通过哪几个字段来分组)
having
order by
limit
create database if not exists `school`;
use `school`;
drop table if exists `student`;
create table `student`(
`studentNo` int(4) not null comment '学号',
`loginpwd` varchar(20) default null comment '登录密码',
`studentName` varchar(20) default null comment '学生姓名',
`sex` tinyint(1) default null comment '性别,0或1',
`gradeId` int(11) default null comment '年级编号',
`phone` varchar(50) not null comment '联系电话,允许为空',
`address` varchar(255) not null comment '地址,允许为空',
`borndate` datetime default null comment '出生时间',
`email` varchar (50) not null comment '邮箱账号允许为空',
`identitycard` varchar(18) default null comment '身份证号',
primary key (`studentno`),
unique key `identitycard`(`identitycard`),
key `email` (`email`)
)engine=myisam default charset=utf8;
drop table if exists `grade`;
create table `grade`(
`gradeid` int(11) not null auto_increment comment '年级编号',
`gradename` varchar(50) not null comment '年级名称',
primary key (`gradeid`)
) engine=innodb auto_increment = 6 default charset = utf8;
drop table if exists `subject`;
create table `subject`(
`subjectno`int(11) not null auto_increment comment '课程编号',
`subjectname` varchar(50) default null comment '课程名称',
`classhour` int(4) default null comment '学时',
`gradeid` int(4) default null comment '年级编号',
primary key (`subjectno`)
)engine = innodb auto_increment = 19 default charset = utf8;
drop table if exists `result`;
create table `result`(
`studentno` int(4) not null comment '学号',
`subjectno` int(4) not null comment '课程编号',
`examdate` datetime not null comment '考试日期',
`studentresult` int (4) not null comment '考试成绩',
key `subjectno` (`subjectno`)
)engine = innodb default charset = utf8;
insert into `student` (`studentno`,`loginpwd`,`studentname`,`sex`,`gradeid`,`phone`,`address`,`borndate`,`email`,`identitycard`)
values
(1000,'123456','张伟',0,2,'13800001234','北京朝阳','1980-1-1','text123@qq.com','123456198001011234'),
(1001,'123456','赵强',1,3,'13800002222','广东深圳','1990-1-1','text111@qq.com','123456199001011233');
insert into `result`(`studentno`,`subjectno`,`examdate`,`studentresult`)
values
(1000,1,'2013-11-11 16:00:00',85),
(1000,2,'2013-11-12 16:00:00',70),
(1000,3,'2013-11-11 09:00:00',68),
(1000,4,'2013-11-13 16:00:00',98),
(1000,5,'2013-11-14 16:00:00',58);
insert into `grade` (`gradeid`,`gradename`) values(1,'大一'),(2,'大二'),(3,'大三'),(4,'大四'),(5,'预科班');
insert into `subject`(`subjectno`,`subjectname`,`classhour`,`gradeid`)values
(1,'高等数学-1',110,1),
(2,'高等数学-2',110,2),
(3,'高等数学-3',100,3),
(4,'高等数学-4',130,4),
(5,'C语言-1',110,1),
(6,'C语言-2',110,2),
(7,'C语言-3',100,3),
(8,'C语言-4',130,4),
(9,'Java程序设计-1',110,1),
(10,'Java程序设计-2',110,2),
(11,'Java程序设计-3',100,3),
(12,'Java程序设计-4',130,4),
(13,'数据库结构-1',110,1),
(14,'数据库结构-2',110,2),
(15,'数据库结构-3',100,3),
(16,'数据库结构-4',130,4),
(17,'C#基础',130,1);
5.2、单表查询
5.2.1、查询所有字段
select 字段名1,字段名2... from 表名;
select * from 表名;
mysql> select * from student\G
*************************** 1. row ***************************
studentNo: 1000
loginpwd: 123456
studentName: 张伟
sex: 0
gradeId: 2
phone: 13800001234
address: 北京朝阳
borndate: 1980-01-01 00:00:00
email: text123@qq.com
identitycard: 123456198001011234
*************************** 2. row ***************************
studentNo: 1001
loginpwd: 123456
studentName: 赵强
sex: 1
gradeId: 3
phone: 13800002222
address: 广东深圳
borndate: 1990-01-01 00:00:00
email: text111@qq.com
identitycard: 123456199001011233
2 rows in set (0.00 sec)
注意:
- 一般情况下最好还是不要使用通配符(*),除非查询所有字段;
- 缺点:使用通配符虽然可以节省输入查询语句的时间,但是获取不需要的列数据通常会降低查询和应用程序的效率;
- 优点:可以通过他获取列名。或者直接使用desc命令获取列名。
5.2.2、查询单个、多个字段
select 字段名 from 表名;
mysql> select `studentNo`,`studentName` from `student`;
+
| studentNo | studentName |
+
| 1000 | 张伟 |
| 1001 | 赵强 |
+
2 rows in set (0.00 sec)
注意:查询指定字段,其中可以是单个字段,也可以是多个字段。
5.3、别名 as
有的时候,字段名不是见名知意,所以就起别名。
select 字段名1 as 别名1,字段名2 as 别名2 from 表名;
5.4、去重(distinct)
作用:去除select查询语句出来的结果中重复的部分,重复的数据只显示一条
select * from result;
select `studentNo` from result;
select distinct `studentNo` from result;
数据库的列(表达式)
select version();
select 100*3-1 as 计算结果;
select @@auto_increment_increment;
select `studentNo`,`studentResult`+1 as '提分后' from result;
数据库中的表达式:文本值、列、null、函数、计算表达式、系统变量…
select 表达式 from 表名;
5.5、where 条件子句
作用:检索数据中符合条件的值
搜索的条件由一个或者多个表达式组成。返回的结果都是Boolean值
5.5.1、逻辑元素符
运算符 | 语法 | 描述 |
---|
and && | a and b a&&b | 逻辑与,两个都为真,结果为真 | or || | a or b a||b | 逻辑或,其中一个为真,则结果为真 | not ! | not a !a | 逻辑非,真为假,假为真 |
注意:最好还是写英文字符比较好
案例:
select `studentNo`,`studentResult` from result where `studentResult`>=95 && `studentResult`<=100;
select `studentNo`,`studentResult` from result where `studentResult`>=95 and `studentResult`<=100;
select `studentNo`,`studentResult` from `result` where `studentResult` between 95 and 100;
select `studentNo`,`studentResult` from `result` where `studentNo` !=1000;
select `studentNo`,`studentResult` from `result` where not `studentNo` =1000;
5.5.2、模糊查询
运算符 | 语法 | 描述 |
---|
is null | a is null | 如果操作符为null,结果为真 | is not null | a is not null | 如果操作符不为null,结果为真 | between and | a between b and c | 若a在b和c之间 | like | a like b | SQL匹配,如果a匹配b,则结果为真 | in | a in (a1,a2,a3…) | 假设a在a1,或者是a2…其中的某一个值,则结果为真 |
select `studentNo`,`studentName` from `student` where `studentName` like `刘%`;
select `studentNo`,`studentName` from `student` where `studentName` like `刘_`;
select `studentNo`,`studentName` from `student` where `studentName` like `刘__`;
select `studentNo`,`studentName` from `student` where `studentName` like `%嘉%`;
select `studentNo`,`studentName` from `student` where `studentNo` in(1001,1002,1003);
select `studentNo`,`studentName` from `student` where `address` in('北京');
select `studentNo`,`studnetName` from `stundet` where `address` = '' or `address` is null;
select `studentNo`,`studentName` from `student` where `bornDate` is not null;
5.6、连表查询
https://blog.csdn.net/huang__2/article/details/83688001
操作 | 描述 |
---|
inner join | 如果表中至少有一个匹配,就返回匹配的值 | left join | 即使右表中没有匹配,也会从左表中返回所有的数据 | right join | 即使左表中没有匹配,也会从右表中返回所有的数据 |
- join on:连接查询;其中join:连接的表;on:判断的条件
- where:等值查询
select * from `student`;
select * from `result`;
select `s.studentNo`,`studentName`,`subjectNo`,`studentName`
from `student` as s
inner join result as r
where `s.studnetNo` =`r.studentNo`;
select `s.studentNo`,`studentName`,`subjectNo`,`studentName`
from `student` [as] s
right join `result` [as] r
on `s.studentNo` = `r.studentNo`;
select `s.studentNo`,`studentName`,`subjectNo`,`studentName`
from `student` [as] s
right join `result` [as] r
on `s.studentNo` = `r.studentNo`;
select `s.studentNo`,`studentName`,`subjectNo`,`studentName`
from `student` [as] s
left join `result` [as] r
on `s.studentNo` = `r.studentNo`,
where `studentResult` is null;
select `s.studentNo`,`studentName`,`subjectName`,`result`
from `student` s
right join `result` r
on `r.studentNo` = `s.studentNo`
inner join `subject` sub
on `r.subjectNo` = `sub.subjectNo`
自连接(了解)
·自己的表和自己的表连接;核心:一张表拆为两张一样的表即可。·
自连接数据库:
CREATE TABLE `school`.`category`(
`categoryid` INT(3) NOT NULL COMMENT 'id',
`pid` INT(3) NOT NULL COMMENT '父id 没有父则为1',
`categoryname` VARCHAR(10) NOT NULL COMMENT '种类名字',
PRIMARY KEY (`categoryid`)
) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `school`.`category` (`categoryid`, `pid`, `categoryname`) VALUES ('2', '1', '信息技术');
insert into `school`.`CATEGOrY` (`categoryid`, `pid`, `categoryname`) values ('3', '1', '软件开发');
insert into `school`.`category` (`categoryid`, `PId`, `categoryname`) values ('5', '1', '美术设计');
insert iNTO `School`.`category` (`categoryid`, `pid`, `categorynamE`) VAlUES ('4', '3', '数据库');
insert into `school`.`category` (`CATEgoryid`, `pid`, `categoryname`) values ('8', '2', '办公信息');
insert into `school`.`category` (`categoryid`, `pid`, `CAtegoryname`) values ('6', '3', 'web开发');
inserT INTO `SCHool`.`category` (`categoryid`, `pid`, `categoryname`) valueS ('7', '5', 'ps技术');
父类表
categoryid | categoryName |
---|
2 | 信息技术 | 3 | 软件开发 | 5 | 美术设计 |
子类表
pid(父类id) | categoryid | categoryName |
---|
3 | 4 | 数据库 | 2 | 8 | 办公信息 | 3 | 6 | web开发 | 5 | 7 | ps技术 |
操作:查询父类对应的子类关系
父类 | 子类 |
---|
信息技术 | 办公信息 | 软件开发 | 数据库 | 软件开发 | web开发 | 美术设计 | ps技术 |
select `a.categoryName` as '父栏目',
`b.categoryName` as '子栏目'
from `category` as a,
`category` as b
where `a.categoryid` = `b.pid`;
select `studentNo`,`studnetName`,`gradeName`
from `student` s
inner join `grade` g
on `s.grdaeId` = `g.gradeId`;
select `subjectName`,`gradeName`
from `subject` sub
inner join `grade` g
on `sub.gradeId` = `g.gradeId`
select `s.studentNo`,`studnetName`,`subjectName`,`studentResult`
from `student` s
inner join `result` r
on `s.studentNo` = `r.studentNo`
inner join `subject` sub
on `r.subjectNo` =`sub.subjectNo`
where `subjectName` ='数据库结构-1';
5.7、分页和排序
5.7.1、分页:limit
分页作用:缓解数据库压力,给人的体验更好,瀑布流
select `s.studentNo`,`studentName`,`subjectName`,`studentResult`
from `student` s
inner join `result` r
on `s.studentNo` = `r.studentNo`
inner join `subject` sub
on `r.subjectNo` = `sub.subjectNo`
where `subjectName`='数据库结构-1'
order by `studentResult` asc
limit 0,5
语法:limit(查询起始下标,pagesize)
思考题
select `s.studentNo`,`studentName`,`subjectName`,`studentResult`
from `student` s
inner join `result` r
on `s.studentNo` = `r.studentNo`
inner join `subject` sub
on `sub.subjectNo` = `r.subjectNo`
where `subjectName` =' JAVA第一学年' and `studentResult`>=80
order by `studentResult` desc
limit 0,10
5.5.2、排序:order by
升序:ASC
order by 通过哪个字段排序
select `s.studentNo`,`studentName`,`subjectName`,`studentResult`
from `student` s
inner join `result` r
on `s.studentNo` = `r.studentNo`
inner join `subject` sub
on `r.subjectNo` = `sub.subjectNo`
where `subjectName`='数据库结构-1'
order by `studentResult` asc
降序:DESC
select `s.studentNo`,`studentName`,`subjectName`,`studentResult`
from `student` s
inner join `result` r
on `s.studentNo` = `r.studentNo`
inner join `subject` sub
on `r.subjectNo` = `sub.subjectNo`
where `subjectName`='数据库结构-1'
order by `studentResult` desc
5.8、子查询
where(这个值是计算出来的)
本质:在where语句中嵌套一个子查询语句
where(select * from 表名);
select `studentNo`,`r.subjectNo` `studentResult`
from `result` r
inner join `subject` sub
on `r.subjectNo` =`sub.subjectNo`
where `subjectName` ='数据库结构-1'
order by `studentResult` desc
select `studentNo`,`R.subjectNo` `studentResult`
from `result`
where `subjectNo`=(select `studentNo` from `subject` where `subjectName` = '数据库结构-1';);
select `studentNo` from `subject` where `subjectName` = '数据库结构-1';
select distinct `s.studentNo`,`studentName`
from `student` s
inner join `result` r
on `r.studnetNo` =`s.studentNo`
where `studentResult`>=80
select distinct `s.studentNo`,`studentName`
from `student` s
inner join `result` r
on `r.studnetNo` =`s.studentNo`
where `studentResult`>=80 and
`subjectNo`= (select `subjectNo` from `subject` where `subjectName` = '高等数学-2');
select `studentName`,`studentNo`
from `student` s
inner join `result` r
on `s.studentNo` = `r.studentNo`
inner join `subject` sub
on `r.subjectNo` = `sub.subjectNo`
where `subjectName` = '高等数学-2' and `studentResult`>=80;
select `s.studentNo`,`studentName`
from `student` s
where `studentNo` in(
select `studentNo` from `result` where `studentResult`>=80 and `subjectNo`=(
select `subjectNo` from `subject` where `subjectName` ='高等数学-2'
)
);
5.9、分组和过滤
select `subjectName`,
avg(`studentResult`) as 平均分,
max(`studentResult`) as 最高分,
min(`studentResult`) as 最低分
from `result` r
inner join `subject` sub
on `r.subjectNo` = `sub.studentNo`
group by `r.subjectNo`
having 平均分>80
6、Mysql函数
MySQL官方运算符和函数
https://dev.mysql.com/doc/refman/5.7/en/sql-function-reference.html
6.1、常用函数
6.1.1、数学运算
select abs(-8);
select celling(9.4)
select floor(9.4);
select rand();
select sign(10);
6.1.2、字符串函数
select char_length('zhangsan');
select concat('wo','1212');
select insert('我爱编程helloWord',1,2,'超级热爱');
select lower('ZHANGTAO');
select upper('zhangtao');
select instr('zhangtao','h');
select replace('爱拼才会赢','爱拼','对头');
select substr('爱拼才会赢',1,2);
select reverse('爱拼才会赢');
6.1.3、拼接函数
select concat('姓名:',字段名) as 新名字 from 表名;
select concat('姓名:',`name`) as 新名字 from `tb_emp`;
6.1.4、时间函数
select current_date();
select curdate();
select now();
select localtime();
select sysdate();
6.1.5、系统
select system_user();
select user();
select version();
6.2、聚合函数(常用)
函数名称 | 描述 |
---|
count() | 计数 | sum() | 求和 | avg() | 平均值 | max() | 最大值 | min() | 最小值 | … | … |
6.2.1、count()
作用:查询表中有多少条记录
相同点:都能够统计表中的数据。
不同点:
count(*)和count(1)的区别
https://blog.csdn.net/wx1528159409/article/details/95643499
select count(`studentName`) from `student`;
select count(*) from student;
select count(1) from result;
6.2.2、SUM()、AVG()、MAX()、MIN()
select sum(`studentResult`) as '总和' from result;
select avg(`studentResult`) as '平均分' from result;
select max(`studentResult`) as '最大值' from result;
select min(`studentResult`) as '最小值' from result;
select `subjectName`,
avg(`studentResult`) as 平均分,
max(`studentResult`) as 最高分,
min(`studentResult`) as 最低分
from `result` r
inner join `subject` sub
on `r.subjectNo` = `sub.studentNo`
group by `r.subjectNo`
having 平均分>80
6.3、数据库级别的MD5加密(扩展)
MD5:信息摘要算法第五代,主要增强算法复杂度和不可逆性。
MD5不可逆,具体的值的MD5是一样的
MD5破解网站的原理:背后有一个字典,MD5加密后的值,MD5加密前的值。
mysql> create table `testmd5`(
-> `id` int(4) not null,
-> `name` varchar(20) not null,
-> `pwd` varchar(50) not null,
-> primary key(`id`)
-> );
Query OK, 0 rows affected, 1 warning (0.03 sec)
mysql> insert into `testmd5` values(1,'zhangsan','123456'),
-> (2,'lisi','123456'),(3,'wangwu','123456');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> update `testmd5` set `pwd`=md5(pwd) where `id`=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
update `testmd5` set `pwd` =md5(`pwd`);
insert into `testmd5` values(4,'zhaowu',md5('123456'));
select * from `testmd5` where `name`='zhangsan' and `pwd` =md5('123456');
7、事务:Transaction
7.1、什么是事务
要么都成功,要么都失败
A 给 B 转账,A----》200 B
B 收到 A的钱,
A之前有1000,B有200
现在A有800,B有400
事务核心:将一组SQL放在一个批次去执行。
InnoDB支持事务
7.1.1、事务原则:ACID原则
ACID原则:原子性,一致性,持久性,隔离性
https://blog.csdn.net/dengjili/article/details/82468576
原子性:A–>B 1000-200=800;
? B 200+200=400;
1、原子性表示要么都成功,要么就都失败;
2、一致性:表示事务完成后,符合逻辑运算。即事务完成前后的数据完整性要保持一致。
即:两者加起来还是1000
3、持久性:事务结束后的数据不会随着外界原因而导致数据丢失。
即事务一旦提交就不可逆,被持久化到数据库
- 如果在操作前(事务没有提交),服务器宕机或者断电。那么重启数据库以后,数据状态恢复到原状态:即A–1000,B–200
- 如果在事务提交后(事务已经提交),服务器宕机或者断电。那么重启数据库以后,数据状态应该为:A–800,B–400
4、隔离性:事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰。
7.1.2、隔离所带来的问题
1、脏读:
一个事务读取另外一个事务没有提交的数据。
2、不可重复读–?
在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误,只是某些场合不同)
3、虚读(幻读)
是指一个事务内读取到了别的事务插入的数据,从而导致前后读取数据不一致。
7.2、执行事务
注意:MySQL是默认开启事务自动提交的
set autocommit = 0;
set autocommit = 1;
set autocommit =1;
start transaction
insert xx
insert xx
commit
rollback
set autocommit=1
savepoint
rollback to savepoint
release savepoint
事务的处理过程
7.2.1、模拟场景:转账
create database `shop` character set utf8 collate utf8_general_ci;
use `shop`;
create table `account`(
`id` int(3) not null auto_increment,
`name` varchar(30) not null,
`money` decimal(9,2) not null,
primary key(`id`)
)engine=InnoDB default charset=utf8;
insert into `account`(`name`,`money`) values('a',20000.00),('b',10000.00);
set autocommit=0;
start transaction;
update `account` set money=money-500 where `name`='a';
update `account` set money=money+500 where `name`='b';
commit;
rollback;
set autocommit=1;
8、索引
http://blog.codinglabs.org/articles/theory-of-mysql-index.html
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。
提取句子主干,就可以得到索引的本质:索引是数据结构。
8.1、索引的分类
注意:表中主键 索引只能有一个,而唯一索引可以有多个
- 主键索引(primary key);
- 唯一索引(unique key);
- 避免重复的列出现,唯一索引可以重复,多个列都可以标识为唯一索引
- 常规索引(key/index);
- 全文索引(fulltext);
- 在特定的数据库引擎下才有的,MyISAM
- 快速定位数据
8.1.1、基础语法
show index from `student`;
alter table `school.student` add fulltext index `studentName`(`studentName`);
8.1.2、分析sql执行的状况
http://blog.csdn.net/jiadajing267/article/details/81269067
explain select * from `student`;
explain select * from `student`;
explain select *from `student` where match(`studentName`) against('刘);
8.2、测试索引
插入100万条数据
delimiter $$
create function mock_data()
returns int
begin
declare num int default 1000000;
declare i int default 0;
while i<num do
set i=i+1;
end while
end;
insert into app_user(`name`,`email`,`phone`,`gender`,`password`,`age`)
8.3、索引原则
- 索引不是越多越好;
- 不要对进程变动数据加索引;
- 小数据量的表不需要加索引;
- 索引一般加在常用来查询的字段上。
8.3.1、索引的数据结构
Hash类型的索引
Btree:InnoDB的默认数据结构
http://blog.codinglabs.org/articles/theory-of-mysql-index.html
9、数据库备份
10、权限管理
10.1、用户管理
11、规范数据库设计
11.1、为什么需要设计
当数据库比较复杂的时候,我们就需要设计
糟糕的数据库设计:
- 数据冗余,浪费空间;
- 数据库插入和删除都会很麻烦,异常(屏蔽使用物理外键);
- 程序的性能差。
良好的数据库设计:
- 节省内存空间;
- 保证数据库的完整性;
- 方便我们开发系统;
11.1.1、软件开发中,关于数据库的设计
- 分析需求:分析业务和需要处理的数据库的需求;
- 概要设计:设计关系图E-R图;
案列----设计数据库的步骤 :(个人博客)
1、收集信息,分析需求
- 用户表(用户登录注销,用户的个人信息,写博客,创建分类)
- 分类表(文章分类,谁创建的)
- 文章表(文章的信息)
- 评论表()
- 友情链接表(友情链接信息)
- 自定义表(系统信息,某个关键的字,或者一些主字段) key:value
2、标识实体(把需求落地到每个字段)
3、标识实体之间的关系
写博客:user—>blog
创建分类:user—>category
关注:user—>user
友情链接:links
评论:user-user-blog
11.2、三大范式
为什么需要数据规范化?
- 信息重复
- 更新异常
- 插入异常—无法正常显示信息
- 删除异常—eg:外键。丢失有效的信息
11.2.1、第一范式(1NF)
原子性:保证每一列不可再分
11.2.2、第二范式(2NF)
前提:满足第一范式
每张表只做一件事,只描述一件事。
第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的一部分相关。
11.2.3、第三范式(3NF)
前提:满足第一范式和第二范式
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
三大范式的目的规范数据库的设计
11.2.4、规范性和性能的问题:
关联查询的表不能超过三张表
- 考虑商业化的需求和目标,(成本,用户体验等),数据库的性能更加重要;
- 在规范性能的问题的时候,需要适当的考虑一下规范性;
- 故意给某些表增加一些冗余的字段(从多表查询变为单表查询);
- 故意增加一些计算列(从大数据量降低为小数据量的查询:索引)。
关于数据库引擎
查看系统表类型
mysql> select distinct(engine) from information_schema.tables;
+
| ENGINE |
+
| NULL |
| InnoDB |
| CSV |
| PERFORMANCE_SCHEMA |
+
注意:从MySQL8.0之后,系统表全部换成了事务性的InnoDB,默认的MySQL实例将不包含MyISAM表,除非手动创建。
INNODB 默认使用
MYISAM 早些年使用的
| MYISAM | INNODB |
---|
事务支持 | 不支持 | 支持 | 数据行锁定 | 不支持 | 支持 | 外键约束 | 不支持 | 支持 | 全文索引 | 支持 | 支持(?) | 表空间的大小 | 较小 | 较大,约为2倍 |
常规使用操作:
MYISAM 节约空间,速度较快
INNODB 安全性高,支持事务的处理,多表多用户操作
数据库目录存放的地方
所有的数据库文件都是存储在data目录下面。
注意:一个文件夹对应一个数据库
本质还是文件的存储
MySQL引擎在物理文件上的区别:
- INNODB在数据库表中只有一个“*.frm”文件,以及上级目录下的“ibdata1” 文件;
- MyISAM对应文件:
- ? *.frm-----表结构的定义文件
- ? *.MYD—数据文件(data)
- ? *.MYI----索引文件(index)
设置字符集编码
charset=utf8
注意:
在mysql8.0之前,如果不设置字符集,就会是数据库自己的字符集编码----Latin1
在my.ini文件中配置默认的字符编码
character-set-server=utf8
拓展:
MySQL中数据类型的长度问题总结
http://blog.csdn.net/yaruli/article/details/79187814
MySQL远程连接
https://cloud.tencent.com/developer/article/1592379
- 在特定的数据库引擎下才有的,MyISAM
- 快速定位数据
|