数据库系统:
数据库:文件夹
数据表:文件
表记录:一条数据
sql语句规范
sql是Structured Query Language(结构化查询语言)的缩写。SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言
<1> 在数据库系统中,SQL语句不区分大小写(建议用大写) 。但字符串常量区分大小写。建议命令大写,表名库名小写;
<2> SQL语句可单行或多行书写,以“;”结尾。关键词不能跨多行或简写。
<3> 用空格和缩进来提高语句的可读性。子句通常位于独立行,便于编辑,提高可读性。
1 2 |
SELECT * FROM tb_table WHERE NAME="YUAN"; |
<4> 注释:
单行注释:--
多行注释:/*......*/
<5>sql语句可以折行操作
1、mysql的常用sql语句:
a.库的操作
1.创建数据库:
create database 库名 [character set utf8(指定字符集,不加默认为拉丁文)];
2.查看数据库
show databases; 查看所有数据库
show create database 库名; 查看数据库的创建信息
use 库名; 切换到指定数据库
select database(); 查看当前所在的库
3.修改数据库(修改字符集)
alter database 库名 [character set utf8(指定字符集,不加默认为拉丁文)];
4.删除数据库
drop database 库名;
b.表的操作
1.创建表
create table 表名 (
字段 类型[完整性约束条件],
字段 类型[完整性约束条件]
);
2.查看表信息
show tables; 查看当前库中所有的表
show create table 表名; 查看表的建表语句
desc 表名; 查看表结构
show columns from 表名; 同上,查看表结构
3.修改表结构
alter table 表名(
add 字段 类型[完整性约束条件] [first|after 字段名], #增加字段
modify 字段 类型[完整性约束条件] [first|after 字段名], #修改字段类型
change 旧字段 新字段 类型[完整性约束条件][first|after 字段名] #修改字段名
drop 字段; #删除一列字段
);
rename table 旧表名 to 新表名; 修改表名
4.删除表
drop table 表名; 删除表
c.表记录的操作
1.增加表记录
增加一条记录:
insert [into] 表名 (字段1,字段2,…) values (值1,值2,…);
增加多条:
insert [into] 表名 (字段1,字段2,…) values (值1,值2,…),
(值1,值2,…),
…… ;
set插入:
insert [into] 表名 set 字段1=值2,字段2=值2;
2.修改表记录
update 表名 set 字段1=值1 where子句
3.删除表记录
delete from 表名 where 子句;
清空表内所有记录有两种方法:
方式1:
delete from 表名;
方式2:
truncate table 表名;
对比:
delete语句只能删除表中的内容,不能删除表本身,想要删除表,用drop
truncate也可以删除表中的所有数据,语句首先会摧毁表,再新建表,此种方式删除的数据不能在事务中恢复,数据量大时推荐使用
4.查询表记录
select * from 表名; #显示所有的记录信息
select 字段1,字段2,… from 表名
where 子句 #过滤查询
group by 字段 #分组查询
having 子句 #过滤
order by 字段 #排序
limit #记录条数限制
Mysql在执行sql语句时的执行顺序:
from > where > select > group by > having > orderby
(1)where 子句:
比较运算符:
> < >= <=<> !=
between 80 and 100 值在10到20之间
in(80,90,100) 值是10或20或30
like ‘yuan%‘ (%后面可以接_,代表匹配一个字符,可以接多个)
逻辑运算符
在多个条件直接可以使用逻辑运算符 and or not
(2)group by 字段:
GROUP BY 语句根据某个列对结果集进行分组,在分组的列上我们可以使用聚合函数进行相关查询
count 计数
sum 总数值
avg 平均值
max 最大值
min 最小值
(3)having 子句
过滤
与where 子句的区别:
在sql语句中,两者的书写顺序和执行顺序不一样,where写在前面,先执行,having写在后面,后执行,having适用于对查询结果的二次过滤
(4)order by 字段
按指定的列进行排序,排序的列即可是表中的列名,也可以是select语句后指定的别名
语法:select*|field1,field2... from tab_name order by field [Asc|Desc]
-- Asc 升序、Desc 降序,其中asc为默认值 ,ORDER BY 子句应位于SELECT语句的结尾。
(5)limit记录条数限制
(6)正则表达式
练习:
先创建一个员工表:
create table emp(
id int primary keyauto_increment,
name varchar(20),
gender enum("male","female","other"),
age tinyint,
dep varchar(20),
city varchar(20),
salary double(7,2)
);
表内插入信息:
insert into emp(name,gender,age,dep,city,salary) values
("yuan","male",24,"教学部","河北省",8000),
("egon","male",34,"保安部","山东省",8000),
("alex","male",28,"保洁部","山东省",10000),
("景丽阳","female",22,"教学部","北京",9000),
("张三", "male",24,"教学部","河北省",6000),
("李四", "male",32,"保安部","北京",12000),
("王五", "male",38,"教学部","河北省",7000),
("赵六", "male",19,"保安部","河北省",9000),
("猪七", "female",24,"保洁部","北京",9000);
查看表记录信息:
mysql> select * from emp;
+----+--------+--------+------+--------+--------+----------+
| id | name | gender | age | dep | city | salary |
+----+--------+--------+------+--------+--------+----------+
| 1| yuan | male | 24| 教学部 | 河北省 | 8000.00 |
| 2| egon | male | 34| 保安部 | 山东省 | 8000.00 |
| 3| alex | male | 28| 保洁部 | 山东省 | 10000.00 |
| 4| 景丽阳 | female| 22 | 教学部 | 北京 | 9000.00 |
| 5| 张三 | male | 24 | 教学部 | 河北省 | 6000.00 |
| 6| 李四 | male | 32 | 保安部 | 北京 | 12000.00 |
| 7| 王五 | male | 38 | 教学部 | 河北省 | 7000.00 |
| 8| 赵六 | male | 19 | 保安部 | 河北省 | 9000.00 |
| 9| 猪七 | female | 24 | 保洁部 | 北京 | 9000.00 |
+----+--------+--------+------+--------+--------+----------+
查询语句实例:
查询所有name、salary字段的值
select name,salary from emp;
查询所有name、salary字段的值并设置别名
select name as 姓名,salary as 薪水 from emp; #as可以省略不写
- where 子句
查询所有年龄大于20的:
select * from emp where age>20;
查询所有年龄大于20的name、salary:
select name,salary from emp whereage>20;
查询所有年龄除以10大于2的name、age:
select name,age from emp where age/10>2;
查询所有年龄在20到30岁之间的name、age:
select name,age from emp where age between20 and 30; #闭区间,包含20和30
查询所有姓张的name、age:
select name,age from emp where name like"张%";
查询所有性别为male且年龄大于25的name、age:
select name,age from emp wheregender="male" and age>25;
2.group by 字段
查询每个部门的人数:
select dep,count(*) from emp group by dep;
查询每个部门里的最高工资:
select dep,max(salary) from emp group bydep;
查询男生、女生的人数:
select gender,count(*) from emp group by gender;
查询每个省份的最高工资:
select city,avg(salary) from emp group bycity;
3.having 子句:
查询平均工资大于8000的省份:
select city,avg(salary) from emp group bycity having avg(salary)>8000;
4.order by
按员工薪资从低到高排序:
select * from emp order by salary;
按员工薪资从高到低排序:
select * from emp order by salary desc;
5.limit
查询表内前5条记录:
select * from emp limit 5;
查询第2条记录以后的3条记录:
select * from emp limit 2,3; #不包含第2条
2、多表查询
创建练习表:
首先创建员工表emp:
create table emp(
id int primary key auto_increment,
name varchar(20),
salary double(7,2),
dep_id int
);
插入员工信息(dep_id对应dep表中的id):
insert into emp (name,salary,dep_id) values("张三",8000,2),
("李四",12000,1),
("王五",5000,2),
("赵六",8000,3),
("猪七",9000,1),
("周八",7000,4),
("蔡九",7000,2);
创建部门表dep:
create table dep(
id int primary key auto_increment,
name varchar(20)
);
插入部门信息:
insert into dep (name) values ("教学部"),
("销售部"),
("人事部");
笛卡尔积查询:
mysql> select * from emp,dep;
+----+------+----------+--------+----+--------+
| id | name | salary | dep_id | id | name |
+----+------+----------+--------+----+--------+
| 1| 张三 | 8000.00 | 2 | 1 | 教学部 |
| 1| 张三 | 8000.00 | 2 | 2 | 销售部 |
| 1| 张三 | 8000.00 | 2 | 3 | 人事部 |
| 2| 李四 | 12000.00| 1 | 1 | 教学部 |
| 2| 李四 | 12000.00| 1 | 2 | 销售部 |
| 2| 李四 | 12000.00| 1 | 3 | 人事部 |
| 3| 王五 | 5000.00 | 2 | 1 | 教学部 |
| 3| 王五 | 5000.00 | 2 | 2 | 销售部 |
| 3| 王五 | 5000.00 | 2 | 3 | 人事部 |
| 4| 赵六 | 8000.00 | 3 | 1 | 教学部 |
| 4| 赵六 | 8000.00 | 3 | 2 | 销售部 |
| 4| 赵六 | 8000.00 | 3 | 3 | 人事部 |
| 5| 猪七 | 9000.00 | 1 | 1 | 教学部 |
| 5| 猪七 | 9000.00 | 1 | 2 | 销售部 |
| 5| 猪七 | 9000.00 | 1 | 3 | 人事部 |
| 6| 周八 | 7000.00 | 4 | 1 | 教学部 |
| 6| 周八 | 7000.00 | 4 | 2 | 销售部 |
| 6| 周八 | 7000.00 | 4 | 3 | 人事部 |
| 7| 蔡九 | 7000.00 | 2 | 1 | 教学部 |
| 7 |蔡九 | 7000.00 | 2 | 2 | 销售部 |
| 7| 蔡九 | 7000.00 | 2 | 3 | 人事部 |
+----+------+----------+--------+----+--------+
21 rows in set (0.00 sec)
a.内连接查询
select * from 表1 inner join 表2 on 子句
inner join(等值连接) 只返回两个表中联结字段相等的行
查询两张表中都有的关联数据,相当于利用条件从笛卡尔积结果中筛选出了正确的结果
查询张三所在的部门:
select emp.name,dep.name from emp,dep whereemp.dep_id=dep.id and emp.name="张三";
或者
mysql> select emp.name,dep.name from empinner join dep on emp.dep_id=dep.id where emp.name="张三";
b.外连接查询
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
以左表为主,打印出所有信息(包含左表的所有记录):
select * from emp left join dep onemp.dep_id=dep.id order by emp.id;
以右表为主,打印出所有信息(包含右表的所有记录):
select * from emp right join dep onemp.dep_id=dep.id order by emp.id;
3、完整性约束
完整性约束是对字段进行限制,从而符合该字段达到我们期望的效果比如字段含有默认值,不能是NULL等 。直观点说:如果插入的数据不满足限制要求,数据库管理系统就拒绝执行操作
a. 唯一约束
可以有多个但索引列的值必须唯一,索引列的值允许有空值
如果能确定某个数据列将只允许包含不相同的值,在为这个数据列创建索引的时候就应该使用关键字unique
在建表时添加唯一约束:
create table 表名(
id int auto_increment, #id字段设置自增
namevarchar(20) default null,
primary key (id), #id字段设置为主键
unique key 索引别名 (name) #name设置为唯一索引
);
在建表后添加唯一约束:
alter table 表名 add constraint 索引别名 unique (name);
如果不需要唯一约束,则可以这样删除
alter table 表名 drop index 索引别名;
b.自增约束
MySQL 每张表只能有1个自动增长字段,这个自动增长字段通常作为主键,也可以用作非主键使用,但是请注意将自动增长字段当做非主键使用时必须为其添加唯一索引,否则系统将会报错
create table 表名(
id int not null,
namevarchar(20),
age int uniqueauto_increment #把age字段设置为自增字段和唯一索引
);
c.主键约束
主键是用于唯一标识一条记录的约束,如同身份证
主键有两个约束:非空且唯一
建表时添加主键的两种方式:
方式1:
create table 表名(
字段 类型 primary key auto_increment, #设置字段为主键且自增
字段 类型
);
方式2:
create table 表名(
字段 类型 not null,
字段 类型
);
建表后添加主键:
alter table 表名 add primary key(字段名)
设置主键注意:
1、一张表中最多只能有一个主键
2、表中如果没有设置主键,默认设置NOT NULL的字段为主键;此外,表中如果有多个NOT NULL的字段,则按顺序将第一个设置NOT NULL的字段设为主键。
主键一定是非空且唯一,但非空且唯一的字段不一定是主键。
3、主键类型不一定必须是整型
删除主键:
alter table 表名 drop primary key;
删除主键注意:
如果主键是auto_increment,需要先取消auto_increment,因为auto_increment只能加在key上
create table 表名(字段 类型 primary key auto_increment);
alter table 表名 modify 字段 类型; #删除自增,主键依然存在
alter table 表名 drop primary key; #删除主键
复合主键:
复合主键 就是指表的主键含有一个以上的字段
如果一列不能唯一区分一个表里的记录时,可以考虑多个列组合起来达到区分表记录的唯一性
创建复合主键:
create table 表名 (
字段1 int,
字段2 int,
字段3 int,
primary key (字段1,字段2)
);
修改复合主键:
alter table 表名 add primary key (字段1,字段2,字段3);
d.外键约束
外键的定义语法:
[constraint symbol] foreign key [id](index_col_name, ...)
references tbl_name(index_col_name, ...)
[on delete {restrict | cascade | set null | no action | set default}]
[on update {restrict | cascade | set null | no action | set default}]
表关系:
表与表之间的关系(两张表):
一对多
将关联字段设置在多的表中(多)
有外键的叫子表,没有外键的叫主表
多对多
两表彼此一对多,就是多对多的关系
借助第三张表来实现
一对一
可以将关联字段设在任意一张表上,但约束必须为unique