数据库可以持久化数据到本地,结构化查询。
三个基本名词:
数据库存储数据的特点:
数据存放到表中,然后表再放到库中
一个库中可以有多张表,每张表具有唯一的表名用来标识自己
表中有一个或多个列,列又称为“字段”,相当于java中“属性”
表中的每一行数据,相当于java中“对象”
SQL语言的分类
DML(Data Manipulation Language)
:数据操纵语句,用于添加、删除、修改、查询数据库记录,并检查数据完整性。包括如下SQL语句:
DDL(Data Definition Language)
:定义数据库的结构,比如创建、修改或删除数据库对象,包括如下SQL语句:
DCL(Data Control Language)
:数据控制语句,用于定义用户的访问权限和安全级别。包括如下SQL语句:
GRANT:授予访问权限
REVOKE:撤销访问权限
COMMIT:提交事务处理
ROLLBACK:事务处理回退
SAVEPOINT:设置保存点
LOCK:对数据库的特定部分进行锁定
基本的命令
首先是数据库的下载,Windows平台下下载:http://dev.mysql.com/downloads/mysql
下载安装后,可以——右击计算机—管理—服务—启动或停止MySQL服务。但是座位于i个程序员,这种方式也太low了,所以这几个命令可以看看:
启动:net start mysql服务名
停止:net stop mysql服务名
登录 mysql [-h 主机名 -P 端口号] –u用户名 –p密码
,[]这个是可选的,用于远程连接。
退出 exit
一个基本的操作流程
使用一个数据库: use 数据库名称;
新建一个数据库: create database 数据库名
查看指定的数据库中有哪些数据表: show tables;
建表。
查看表的结构:desc 表名
删除表: drop table 表名
这是对数据库以及表的一些基本的操作命令,只展示两张基本操作截图,其他操作可以自行测试。
然后就是对表的数据经行基本的操作:
查看表中的所有记录: select * from 表名;
向表中插入记录:insert into 表名(列名列表) values(列对应的值的列表);
注意:插入 varchar 或 date 型的数据要用 单引号 引起来
修改记录: update 表名 set 列1 = 列1的值, 列2 = 列2的值 where …
删除记录: delete from 表名 where ….
这大概就是一个最基本的操作了,详细的操作将在下面展开。
上面也基本说明了DML就是对数据(也就是表)的基本操作。
查询应该是使用最为频繁的一种操作了。数据库的优化,也基本上就是对查询的优化。
基本的语法
select 查询列表 from 表名;
。例如:select * from student;
这就是对student查询所有的数据。
查询单个字段:select 字段名 from 表名;
。例如:select name,age from student;
只查询这两个字段。
特别注意:
查询的时候可以给查询到的列取一个别名,方便数据的展示。
规则:紧跟列名,也可以在列名和别名之间加入关键字 ‘AS’,别名使用双引号,以便在别名中包含空格或特殊的字符并区分大小写。
例如:select name as studentName,age "studentAge" from student;
去重查询,有时候不需要重复的数据就可以使用关键字来对这个数据去重,语法如下:
select distinct 字段名 from 表名;
带条件的查询
使用WHERE 子句,将不满足条件的行过滤掉。WHERE 子句紧随 FROM 子句。语法如下:
select 查询列表 from 表名 where 筛选条件
,例如:(只查询部门id为90的员工)
也可以加其他的比较运算符:
简单条件运算符:> < = <> != >= <= <=>安全等于
逻辑运算符:&& and || or ! not
,如果有多个条件,可以使用逻辑运算符连接起来:
其它比较运算:
操作符 | 含义 |
---|---|
BETWEEN ...AND... |
在两个值之间 (包含边界) |
IN(set) |
等于值列表中的一个 |
LIKE |
模糊查询 |
IS NULL |
空值 |
使用 IS (NOT) NULL 判断空值,例如:select * from student where name is NULL
使用 BETWEEN 运算来显示在一个区间内的值:
使用 IN运算显示列表中的值:
使用 LIKE 运算选择类似的值,选择条件可以包含字符或数字:
如下图,查询名字开头单词为S的,后面是啥都行,只要求开头为S,比如Ssdg也会被查询出来。
如果说上面这个例子%改为 _ ,那就变成了后面只能有一个字符。
‘%’和‘-’可以同时使用:select * from student where name like %进_
基本语法:select 查询列表 from 表 where 筛选条件 order by 排序列表 【asc | desc】
如果最后不加DESC,默认就是ASC升序的方式。
如果我们的字段取了别名,使用这个字段排序就需要使用别名:(salary*12 扩大12倍)
如果使用多个字段排序,按照ORDER BY 列表的顺序排序。(也就是按照写在前面的排序,如果有相等的就在按照后面的字段再次排序)
比如这个,由于department_id后面没有DESC,所以默认按照这个字段升序排列,然后有相等的再按照后面的salary降序排列。
分组函数作用于一组数据,并对一组数据返回一个值。
组函数类型:
可以对数值型数据使用AVG 和 SUM 函数,可以对==任意数据类型(字符按照字典排序)==的数据使用 MIN 和 MAX 函数。
COUNT(*) 返回表中记录总数,适用于任意数据类型:
COUNT(expr) 返回expr不为空的记录总数。
可以使用GROUP BY子句将表中的数据分成若干组,语法如下:
select 分组函数,分组后的字段
from 表
【where 筛选条件】
group by 分组的字段
【having 分组后的筛选】
【order by 排序列表】
在SELECT 列表中所有未包含在组函数中的列都应该包含 在 GROUP BY 子句中。
包含在 GROUP BY 子句中的列不必包含在SELECT 列表中,就比如上面这个例子中的department_id在select中就可以不写,但是结果不会包含这个列。
WHERE 子句中不能使用组函数
使用 HAVING 过滤分组:(跟where用法一样,作用域不同)
多个表可以经行联合的数据查询并展示,语法如下:select 字段 from 表1,表2,...;
笛卡尔集会在下面条件下产生:(效率很低)
为了避免笛卡尔集, 可以在 WHERE 加入有效的连接条件。
等值连接:
SELECT beauty.id,NAME,boyname FROM beauty ,boys
WHERE beauty.`boyfriend_id`=boys.id;
区分重复的列名
连接 n个表,至少需要 n-1个连接条件。
内连接
基本的语法格式:(别名可取可不取)
select 查询列表
from 表1 别名
[inner] join 表2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;
这种链接的特点:
举个例子:
#案例.查询名字中包含e的员工名和工种名(添加筛选)
SELECT last_name,job_title
FROM employees e
INNER JOIN jobs j
ON e.`job_id`= j.`job_id`
WHERE e.`last_name` LIKE '%e%';
外连接
基本的语法格式:
select 查询列表
from 表1 别名
left|right|full [outer] join 表2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;
这种连接的特点:
left join
左边的就是主表,right join
右边的就是主表,full join
两边都是主表举些例子:
#案例1:查询哪个部门没有员工,左外
SELECT d.*,e.employee_id
FROM departments d
LEFT OUTER JOIN employees e
ON d.`department_id` = e.`department_id`
WHERE e.`employee_id` IS NULL;
#右外
SELECT d.*,e.employee_id
FROM employees e
RIGHT OUTER JOIN departments d
ON d.`department_id` = e.`department_id`
WHERE e.`employee_id` IS NULL;
#全外
USE girls;
SELECT b.*,bo.*
FROM beauty b
FULL OUTER JOIN boys bo
ON b.`boyfriend_id` = bo.id;
John连接总结
举个例子
SELECT * FROM t_dept, t_emp;
t_dept共20条记录,t_emp共6条记录。两表共同查询后共120条记录
SELECT * FROM t_emp a INNER JOIN t_dept b ON a.deptId = b.id;
只会把两个表共有的部分查询出来
SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.deptId = b.id;
取出左表的所有数据,然后有伴的数据满足就查询出来,不满足就填充null,和右外连接一致
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId = b.id;
SELECT * FROM t_emp e LEFT JOIN t_dept d ON d.`id` = e.`deptId` WHERE d.id IS NULL
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId = b.id WHERE a.deptId IS NULL;
注意:判断字段是否为NULL时,不能使用’=’
因为 = NULL
的结果不会报错,但是结果永远为false。所以必须使用IS NULL
来进行判空
MySQL不支持全外连接,要查询两个表的全集,需要合并两个查询结果,所以要使用 UNION 关键字
SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.deptId = b.id
UNION
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId = b.id;
这种连接会把两个表有的都获取出来,然后对应的没有的置为null
SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.deptId = b.id WHERE b.id IS NULL
UNION
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId = b.id WHERE a.deptId IS NULL;
子查询
出现在其他语句内部的select语句,称为子 查询或内查询内部嵌套其他select语句的查询,称为外查询或主查询
例如:
select first_name from employees where department_id in(
select department_id from departments where location_id=1700
)
特别注意:
举个例子:谁的工资比 Abel 高?
SELECT last_name
FROM employees
WHERE salary > (SELECT salary FROM employees WHERE last_name = 'Abel');
会先执行完子查询,然后结果供主查询使用。
分页查询
当要查询的条目数太多,一页显示不全,这个时候就可以使用分页查询。
基本的语法格式:
select 查询列表
from 表
limit [offset,] size;
# 注意:
offset代表的是起始的条目索引,默认从0开始
size代表的是显示的条目数
一个固定的分页公式:
假如要显示的页数为page,每一页条目数为size:select 查询列表 from 表 limit (page-1)*size,size;
举个例子:
#案例1:查询前五条员工信息
SELECT * FROM employees LIMIT 0,5;
SELECT * FROM employees LIMIT 5;
#案例2:查询第11条——第25条
SELECT * FROM employees LIMIT 10,15;
总结查询以及执行顺序
select 查询列表 7
from 表1 别名 1
连接类型 join 表2 2
on 连接条件 3
where 筛选 4
group by 分组列表 5
having 筛选 6
order by排序列表 8
limit 起始条目索引,条目数; 9
insert语句
基本语法格式:insert into 表名(字段名,...) values(值,...);
特别注意:
要求值的类型和字段的类型要一致或兼容
字段的个数和顺序不一定与原始表中的字段个数和顺序一致,但必须保证值和字段一一对应
假如表中有可以为null的字段,注意可以通过以下两种方式插入null值
字段和值的个数必须一致
字段名可以省略,默认所有列
举个例子:
INSERT INTO departments(department_id, department_name,manager_id, location_id)
VALUES (70, 'Public Relations', 100, 1700);
如果有日期类型:字符和日期型数据应包含在单引号中。
INSERT INTO employees(employee_id,last_name,email,hire_date,job_id)
VALUES (300,’Tom’,’[email protected]’,to_date(‘2012-3-21’,’yyyy-mm-dd’),’SA_RAP’);
一次插入多条语句的语法:insert into 表名【(字段名,..)】 values(值,..),(值,...)
举个例子:
INSERT INTO departments(department_id, department_name,manager_id, location_id)
VALUES
(70, 'Public Relations', 100, 1700),
(71, 'Public sdf', 23, 65745),
(72, 'Public asdg', 54, 3454);
update语句
基本的语法格式:update 表名 set 字段=值,字段=值 【where 筛选条件】;
可以一次更新多条数据。如果需要回滚数据,需要保证在DML前,进行 设置:SET AUTOCOMMIT = FALSE;
使用 WHERE 子句指定需要更新的数据:
UPDATE employees SET department_id = 70 WHERE employee_id = 113;
如果省略 WHERE 子句,则表中的所有数据都将被更新:
UPDATE copy_emp SET department_id = 110;
delete语句
基本的语法格式:delete from 表名 【where 筛选条件】【limit 条目数】
使用 WHERE 子句删除指定的记录:delete from departments where department_name = 'Finance';
如果省略 WHERE 子句,则表中的全部数据将被删除:DELETE FROM copy_emp;
这个部分相对上面内容就少了很多了。
数据库的管理
创建数据库:create database [if not exists] 库名 [character set 字符集名];
修改库:alter database 库名 character set 字符集名;
删除库:drop database [if exists] 库名;
相关其他命令,这个一般用于命令行中:
表的管理语句
创建表:
create table 【if not exists】 表名(
字段名 字段类型 【约束】,
字段名 字段类型 【约束】,
。。。
字段名 字段类型 【约束】
)
# 举个例子:
CREATE TABLE dept(
deptno INT(2),
dname VARCHAR(14),
loc VARCHAR(13)
);
常用的数据类型:
INT | 使用4个字节保存整数数据 |
---|---|
CHAR(size) | 定长字符数据。若未指定,默认为1个字符,最大长度255 |
VARCHAR(size) | 可变长字符数据,根据字符串实际长度保存,必须指定长度 |
FLOAT(M,D) | 单精度,M=整数位+小数位,D=小数位。 D<=M<=255,0<=D<=30, 默认M+D<=6 |
DOUBLE(M,D) | 双精度。D<=M<=255,0<=D<=30,默认M+D<=15 |
DATE | 日期型数据,格式’YYYY-MM-DD’ |
BLOB | 二进制形式的长文本数据,最大可达4G |
TEXT | 长文本数据,最大可达4G |
修改表的语句:
添加列:alter table 表名 add column 列名 类型 [first|after 字段名];
修改列的类型或约束:alter table 表名 modify column 列名 新类型 [新约束];
修改列名:alter table 表名 change column 旧列名 新列名 类型;
删除列:alter table 表名 drop column 列名;
修改表名:alter table 表名 rename [to] 新表名;
删除表:drop table [if exists] 表名;
建表的时候常见的约束
NOT NULL
:非空,该字段的值必填UNIQUE
:唯一,该字段的值不可重复DEFAULT
:默认,该字段的值不用手动插入有默认值CHECK
:检查,mysql不支持PRIMARY KEY
:主键,该字段的值不可重复并且非空 unique+not nullFOREIGN KEY
:外键,该字段的值引用了另外的表的字段主键:一个表至多有一个主键,主键本生就包含了唯一和非空两个约束
外键的作用和注意点:
create table 表名(
字段名 字段类型 not null,#非空
字段名 字段类型 primary key,#主键
字段名 字段类型 unique,#唯一
字段名 字段类型 default 值,#默认
constraint 约束名 foreign key(字段名) references 主表(被引用列)
)
在一张数据表建好之后,这些约束也可以通过SQL语句经行修改或者删除:
alter table 表名 modify column 字段名 字段类型 not null;
alter table 表名 modify column 字段名 字段类型 ;
alter table 表名 modify column 字段名 字段类型 default 值;
alter table 表名 modify column 字段名 字段类型 ;
alter table 表名 add [constraint 约束名] primary key(字段名);
alter table 表名 drop primary key;
更多的写法就自行搜索吧。
的字段值引用了主表的某字段值
create table 表名(
字段名 字段类型 not null,#非空
字段名 字段类型 primary key,#主键
字段名 字段类型 unique,#唯一
字段名 字段类型 default 值,#默认
constraint 约束名 foreign key(字段名) references 主表(被引用列)
)
在一张数据表建好之后,这些约束也可以通过SQL语句经行修改或者删除:
alter table 表名 modify column 字段名 字段类型 not null;
alter table 表名 modify column 字段名 字段类型 ;
alter table 表名 modify column 字段名 字段类型 default 值;
alter table 表名 modify column 字段名 字段类型 ;
alter table 表名 add [constraint 约束名] primary key(字段名);
alter table 表名 drop primary key;
更多的写法就自行搜索吧。