数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储起来,用户可以对数据库中的数据进行增加,修改,删除及查询操作。
数据库管理系统(DataBase Management System,DBMS):指一种操作和管理数据库的 大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中表内的数据。
数据库中以表为组织单位存储数据。表中有行和列,我们叫做字段和记录
表类似我们的Java类,每个字段都有对应的数据类型。
那么用我们熟悉的java程序来与关系型数据对比,就会发现以下对应关系。
类----------表
类中属性----------表中字段
对象----------记录
根据表字段所规定的数据类型,我们可以向其中填入一条条的数据,而表中的每条数据类似类的实例对象。表中的一行一行的信息我们称之为记录。
l 常见的数据库管理系统
MYSQL :开源免费的数据库,小型的数据库.已经被Oracle收购了.MySQL6.x版本也开始收费。
Oracle :收费的大型数据库,Oracle公司的产品。Oracle收购SUN公司,收购MYSQL。
DB2 :IBM公司的数据库产品,收费的。常应用在银行系统中.
SQLServer:MicroSoft 公司收费的中型的数据库。C#、.net等语言常使用。
SyBase :已经淡出历史舞台。提供了一个非常专业数据建模的工具PowerDesigner。
SQLite : 嵌入式的小型数据库,应用在手机端。
常用数据库:MYSQL Oracle
这里使用MySQL数据库。MySQL中可以有多个数据库,数据库是真正存储数据的地方。
数据库是不认识JAVA语言的,但是我们同样要与数据库交互,这时需要使用到数据库认识的语言SQL语句,它是数据库的代码。
结构化查询语言(Structured Query Language)简称SQL,是关系型数据库管理系统都需要遵循的规范。不同的数据库生产厂商都支持SQL语句,但都有特有内容。
普通话:各数据库厂商都遵循的ISO**标准。**
方言:数据库特有的关键字,**语法。**
SQL分类:
数据定义语言:简称DDL(Data Definition Language),用来定义数据库中的对象:数据库,表,列等。关键字:create,alter,drop, show等
数据操作语言:简称DML(Data Manipulation Language),用来对数据库中表的记录进行更新。关键字:insert,delete,update等
数据控制语言:简称DCL(Data Control Language),用来定义数据库的访问权限和安全级别,及创建用户。
数据查询语言:简称DQL(Data Query Language),用来查询数据库中表的记录。关键字:select,from,where等
SQL语句可以单行或多行书写,以分号结尾
可使用空格和缩进来增强语句的可读性
MySQL数据库的SQL语句不区分大小写,关键字建议使用大写
例如:SELECT * FROM user。
同样可以使用/**/的方式完成注释 在Sqlyog中也可以是 #或者- -注释一行
MySQL中的我们常使用的数据类型如下
类型 | 描述 |
---|---|
int | 整数 |
double | 浮点数 |
varchar | 字符串 |
date | 日期,格式为yyyy-MM-dd 只有年月日 |
其他数据类型
分类 | 类型名称 | 说明 |
---|---|---|
整数类型 | tinyInt | 很小的整数 |
smallint | 小的整数 | |
mediumint | 中等大小的整数 | |
int(integer) | 普通大小的整数 | |
小数类型 | float | 单精度浮点数 |
double | 双精度浮点数 | |
decimal(m,d) | 压缩严格的定点数 decimal(10,2) 一共10位,小数2位 | |
日期类型 | year | YYYY 1901~2155 |
time | HH:MM:SS -838:59:59~838:59:59 | |
date | YYYY-MM-DD 1000-01-01~9999-12-3 | |
datetime | YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00~ 9999-12-31 23:59:59 | |
timestamp | YYYY-MM-DD HH:MM:SS 1970~01~01 00:00:01 UTC~2038-01-19 03:14:07UTC | |
文本、二进制类型 | CHAR(M) | M为0~255之间的整数定长 char(10) tom |
VARCHAR(M) | M为0~65535之间的整数变长 varchar(10) tom | |
TINYBLOB | 允许长度0~255字节 | |
BLOB | 允许长度0~65535字节 | |
MEDIUMBLOB | 允许长度0~167772150字节 | |
LONGBLOB | 允许长度0~4294967295字节 | |
TINYTEXT | 允许长度0~255字节 | |
TEXT | 允许长度0~65535字节 | |
MEDIUMTEXT | 允许长度0~167772150字节 | |
LONGTEXT | 允许长度0~4294967295字节 | |
VARBINARY(M) | 允许长度0~M个字节的变长字节字符串 | |
BINARY(M) | 允许长度0~M个字节的定长字节字符串 |
操作数据库,表列
C(Create) 创建 , R(Retrieve) 查询, U(update) 修改, D(delete)删除;
用数据库默认的字符集创建数据库:
create database 数据库名;
可以使用if来判断一下
create database if not exists 数据库名
可以在创建数据库时指定字符集
create database 数据库名 character set gbk;
也可以和if语句连用
create database if not exists 数据库名 character set gbk;
查看数据库MySQL服务器中的所有的数据库:
show databases;
查看某个数据库的定义的信息:
show create database 数据库名; 查看某个数据库的字符集和创建语句
删除数据库
drop database 数据库名称;
删除前可以用if判断是否存在
drop database if exists 数据库名;
(切换数据库)
显示正在使用的数据库
select database();
切换数据库:
use 数据库名;
修改数据库的字符集
alter database 数据库名 character set 字符集名;
创建一个表
create table 表名( 字段名 类型(长度) [约束], 字段名 类型(长度) [约束], ... );
最后一列不加逗号
类型: varchar(n) 字符串 一个中文转一个字符, 一个字母也占一个字符 int 整形 double 浮点 date 时间 timestamp 时间戳
如果将来不给timestamp 字段赋值,或者赋值为null,则默认使用当前的系统时间,自动赋值;
约束(后期讲解,现在先知道): primary key 主键,被主键修饰字段中的数据,不能重复、不能为null。###创建分类表
例如:
CREATE TABLE category ( cid INT primary key, #分类ID cname VARCHAR(100) #分类名称 ); ###创建分类表 CREATE TABLE category ( cid INT primary key, #分类ID cname VARCHAR(100) #分类名称 );
查看所有的表
格式:show tables;
查看表结构
格式: desc 表名;
删除表
格式: drop table 表名; 例如: drop table category;
修改表
alter table 表名 rename to 新表名; rename table 表名 to 新表名; 作用:修改表名 例如: 分类表category改名成 category2 RENAME TABLE category TO category2;
修改标的字符集
alter table 表名 character set 字符集名;
(主要是操作表中的列):
修改表--添加列
alter table 表名 add 列名 类型(长度) [约束]; 例如: 1,为分类表添加一个新的字段为分类描述 varchar(20) ALTER TABLE category ADD `desc` VARCHAR(20);
修改表--删除列
alter table 表名 drop 列名;
例如: #4, 删除分类表中snamename这列 ALTER TABLE category DROP description;
修改表--修改列名和属性
alter table 表名 change 旧列名 新列名 类型(长度) 约束; alter table 表名 modify 列名 新数据类型
修改列的类型长度及约束
alter table 表名 modify 列名 类型(长度) 约束;
修改表的字符集
alter table 表名 character set 字符集;(一般不修改);
查看表结构中的列
desc 表名;
1.primary key 主键,值唯一,并且不能为空 2.auto_increment 自动增长,数据可以由MySql自己维护
向表中插入某些字段
insert into 表 (字段1,字段2,字段3..) values (值1,值2,值3..);
向表中插入所有字段,字段的顺序为创建表时的顺序
insert into 表 values (值1,值2,值3..);
注意:
值与字段必须对应,个数相同,类型相同
值的数据大小必须在字段的长度范围内
除了数值类型外,其它的字段类型的值必须使用引号引起。(建议单引号)
如果要插入空值,可以不写字段,或者插入 null
用来修改指定条件的数据,将满足条件的记录指定列修改为指定值
更新所有记录的指定字段(列名)
update 表名 set 字段名=值,字段名=值,...; 如果不添加条件默认修改所有的值
更新符号条件记录的指定字段
update 表名 set 字段名=值,字段名=值,... where 条件;
l 注意:
列名的类型与修改的值要一致.
修改值得时候不能超过最大长度.
除了数值类型外,其它的字段类型的值必须使用引号引起
删除记录方式1
delete from 表名 where 条件; 1.如果不加where则删除表中所有的记录
删除记录方式2
truncate table 表名; #先删除表再创建一模一样的空表.(名称与结构).
删除表中所有记录使用delete from 表名; 还是用truncate table 表名;
删除方式:delete 一条一条删除,不清空auto_increment记录数。
truncate 直接将表删除,重新建表,auto_increment将置为零,从新开始。
我们在dos命令行操作中文时,会报错
insert into category(cid,cname) values(‘c010’,’中文’); ERROR 1366 (HY000): Incorrect string value: '\xB7\xFE\xD7\xB0' for column 'cname' at row 1
解决方案1:在cmd命令窗口中输入命令,此操作当前窗口有效,为临时方案1
set names gbk;
决方案2:安装目录下修改my.ini文件,重启服务所有地方生效。[不建议]
查看MySQL内部设置的编码
show variables like 'character%'; 查看所有mysql的编码
修改client、connection、results的编码一致(GBK编码)client connetion result 和客户端保持一致,都为GBK
将客户端编码修改为gbk #方式1:单独设置 set character_set_client=gbk; set character_set_connection=gbk; set character_set_results=gbk; #方式2:快捷设置 set names gbk;
1.1简单查询
select -> from -> where -> group by -> having -> order by -> limit; 字段列表 表名列表 条件列表 分组字段 分组后的条件 排序 分页限定
查询所有的表信息.
select * from 表名; *表示所有字段
查询表中字段的信息.
select 字段1,字段2 from 表名;
去掉重复值
select distinct 字段 from 表名;
.查询结果是表达式(运算查询)
select 字段1,字段2+10 from 表名; # 字段2的每个数据加10;
字段在使用运算符是
select * (字段1+字段2) 别名 from 表名;
别名查询.使用的关键字是as(as可以省略的)
select * from 表名 as 别名;
ifnull的使用
ifnull(字段,设置的值); #字段如果为null替换成后面的值.
比较运 算符 | > < <= >= = <> != | 大于、小于、大于(小于)等于、不等于 |
---|---|---|
BETWEEN ...AND... | 显示在某一区间的值(含头含尾)(也可以是日期) | |
IN(set) | 显示在in列表中的值,例:in(100,200) | |
LIKE ‘张%’ | 模糊查询,Like语句中, %代表零个或多个任意字符, _代表一个字符, 例如:first_name like ‘_a%’; | |
IS NULL /IS NOT NULL | 判断为空/不为空 where name IS NULL 和name = ‘’ | |
逻辑运算符 | and | 多个条件同时成立 |
or | 多个条件任一成立 | |
not | 不成立,例:where not(salary>100); |
查询表中字段值为“查询的数据”的表中的所有信息:
SELECT * FROM 表名 WHERE 字段名 = '要查询的东西'
null值不能有比较运算符判断.
SQL分类:
DDL:操作数据库和表
DML:增删改表中数据
DQL:查询表中数据
DCL:管理用户,授权
DBA:数据库管理员
DCL:管理用户,授权
添加用户:
* 语法:CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
删除用户:
* 语法:DROP USER '用户名'@'主机名';
修改用户密码:
UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';# 此方法设置后需重启mysql服务才能生效. UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi'; SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码'); SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123'); * mysql中忘记了root用户的密码? 1. cmd -- > net stop mysql 停止mysql服务 * 需要管理员运行该cmd 2. 使用无验证方式启动mysql服务: mysqld --skip-grant-tables 3. 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功 4. use mysql; 5. update user set password = password('你的新密码') where user = 'root'; 6. 关闭两个窗口 7. 打开任务管理器,手动结束mysqld.exe 的进程 8. 启动mysql服务 9. 使用新密码登录。
查询用户:
-- 1. 切换到mysql数据库 USE myql; -- 2. 查询user表 SELECT * FROM USER;
* 通配符: % 表示可以在任意主机使用用户登录数据库
查询权限:
-- 查询权限 SHOW GRANTS FOR '用户名'@'主机名'; SHOW GRANTS FOR 'lisi'@'%';
授予权限:
-- 授予权限 grant 权限列表 on 数据库名.表名 to '用户名'@'主机名'; -- 给张三用户授予所有权限,在任意数据库任意表上
GRANT ALL ON *.* TO 'zhangsan'@'localhost';
撤销权限:
-- 撤销权限: revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名'; REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%';
通过order by语句,可以将查询出的结果进行排序。放置在select语句的最后。
格式;
SELECT * FROM 表名 ORDER BY 排序字段 排序规则; SELECT * FROM 表名 ORDER BY 排序字段1 排序规则,排序字段2 排序规则,排序字段3 排序规则; ASC 升序 (默认) DESC 降序 如果字段1相同就用字段2 如果有多个排序条件,则但前边的条件值一样时,才会判断第二个字段
之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,他是对查询后的结果的列进行计算,然后返回一个单一的值;另外聚合函数会忽略空值。
今天我们学习如下五个聚合函数:
count:统计指定列不为NULL的记录行数;count(*)表示任意不为空的count(1)
sum:计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
max:计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
min:计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
avg:计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;
聚合函数会排除null值.
查询商品的总条数 SELECT COUNT(*) FROM 表名; count(*)和count(1)效果一样,但是比count(*)快. #2 查询价格大于200商品的总条数 SELECT COUNT(*) FROM product WHERE price > 200; #3 查询分类为'c001'的所有商品价格的总和 SELECT SUM(price) FROM product WHERE category_id = 'c001'; #4 查询分类为'c002'所有商品的平均价格 SELECT AVG(price) FROM product WHERE category_id = 'c002'; 5 查询商品的最大价格和最小价格 SELECT MAX(price),MIN(price) FROM product; ifnull可以嵌套使用,count(ifnull(字段,值));
分组查询是指使用group by字句对查询信息进行分组。
格式
SELECT 字段1,字段2… FROM 表名GROUP BY分组字段 HAVING 分组条件;
注意: 分组后查询的字段: 要么是分组字段,要么是聚合函数,
分组操作中的having子语句,是用于在分组后对数据进行过滤的,作用类似于where条件。
having与where的区别:
having是在分组后对数据进行过滤.
where是在分组前对数据进行过滤
having后面可以使用聚合函数过滤数据
where后面不可以使用聚合函数
分页查询在项目开发中常见,由于数据量很大,显示屏长度有限,因此对数据需要采取分页显示方式。例如数据共有30条,每页显示5条,第一页显示1-5条,第二页显示6-10条。
格式
SELECT 字段1,字段2... FROM 表名 LIMIT M,N M: 整数,表示从第几条索引开始,计算方式 (当前页-1)*每页显示条数 N: 整数,表示每页查询多少条数据 SELECT 字段1,字段2... FROM 表名 LIMIT 0,5 SELECT 字段1,字段2... FROM 表名 LIMIT 5,5 limit 是MySQL的方言;
添加数据完整性=添加表约束
分类:实体完整性,域完整性,引用完整性 实体完整性: 对数据行的约束,比如:主键约束,唯一约束
域完整性: 对数据列的约束,比如:该列的数据类型, 默认约束,非空约束
引用完整性: 外键约束(多表的关系)
PRIMARY KEY 约束唯一标识数据库表中的每条记录每条记录中被主键约束约束的字段不能相同。
主键非空且唯一 必须是唯一的值。主键列不能是 NULL 值。每个表都应该有且只能有一个主键。
方式一:创建表时,在字段描述处,声明s指定字段为主键:
CREATE TABLE Persons( Id_P int PRIMARY KEY, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255) );
方式二:创建表时,在constraint约束区域,声明指定字段为主键:
CREATE TABLE Persons( FirstName varchar(255), LastName varchar(255), Address varchar(255), City varchar(255), CONSTRAINT pk_PersonID PRIMARY KEY (FirstName,LastName) ); 或者 CREATE TABLE Persons( FirstName varchar(255), LastName varchar(255), Address varchar(255), City varchar(255), PRIMARY KEY (FirstName) );
l 方式三:创建表之后,通过修改表结构,声明指定字段为主键:
ALTER TABLE 表名 ADD [CONSTRAINT 名称] PRIMARY KEY (字段列表) ALTER TABLE 表名 modify 字段 类型 PRIMARY KEY;
create table peroon( FirstName varchar(255), LastName varchar(255), Address varchar(255), City varchar(255) ); ALTER TABLE Persons ADD PRIMARY KEY (FirstName);
如需撤销 PRIMARY KEY 约束,请使用下面的 SQL:
ALTER TABLE 表名 DROP PRIMARY KEY
我们通常希望在每次插入新记录时,数据库自动生成字段的值。
我们可以在表中使用 auto_increment(自动增长列)关键字,自动增长列类型必须是整形,自动增长列必须为键(一般是主键)。
下列 SQL 语句把 "Persons" 表中的 "P_Id" 列定义为 auto-increment 主键
CREATE TABLE Persons( P_Id int PRIMARY KEY AUTO_INCREMENT, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255) );
向persons添加数据时,可以不为P_Id字段设置值,也可以设置成null,数据库将自动维护主键值
INSERT INTO Persons (FirstName,LastName) VALUES ('Bill','Gates') INSERT INTO Persons (P_Id,FirstName,LastName) VALUES (NULL,'Bill','Gates')
delete和truncate的区别
Delete删除表中的数据,但不重置auto-increment记录数。 Truncate删除表中的数据,auto-increment记录数将重置。Truncate其实先删除表然后再创建表。
扩展:默认地,AUTO_INCREMENT 的开始值是 1,如果希望修改起始值,请使用下列 SQL 语法:
ALTER TABLE 表名 AUTO_INCREMENT=100
NOT NULL 约束强制列不接受 NULL 值。
NOT NULL 约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新记录或者更新记录。
方式一:创建表,下面的 SQL 语句强制 "Id_P" 列和 "LastName" 列不接受 NULL 值:
CREATE TABLE Persons( Id_P int NOT NULL, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255) );
方式二:修改表结构
添加非空约束 ALTER TABLE student MODIFY LastName varchar(255) NOT NULL alter table 表名 change 旧列名 新列名 类型(长度) 约束;
删除非空约束 ALTER TABLE student MODIFY LastName varchar(255)
UNIQUE 约束唯一标识数据库表中的每条记录。
UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。
PRIMARY KEY 拥有自动定义的 UNIQUE 约束。请注意,每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束
与主键添加方式相同,共有3种,
方式1:创建表时,在字段描述处,声明唯一:
CREATE TABLE Persons( Id_P int UNIQUE, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255) );
方式2:创建表时,在约束区域,声明唯一
CREATE TABLE Persons( Id_P int, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255), CONSTRAINT 名称UNIQUE (Id_P) );
方式3:创建表后,修改表结构,声明字段唯一:
ALTER TABLE 表名 ADD [CONSTRAINT 名称] UNIQUE (Id_P)
方式4 修改唯一约束, 修改之前要保证修改的字段的值徐唯一.
ALTER TABLE 表名 modify 字段名 类型 UNIQUE;
如需撤销 UNIQUE 约束,请使用下面的 SQL
ALTER TABLE 表名 DROP INDEX 约束名称
如果添加唯一约束时,没有设置约束名称,默认是当前字段的字段名。
唯一约束与主键约束的区别:
主键:唯一、不能为空、一个表只能有一个主键,非业务数据
唯一:唯一、可以有空值,但只能有一个空值。一个表可以有多个唯一约束。
唯一约束可以有多个null值.
在添加数据中,如果该字段不指定值,采用默认值处理
方式一: 创建表,字段处声明
CREATE TABLE Persons( Id_P int, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255) DEFAULT '北京', City varchar(255) );
方式二: 修改表结构
ALTER TABLE Persons MODIFY Address VARCHAR(255) DEFAULT '北京'
删除默认约束ALTER TABLE Persons MODIFY Address VARCHAR(255)
实际开发中,一个项目通常需要很多张表才能完成。例如:一个商城项目就需要分类表(category)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系,接下来我们将在单表的基础上,一起学习多表方面的知识。
有3类表关系:一对多(多对一)、多对多、一对一(了解)
一对多关系: 从表的外键即使主键
常见实例:学生和考试成绩(画图),客户和订单,分类和商品,部门和员工.
一对多建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键.
多对多关系:
常见实例:学生和教师,商品和订单(画图),学生和课程、用户和角色
多对多关系建表原则:需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键.
一对一关系:(了解)
在实际的开发中应用不多,比如QQ号码,和QQ用户信息
因为一对一可以创建成一张表.
两种建表原则:
外键唯一:主表的主键和从表的外键(唯一),形成主外键关系,外键唯一unique。
外键是主键:主表的主键和从表的主键,形成主外键关系。
我们通过主表的主键和从表的外键来描述主外键关系,呈现就是一对多关系。
外键特点:
从表外键的值是对主表主键的引用。
从表外键类型,必须与主表主键类型一致。
声明外键约束:
alter table 从表 add constraint 外键名称 foreign key (从表外键字段名) references 主表 (主表的主键); [外键名称] 用于删除外键约束的,一般建议“_fk”结尾 ALTER TABLE 从表 ADD [CONSTRAINT] [外键约束名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主 键字段名);
创建表示添加
create table 表名( 字段 类型 约束 ..., constraint 外键名称 foreign key (外键名称) references 主表名称(主表需要成为主键的列) [CONSTRAINT] [外键约束名称] FOREIGN KEY(外键字段名) REFERENCES 主表名(主键字段名) );
使用外键目的:保证数据完整性
外键的删除
alter table 从表 drop foreign key 外键名称
操作两个关联的表示可以使用级联操作,
ALTER TABLE 从表 ADD [CONSTRAINT] [外键约束名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主 键字段名) on update cascade on delete cascade;
级联更新和级联删除
级联更新: ON UPDATE CASCADE
级联删除: ON DELETE CASCADE
一对多(1:n) 例如:班级和学生,部门和员工,客户和订单,分类和商品
一对多建表原则: 在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键
笛卡尔积是指两个集合A,B,去这两个集合的所以组成情况,
要完成多表查询想要消除无用数据,使用以下三种方式.
交叉连接查询(基本不会使用-得到的是两个表的乘积) [笛卡尔积]
语法:select * from A,B;
内连接查询(使用的关键字 inner join -- inner可以省略)
隐式内连接:
select 字段列表1,字段2 from 表A,表B where 条件;
显示内连接:执行效率要高
select 字段列表1,字段2 from 表名1 [inner] join 表名2 on 条件;
注意事项
确定要查询的表
确定条件
确定要查询的字段
外连接查询(使用的关键字 outer join -- outer可以省略) 写在左边的是左表,写在右边的是右表
左外连接:left outer join 查询的是做表所有数据以及其交集部分
select * from 表A left [outer] join 表B on 条件;
右外连接:right outer join 查询的是右表所有数据以及其交集的部分
select * from A right outer join B on 条件;
子查询:一条select语句结果作为另一条select语法一部分(查询条件,查询结果,表等)。
select ....查询字段 ... from ...表.. where ... 查询条件
子查询的结果是单行单列的:
子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =
-- 查询员工工资小于平均工资的人
SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
子查询的结果是多行单列的:
子查询可以作为条件,使用运算符in来判断 -- 查询'财务部'和'市场部'所有的员工信息 SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部'; SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2; -- 子查询 SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');
子查询的结果是多行多列的:
子查询可以作为一张虚拟表参与查询 -- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息 -- 子查询 SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.join_date
> '2011-11-11') t2 WHERE t1.id = t2.dept_id;
(1) SELECT (2) DISTINCT(3) FROM (4) JOIN (5) ON (6) WHERE (7) GROUP BY (8) HAVING (9) ORDER BY (10) LIMIT
内连
内连接:只列出匹配的记录
语法:
SELECT … FROM 表1 [INNER] JOIN 表2 [ON join_condition] WHERE where_definition 解释:只列出这些连接表中与连接条件相匹配的数据行。INNER可以不写,则默认为内连接。[ON join_condition]里面写的是连接的条件
外连接分类:
左外连接(LEFT [OUTER] JOIN)
右外连接(RIGHT [OUTER] JOIN)
全外连接(FULL [OUTER] JOIN) 注:MySQL5.1的版本暂不支持
语法:
SELECT … FROM 表1 (LEFT | RIGHT | FULL) [OUTER] JOIN 表2 ON join_condition WHERE where_definition 不仅列出与连接条件(on)相匹配的行,还列出左表table1(左外连接)、或右表table2(右外连接)、或两个表(全外连接)中所有符合WHERE过滤条件的数据行。一般都是用左连接或者外连接。 其中,[OUTER]部分可以不写,(LEFT | RIGHT | FULL)部分要写其中一个。
1左外连接:左表列出全部,右表只列出匹配的记录
2右外连接:右表列出全部,左表只列出匹配的记录。
交叉连接:
语法;
SELECT … FROM join_table1 CROSS JOIN join_table2; 没有ON子句和WHERE子句,它返回的是连接表中所有数据行的笛卡尔积。 笛卡尔积举例:假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)} 其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数
自连接:参与连接的表都是同一张表。(通过给表取别名虚拟出两张表)
语法:
:非常重要,在JavaWeb中的目录树中用的特别多。
索引是数据库中用来提高查询性能的最常用工具。
所有MySQL列类型都可以被索引,对相关列使用索引是提高SELECT操作性能的最佳途径。索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。
这是最基本的索引类型,而且它没有唯一性之类的限制。普通索引可以通过以下几种方式创建: (1)创建索引,例如CREATE INDEX 索引的名字 ON tablename (列名1,列名2,...); (2)修改表,例如ALTER TABLE tablename ADD INDEX 索引的名字 (列名1,列名2,...); (3)创建表的时候指定索引,例如CREATE TABLE tablename ( [...], INDEX 索引的名字 (列名1,列名 2,...) );
方式一:直接创建索引:
CREATE INDEX 索引名 ON 表名(列名[(length)]…);
方式二:修改表时添加索引
ALTER TABLE 表名 ADD INDEX [索引名] (列名[(length)]…);
方式三:创建表的时候指定索引:
CREATE TABLE 表名 ( 表名 ( [...], INDEX [索引名] (列名[(length)]…);
注意:如果要创建索引的列的类型是CHAR、VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定length。
这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一。唯一性索引可以用以下几种方式创建: (1)创建索引,例如CREATE UNIQUE INDEX 索引的名字 ON tablename (列的列表); (2)修改表,例如ALTER TABLE tablename ADD UNIQUE 索引的名字 (列的列表); (3)创建表的时候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE 索引的名字 (列的列 表) );
主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。如果你曾经用过AUTO_INCREMENT类型的列,你可能已经熟悉主键之类的概念了。主键一般在创建表的时候指定,例如“CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); ”。但是,我们也可以通过修改表的方式加入主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每个表只能有一个主键。 (主键相当于聚合索引,是查找最快的索引)
MySQL从3.2版开始支持全文索引和全文检索。在MySQL中,全文索引的索引类型为FULLTEXT。 MySQL5.0版本只有MyISAM存储引擎支持FULLTEXT,并且只限于CHAR、VARCHAR和TEXT类型的列上创建。 注:全文索引维护起来很吃力,所以了解即可。 创建方式和上方的普通索引类似。即:将普通索引的“index”改为“fulltext index”。
一般使用“删除”,不使用“禁用”。 删除索引: 语法: DROP INDEX 索引名 ON 表名 对于MyISAM表在做数据大批量导入时,它会边插入数据边建索引。所以为了提高执行效率,应该先禁用索引,在完全导入后,再开启索引。而InnoDB表对索引都是单独处理的,无需禁用索引。 禁用索引: ALTER TABLE 表名 DISABLE KEYS; 打开索引: ALTER TABLE 表名 ENABLE KEYS;
问题1:mysql索引类型normal,unique,full text的区别是什么?
normal:表示普通索引 unique:表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用作索引时,可设置为unique full textl: 表示 全文搜索的索引。 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。 总结,索引的类别由建立索引的字段内容特性来决定,通常normal最常见。
概念:
如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
操作:
开启事务: start transaction;
回滚:rollback;
提交:commit;
例子:
CREATE TABLE account ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(10), balance DOUBLE );
-- 添加数据 INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
SELECT * FROM account; UPDATE account SET balance = 1000; -- 张三给李四转账 500 元 -- 0. 开启事务 START TRANSACTION; -- 1. 张三账户 -500 UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan'; -- 2. 李四账户 +500 -- 出错了... UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi'; -- 发现执行没有问题,提交事务 COMMIT; -- 发现出问题了,回滚事务 ROLLBACK;
MySQL数据库中事务默认自动提交
事务提交的两种方式: * 自动提交: * mysql就是自动提交的 * 一条DML(增删改)语句会自动提交一次事务。
手动提交: * Oracle 数据库默认是手动提交事务
需要先开启事务,再提交 * 修改事务的默认提交方式: * 查看事务的默认提交方式:SELECT @@autocommit; -- 1 代表自动提交 0 代表手动提交 * 修改默认提交方式: set @@autocommit = 0;
事务的四大特征:
原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
持久性:当事务提交或回滚后,数据库会持久化的保存数据。
隔离性:多个事务之间。相互独立。
一致性:事务操作前后,数据总量不变
事务的隔离级别(了解)
概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
存在问题:
脏读:一个事务,读取到另一个事务中没有提交的数据
不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
隔离级别:
read uncommitted:读未提交
产生的问题:脏读、不可重复读、幻读
read committed:读已提交 (Oracle)
产生的问题:不可重复读、幻读
repeatable read:可重复读 (MySQL默认)
产生的问题:幻读
serializable:串行化
可以解决所有的问题
注意:隔离级别从小到大安全性越来越高,但是效率越来越低
数据库查询隔离级别:
select @@tx_isolation;
数据库设置隔离级别:
set global transaction isolation level 级别字符串;
演示: set global transaction isolation level read uncommitted; start transaction; -- 转账操作 update account set balance = balance - 500 where id = 1; update account set balance = balance + 500 where id = 2;
分类:
一对一(了解):
* 如:人和身份证 * 分析:一个人只有一个身份证,一个身份证只能对应一个人
一对多(多对一):
* 如:部门和员工 * 分析:一个部门有多个员工,一个员工只能对应一个部门
多对多:
* 如:学生和课程 * 分析:一个学生可以选择很多门课程,一个课程也可以被很多学生选择
实现关系:
一对多(多对一):
* 如:部门和员工 * 实现方式:在多的一方建立外键,指向一的一方的主键。
多对多:
* 如:学生和课程 * 实现方式:多对多关系实现需要借助第三张中间表。中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键
一对一(了解):
* 如:人和身份证 * 实现方式:一对一关系实现,可以在任意一方添加唯一外键指向另一方的主键。
案列;
-- 创建旅游线路分类表 tab_category -- cid 旅游线路分类主键,自动增长 -- cname 旅游线路分类名称非空,唯一,字符串 100 CREATE TABLE tab_category ( cid INT PRIMARY KEY AUTO_INCREMENT, cname VARCHAR(100) NOT NULL UNIQUE ); -- 创建旅游线路表 tab_route /* rid 旅游线路主键,自动增长 rname 旅游线路名称非空,唯一,字符串 100 price 价格 rdate 上架时间,日期类型 cid 外键,所属分类 */ CREATE TABLE tab_route( rid INT PRIMARY KEY AUTO_INCREMENT, rname VARCHAR(100) NOT NULL UNIQUE, price DOUBLE, rdate DATE, cid INT, FOREIGN KEY (cid) REFERENCES tab_category(cid) ); /*创建用户表 tab_user uid 用户主键,自增长 username 用户名长度 100,唯一,非空 password 密码长度 30,非空 name 真实姓名长度 100 birthday 生日 sex 性别,定长字符串 1 telephone 手机号,字符串 11 email 邮箱,字符串长度 100 */ CREATE TABLE tab_user ( uid INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(100) UNIQUE NOT NULL, PASSWORD VARCHAR(30) NOT NULL, NAME VARCHAR(100), birthday DATE, sex CHAR(1) DEFAULT '男', telephone VARCHAR(11), email VARCHAR(100) ); /* 创建收藏表 tab_favorite rid 旅游线路 id,外键 date 收藏时间 uid 用户 id,外键 rid 和 uid 不能重复,设置复合主键,同一个用户不能收藏同一个线路两次 */ CREATE TABLE tab_favorite ( rid INT, -- 线路id DATE DATETIME, uid INT, -- 用户id -- 创建复合主键 PRIMARY KEY(rid,uid), -- 联合主键 FOREIGN KEY (rid) REFERENCES tab_route(rid), FOREIGN KEY(uid) REFERENCES tab_user(uid) );
数据库设计的范式
概念:设计数据库时,需要遵循的一些规范。要遵循后边的范式要求,必须先遵循前边的所有范式要求
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。 目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
分类:
第一范式(1NF):每一列都是不可分割的原子数据项
第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)
几个概念:
函数依赖:A-->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A 例如:学号-->姓名。 (学号,课程名称) --> 分数
完全函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定需要依赖于A属性组中所有的属性值。 例如:(学号,课程名称) --> 分数
部分函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定只需要依赖于A属性组中某一些值即可。 例如:(学号,课程名称) -- > 姓名
传递函数依赖:A-->B, B -- >C . 如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,则称 C 传递函数依赖于A 例如:学号-->系名,系名-->系主任
码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码 例如:该表中码为:(学号,课程名称)
主属性:码属性组中的所有属性
非主属性:除过码属性组的属性
第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
命令行备份数据库
还原数据库
1.登录数据集 2.创建数据库 3.使用数据库 4. 执行文件 source sql 文件保存的路径