常见关系化数据库有哪些?
收费产品
免费产品
SQL Server : 微软公司产品,中等规模数据库 收费产品,运行在windows平台上 ----- .net平台 + SQLServer 进行开发
Oracle : 甲骨文公司产品,大型商业数据库,收费 可以运行在任何操作系统上 windows linux ---- Oracle收购sun(Java) ---- Java + Oracle
MySQL :最初是一个开源免费数据库产品 ,中小型数据库 ------互联网行业主流数据库 Mysql被Oracle收购后,Mysql 6.0开始推出收费版本---- 企业主流5.X
DB2 : IBM产品 大型数据库 ---- BEA 被Oracle收购 weblogic+ Oracle ----- websphere + DB2
SYBASE:收费,中型数据库,银行证券 ----- PowerDesigner PD (数据库设计建模软件)
HSQL : 迷你数据库 开源免费,纯java开发 ----- 被java开源框架内置使用
SQLITE : 嵌入式开发,Android 内部主要数据库 ---- 开源免费
下载Mysql ----- Oracle网站、开源社区下载
版本:5.X版本(5.0 、5.5 )
安装MySQL
卸载
1、在控制面板 卸载mysql程序
2、手动删除mysql目录
安装
1、安装mysql ---- 可以修改安装路径
2、安装结束后,一定要对mysql进行配置
修改mysql默认字符集 Latin1(就是ISO-8859-1) ---- 设置utf-8
将mysql安装为window服务 ---- 即通过服务启动mysql数据库 ---勾选
将mysql/bin 放入环境变量path ----- 勾选
设置mysql超级管理员 root 用户密码
3、安装mysql后,通过运行 输入services.msc(MySQL服务启动,mysql数据库就启动了)
* 在每次使用mysql之前必须启动mysql服务
4、在cmd窗口输入: mysql -? 如果命令识别,证明mysql/bin 已经放入环境变量path
5、连接mysql数据 :
cmd窗口输入:mysql -u root -p
Enter password: ****
重置root密码(忘记密码)
1.停止mysql服务(通过运行 输入services.msc)
2.在cmd窗口输入: mysqld-nt --skip-grant-tables (窗口阻塞,不要关闭)
3.另起一个cmd窗口输入:mysql -u root -p不需要输入密码(回车即可)就可以登录。
mysql> use mysql;
mysql> update user set password=password('新密码') where user='root';
mysql> quit;
4、关闭步骤2.中的cmd窗口并且打开任务管理器关闭进程mysqld-nt.exe
5、重启mysql服务
安装mysql后,自带两个数据库 mysql、test
mysql 存放数据库核心数据 ----- 用户、权限 ...
test 练习数据库, 默认该数据库是空的
mysql数据库组成
1、在mysql数据库软件内部可以创建和使用多个数据库( database)
2、在每一个数据库(database)中可以创建和使用多个数据表( table)
3、table存放数据记录,一条数据记录,对应java程序中的一个对象
4、在数据库中存在很多用户,用户根据相应权限操作数据库或者数据表
SQL 结构化查询语言
1、SQL是非过程性语言 ----- 每一条SQL语句都是独立执行的,没有先后依赖关系
int a = 10;
int b = 20;
int c = a+b;
print(c) ;
上面程序是典型过程性语言
2、SQL是官方提供的数据库标准语言 ---- 任何数据库都必须支持SQL语法
* 每个数据都应该提供sql扩展,增强sql过程化编程(例如Oracle的PL/SQL)
3.SQL分类:数据定义语言 DDL 、数据操纵语言 DML 、数据控制语言 DCL
有人将select查询语句自成一类 数据查询语言 DQL
DDL:数据定义语言 用来定义数据库的对象,如数据表、视图、索引等
DML:数据操纵语言 在数据库表中更新,增加和删除记录,如 update, insert, delete
DCL:数据控制语言 指用于设置用户权限和控制事务语句,如grant,revoke,if…else,while,begin transaction
DQL:数据查询语言 select查询语句
SQL语句使用:数据库操作SQL 、数据表(表结构)操作SQL 、数据记录操作SQL
第一部分:数据库 SQL
1、数据库创建 create database 数据库名称;
创建一个名称为mydb1的数据库 ----- create database mydb1;
* 通过show databases; 查看所有数据库
在创建数据库时,还可以为数据库指定字符集及字符集比较方式 ---- 语法: create database 数据库名称 character set 编码集 collate 比较方式;
* 如果不指定字符集和比较方式,使用默认值 --- 修改utf-8
---------------------------------------
mysql安装目录
bin ---- mysql执行程序
docs ---- 文档
share --- 各国编码信息
data ---- 存放mysql 数据文件
*ibdata1存放mysql中所有数据表的数据记录
* 每个数据库 创建一个同名文件夹,.frm 存放table表结构、db.opt 存放数据默认编码集
* win7 数据库文件夹默认 C:\ProgramData\MySQL\MySQL Server 5.5\data
---------------------------------------
创建一个使用utf8字符集的mydb2数据库 ----- create database mydb2 character set utf8;
创建一个使用utf8字符集,并带校对规则的mydb3数据库 ----- create database mydb3 character set utf8 collate utf8_unicode_ci;
* 什么是校对规则? 用于排序 对张三和李四排序,按照拼音排序、按照笔画排序,按照名字数量
* 一个字符集对应很多校对规则
2、查看和删除数据库
查看数据库的创建信息(编码集和比较方式):show create database 数据库名; 例如 show create database mydb2;
删除数据库:drop database 数据库名称; 例如 drop database mydb1;
3、修改数据库编码
语法: alter database 数据库名称 character set 编码集; 例如:alter database mydb2 character set gbk;
4、切换数据库
切换到指定数据库 : use 数据库名称;
查看当前正在使用数据库: select database();
第二部分:数据表table ---- 表结构SQL
1、创建数据表: create table 表名(列名 类型(长度),列名 类型(长度) ...)character set 字符集 collate 校对规则;
* 如果不设置编码集,数据表将采用数据库默认字符集
create table users(
id int,
name varchar(40),
password varchar(40),
birthday date
);
* 所有数据类型中,除了char 、varchar 必须指定长度,其它类型默认长度
数据库类型
1) 整数类型 tinyint (byte) smallint(short) int(int) bigint(long) float double
2) 字符串类型 varchar(变长字符串) char(定长字符串) 长度取值0-255 对应java中的String
varchar变长 varchar(20) 向数据库存入hello ,因为变长,长度会根据保存内容自动调整
char定长 char(8) 向数据库存入hello 因为定长 保存hello + 3个空格
* varchar经常使用,char性能更好
3) 逻辑型 bit 一位 对应java中的boolean
*bit(8)表示8位 相当于tinyint(byte)类型 ,bit(32) 相当于int(int) 类型
4) 日期型 date time datetime timestamp
date 只能保存日期
time 只能保存时间
datetime 日期和时间都有
timestamp 日期和时间都有,可以自动更新 ---- 当操作数据表时,timestamp字段会自动更新当前时间
5) 大数据类型 text、blob
text 文本类型数据,主要存储字符文件 -----文本文件
blob 二进制类型 , 可以存储任何类型文件(音乐、电影)
* blob和text最大可以保存64KB文件 longtext longblob 最大可以保存4GB文件
1GB = 1024MB 1MB=1024KB 1KB=1024Byte
创建一个员工表employee
id 整形
name 字符型
gender 字符型
birthday 日期型
entry_date 日期型
job 字符型
salary 小数型
resume 大文本型
create table employee (
id int,
name varchar(40),
gender varchar(10),
birthday date,
entry_date date,
job varchar(20),
salary double,
resume longtext
);
2、通过desc语句 查看表结构
语法:desc 表名; 例如 desc employee;
单表约束:主键约束 唯一约束 非空约束
主键约束(唯一标识一条记录,不允许为空,不允许重复)----- primary key 不能为空、不能重复
* 如果主键为数字类型,一般设置主键自动增长 mysql设置自动增长 auto_increment
*一张表只有最重要的那个字段才能作为主键
唯一约束(该字段内容不允许重复) ----- unique
非空约束(该字段内容不允许为空) ----- not null
create table employee (
id int primary key not null auto_increment ,
name varchar(40) unique not null,
gender varchar(10) not null,
birthday date not null,
entry_date date not null,
job varchar(20) not null,
salary double not null,
resume longtext not null
);
3、数据表(表结构)修改
添加一个新列 : alter table 表名 add 列名 类型(长度) 约束;
修改列的类型(长度) : alter table 表名 modify 列名 类型(长度) 约束;
修改列名称: alter table 表名 change 旧列名 新列名 类型(长度) 约束;
删除列 : alter table 表名 drop 列名;
修改表名: rename table 旧表名 to 新表名;
修改表的字符集:alter table 表名 character set 字符集;
练习
在上面员工表的基础上增加一个image列 ----- alter table employee add image varchar(255);
修改job列,使其长度为60 ------ alter table employee modify job varchar(60) not null;
删除gender列。------ alter table employee drop gender;
表名改为user。 ----- rename table employee to user;
修改表的字符集为utf8 ---- alter table user character set utf8;
* show create table user; //查看表的创建信息
列名name修改为username ---- alter table user change name username varchar(40) unique not null;
4、数据表删除
语法: drop table 表名;
* show tables; 查看当前数据库中的所有表
第三部分:对数据表中数据记录 进行 增删改查
1、表记录的插入
语法:insert into 表名(列名,列名, .... ) values(值, 值, ....);
* 值的个数应该和列的个数相同,值顺序要和列顺序相同,值类型要和列字段类型匹配
步骤
1) 启动cmd窗口
2) mysql -u root -p 回车 输入密码
3) 创建数据库 day11 ------ create database day11 ;
* show databases ; 查看当前所有数据库
* show create database day11 ;
4) 创建数据表 ,先切换数据库 use day11;
* select database();
5) 创建数据表
create table employee (
id int primary key not null auto_increment ,
name varchar(40) unique not null,
gender varchar(10) not null,
birthday date not null,
entry_date date not null,
job varchar(20) not null,
salary double not null,
resume longtext not null
);
* desc employee; 查看表结构
6) 插入数据
insert into employee(id,name,gender,birthday, entry_date,job,salary,resume) values(null,'zs','male','1990-01-10','2012-10-10','hr',3000,'He is a good man!');
* 插入数据时,字符串添加单引号 '' ---- 字符和日期型数据应包含在单引号中
insert into employee(id,name,gender,birthday, entry_date,job,salary,resume) values(null,'lisi','male','1980-01-10','2000-10-10','manager',8000,'He is a very good man!');
insert into employee values(null,'wangwu','female','1977-10-08','1999-11-12','BOSS',100000,'He is BOSS');
* 在插入数据时,如果有些列存在默认值或者可以为null ,插入时可以省略部分列 。
create table person(
id int primary key not null auto_increment,
name varchar(40) not null,
introduce varchar(255)
);
insert into person(name) values('zs'); --- 这里只要写不能为空的列 就可以了
* 在插入语句时,省略所有列名
insert into person values(null,'lisi',null); ---- 省略所有列名,必须为所有列提供value值,按照数据表中列顺序
* 插入数据后,通过select * from 表名; ------- 查询插入的数据
select * from person;
插入数据时,中文乱码问题
insert into employee values(null,'小丽','female','1995-10-08','2015-11-12','Sales',2000,'是一个有潜质的女孩子!');
* 查看数据库相关编码集 show variables like 'character%';
* mysql客户端 ,即cmd窗口界面使用的是gbk编码
mysql有六处使用了字符集,分别为:client 、connection、database、results、server 、system。
服务器端相关:database server system(永远无法修改 就是utf-8)
客户端相关 connection client results
解决插入乱码问题:将客户端相关的三个的编码集设置为 gbk
set names gbk; ----- 快速设置客户端相关三个编码集 (临时设置当前窗口编码集)------set character_set_results=gbk;也可以
或者 修改mysql 配置文件,永久改变客户端编码集 ----- mysql/my.ini ,改好后重启mysql服务(通过运行 输入services.msc)
[mysql] ---- 客户端配置
[mysqld] ---- 服务器端配置
2、数据表记录修改操作 update 语句
语法: update 表名 set 列名=值,列名=值 where 条件语句;
* 如果没有where语句,就会对所有数据行进行更新
update employee set salary = 5000 ; ---- 修改所有员工工资为5000
练习
将所有员工薪水修改为5000元。 ------ update employee set salary = 5000 ;
将姓名为’zs’的员工薪水修改为3000元。update employee set salary = 4000 where name = 'zs';
update employee set salary = 4000 where name = 'ZS';----'zs' 变为'ZS'和上一句一样的效果(这是一个bug)
* update employee set salary = 3000 where binary name = 'ZS'; ---- (此时无法修改)条件比较前添加 binary 使比较更加精确严格
将姓名为’lisi’的员工薪水修改为4000元,job改为ccc。 --------- update employee set salary = 4000, job='ccc' where binary name = 'lisi';
将wangwu的薪水在原有基础上增加1000元。------- update employee set salary = salary+1000 where name = 'wangwu';
3、数据表记录通过delete语句进行删除 语法:delete from 表名 where 条件语句;
*如果不使用where子句,将删除表中所有数据。
删除一个表所有记录: truncate 表名; 效果与 delete from 表名; 相同
truncate与delete 使用上区别 ?
truncate 删除记录后不可恢复的,不受事务管理。 原理:先删除整个表,然后再重新创建
delete 可以被事务管理 ,在事务中删除数据可以回滚恢复。 原理: 一行一行删除数据记录
truncate 删除所有记录性能上好于delete
练习:
删除表中名称为’zs’的记录 。 ---- delete from employee where name='zs';
删除表中所有记录。 ---- delete from employee;
* 演示 事务的回滚 ,通过delete在事务中删除是可以恢复的
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from employee;
Query OK, 3 rows affected (0.00 sec)
mysql> select * from employee;
Empty set (0.00 sec)
mysql> rollback;
mysql> select * from employee;
使用truncate删除表中记录。-----truncate employee; 数据永远删除,无法恢复
4、数据记录的查询
语法:select * | 列名,列名 from 表名;
1) 基本查询
select * from employee; ---- 查看当前数据表所有记录
select gender from employee; ----- 查看employee的 gender列数据
select distinct gender from employee; ---- 查看employee表所有性别 ,排重
创建scores
create table scores(
id int primary key not null auto_increment,
name varchar(40),
math double,
chinese double,
english double
);
insert into scores values(null,'老黎',85,90,76);
insert into scores values(null,'老刘',70,65,80);
insert into scores values(null,'老冯',60,70,65);
练习:
查询表中所有学生的信息。------ select * from scores;
查询表中所有学生的姓名和对应的英语成绩。------- select name,english from scores;
过滤表中重复数据。----- select distinct * from scores;
2) 查询时进行运算
select 列名运算表达式 from 表名;
select 列名 as 列别名 from 表名;
练习
在所有学生英语分数上加10分特长分。select name,english+10 from scores;
统计每个学生的总分。 select name,math+chinese+english from scores;
使用别名表示学生分数。select name,math+chinese+english as 总分 from scores;
* 起别名时 as 可以省略 select name 姓名 from scores;
比较* select name math from scores;和 select name,math from scores;的不同
3) 查询数据时通过比较运算添加where条件 过滤查询内容
使用where子句,进行过滤查询。练习:
查询姓名为老黎的学生总成绩 ---- select math+chinese+english from scores where name='老黎';
查询英语成绩大于80分的同学 ---- select name,english from scores where english >= 80;
查询总分大于200分的所有同学 ---- select * from scores where math+chinese+english > 200;
4) select 其它比较运算
查询语文成绩不为90 分的学生 select name,chinese from scores where chinese <> 90;
between ..and... 查询语文在70-80之间同学
select name,chinese from scores where chinese<=80 and chinese>=70;
select name,chinese from scores where chinese between 70 and 80 ; ---- 先写小的后写大的
in(set) 在几个固定值中取值 select * from scores where chinese in (70,80,90); ---- 查询语文成绩为70分或者80分或者90分同学
like 模糊查询 select * from scores where name like '老%';
查询学生中姓 老的所有人 ----- % 代表零个或多个任意字符
select * from scores where name like '老_';
查询学生中姓老 名字为两个字的学生 ------ _ 代表任意单个字符
is null 判断一列是否为空
insert into scores values(null,'小丽',null,80,90);
查询无数学成绩所有人 select name,math from scores where math is null;
查询有数学成绩人 select name,math from scores where math is not null;
* select * from scores where 1; --- 在编程语言中 1 代表rue
select * from scores where 0 ; ---- 0 代表false
* null 代表1/2(介于真与假之间) ---- 任何表达式和null 进行逻辑运算 结果都是false , 和null 进行算术运算 结果都是null
逻辑运算中 and 、or ---- and 和 or 谁优先级高 ?
select * from scores where 2>1 or 2>3 and 3>4 ; ---- and先执行 SQL攻击
练习:
查询英语分数在 80-90之间的同学。 select name,english from scores where english between 80 and 90;
查询数学分数为89,90,91的同学。 select name, math from scores where math in (89,90,91);
查询所有姓李的学生成绩。 select * from scores where name like '李%';
查询数学分>80,语文分>80的同学。 select name,math,chinese from scores where math>80 and chinese >80;
5) 对select查询结果通过 order by 语句进行排序
语法 : select * from 表名 where条件语句 order by 列名 asc|desc , 列名 asc|desc ... ;
asc 升序、desc 降序
练习:
对数学成绩排序后输出。select name,math from scores order by math; 默认是升序(asc)
对总分排序按从高到低的顺序输出 select name,chinese+math+english from scores order by chinese+math+english desc;
对姓老的学生数学成绩排序输出 select name,math from scores where name like '老%' order by math desc;
--------------------------------------------------------------------------------------------------------------------------
6) 聚集函数(分组函数) ---- 结合查询分组进行数据统计
count 返回查询结果记录条数 *null数据不参与运算 如 select count(math) from scores;
练习:
统计一个班级共有多少学生? select count(*) from scores;
统计数学成绩小于80的学生有多少个? select count(*) from scores where math<80;
统计总分大于250的人数有多少? select count(*) from scores where math+chinese+english > 250;
sum 对一列的数据求和 * sum求和时 null不运算
统计一个班级数学总成绩? select sum(math) from scores;
统计一个班级语文、英语、数学各科的总成绩 select sum(math),sum(chinese),sum(english) from scores;
统计一个班级语文、英语、数学的成绩总和 select sum(math) + sum(chinese) + sum(english) from scores;
统计一个班级语文成绩平均分 select avg(chinese) from scores; 或select sum(chinese)/count(chinese) from scores;
avg 对一列数据求平均值 * avg求平均值时,null数据不参与运算
求一个班级数学平均分? select avg(math) from scores;
求一个班级总分平均分 select avg(math+chinese+english) from scores;
max和min 对一列数据 计算最大值和最小值 *null数据不参与运算
求班级总分最高分和总分最低分(数值范围在统计中特别有用) select max(math+chinese+english),min(math+chinese+english) from scores;
思考题:语文最高分是谁? select max(chinese) from scores;
select name from scores where chinese = (select max(chinese) from scores);
分组目的:统计 分组前提:重复数据 参看图三 参看Test.sql
create table orders(
id int,
product varchar(20),
price float
);
insert into orders(id,product,price) values(1,'电视',900);
insert into orders(id,product,price) values(2,'洗衣机',100);
insert into orders(id,product,price) values(3,'洗衣粉',90);
insert into orders(id,product,price) values(4,'桔子',9);
insert into orders(id,product,price) values(5,'洗衣粉',90);
练习:对订单表中商品归类后,显示每一类商品的总价
select product,sum(price),count(*) from orders group by product;
在分组查询中通过 having关键字,添加分组查询条件
练习:查询购买了几类商品,并且每类总价大于100的商品
* where中不能使用分组函数
select count(*) from orders group by product;
select * from orders group by product;
select product,sum(price) from orders group by product having sum(price) > 100;
where 和 having 添加条件使用上区别 ?
where 是在分组之前执行,having是在分组之后执行,where不能使用分组函数,having能使用分组函数
* having可以替换where
数据库数据需要定期备份 ------ 数据库的备份和恢复
备份:cmd窗口> mysqldump -u 用户名 -p 数据库名 > 文件名.sql
* 备份时先退出mysql,在命令行下执行
例如 C:\Documents and Settings\Administrator> mysqldump -u root -p day11 > c:/day11.sql
删除数据库 :mysql> drop database day11;
恢复
1、创建空数据库 mysql> create database day11_bak;
2、恢复数据库
Source 文件名.sql // 在mysql内部使用
例如:
mysql> use day11_bak;
mysql> source c:/day11.sql; 或 source c:\\day11.sql;
或
mysql -u 用户名 -p 数据库名 < 文件名.sql // 在cmd下使用
例如:C:\Documents and Settings\Administrator> mysql -u root -p day11_bak < c:/day11.sql
--------------------------------------------------------------------------------------------------
多表设计 --- 任何一个软件系统都是由多个数据表组成
系统中已经存在employee表
向系统添加dept 表 (部门表)
create table dept (
id int primary key not null auto_increment,
name varchar(40) unique not null
);
insert into dept values(null,'人力资源部');
insert into dept values(null,'产品研发部');
insert into dept values(null,'财务部');
insert into dept values(null,'行政部');
建立employee 表和dept表的关系 ,在employee表添加 dept_id
alter table employee add dept_id int ;
update employee set dept_id = 1 where id =1;
update employee set dept_id = 2 where id =2;
update employee set dept_id = 3 where id =3;
update employee set dept_id = 4 where id =4;
产品研发部解散了 删除dept表 相应数据 delete from dept where id = 2;
* 问题:李四属于产品研发部,部门记录删除前,先将李四转到别的部门 --------- 外键约束
外键约束:在employee表添加外键约束,使得表employee的dept_id的值 引用 表dept的id字段 ,值不可以乱写
* 外键通常引用另一个表主键
为employee表添加一个外键约束
alter table employee add foreign key (dept_id) references dept (id );
添加了外键约束,就不能随便取值,取值是引用表存在的主键值,不能随便删除数据
delete from dept where id = 2; ---不可以删除被引用的值
update employee set dept_id = 100 where id = 1;----不可以
1、数据库操作相关SQL ---- database
创建数据库: create database 数据库名称; ------ database 在创建时 character set 指定数据库字符集,如果没有则采用服务器默认字符集
* 服务器默认字符集 mysql安装目录/my.ini [mysqld] default-character-set
* collate 校对方式 ----- 用于数据库排序; 每一种字符集都存在一种默认校对方式(可以不用修改)
查看当前有哪些数据库: show databases;
修改数据库(修改数据库字符集):alter database 数据库名称 character set 字符集;
*数据库字符集存放在mysql安装目录/data/数据库文件夹/db.opt
删除数据库: drop database 数据库名称;
切换数据库(设置当前需要使用的数据库): use 数据库名称;
* select database(); 查看当前正在使用的数据库
2、数据表操作相关SQL ---- table表结构
创建数据表: create table 表名(列名 类型(长度) 约束,列名 类型(长度) 约束... ) ----- 在创建表之前必须指定数据库
* 查看当前数据库中有哪些数据表: show tables;
查看数据表表结构: desc table;
修改表结构:
添加一个新列 : alter table 表名 add 列名 类型(长度) 约束;
修改列的类型(长度) : alter table 表名 modify 列名 类型(长度) 约束;
修改列名称: alter table 表名 change 旧列名 新列名 类型(长度) 约束;
删除列 : alter table 表名 drop 列名;
修改表名: rename table 旧表名 to 新表名;
修改表的字符集:alter table 表名 character set 字符集;
* table 在创建时 character set 指定表字符集,如果没有则采用数据库默认字符集
删除表: drop table 表名;
3、数据记录增删改查 insert update delete select
数据记录插入: insert into 表名(列,...) values(值,...);
* 值的顺序和列顺序一致,个数一致 , 在开发中经常省略列名,值按照表结构所有字段进行设值。
数据记录修改: update 表名 set 列名=值,列名= 值 where 条件语句
数据记录删除 delete from 表名 where 语句
* truncate 与 delete区别 ? truncate删除表,重新创建, delete from 逐行删除-----truncate 性能好于 delete,delete被事务控制,删除后回滚取消删除,truncate不可恢复
数据查看 select * from 表名;
select 语句
S - F - W - G - H - O
select ... from ... where ... group by ... having ... order by ... ; 顺序固定的
执行顺序:
1、from :指定查询的数据表
2、where :前置过滤条件 --- 将表数据过滤掉一部分
3、group by :对where 过滤后数据进行分组
4、having :对分组后结果添加条件过滤
5、select :指定检索哪些字段
6、order by :对检索结果排序
4、数据库备份和恢复
备份命令: mysqldump -u 用户名 -p 数据库名 > sql脚本位置 (回车输入密码);
恢复命令: mysql -u 用户名 -p 数据库名 < sql脚本位置 (回车输入密码 );
* 也可以在mysql连接后,通过source 进行数据库恢复: source sql脚本位置;
5、数据库完整性约束 ----- 保证数据表中记录完整性
主键约束 primary key : 用来指定数据表数据记录的唯一标识
唯一约束 unique : 该字段取值唯一
非空约束 not null ; 该字段取值不能为null
外键约束 foreign key : 当两个数据表存在关联时,添加外键约束,外键引用另一张表的主键
条件约束 check : mysql不支持, Oracle支持, 例如,check age<100 ; 则向数据表存入age值时必须小于100
* 完整性约束有5类
----------------------------------------------------------------------------------------------------------------
多表设计
数据表与数据表之间关系三种:实体之间关系 多对多、一对多、一对一
多对多案例:项目和程序员
一个项目可以由多个程序员参与开发
一个程序员可以参与多个项目的开发
建表原则:多对多关系,必须引入第三张数据表,同时引入另两张实体表的主键作为外键
一对多案例:老师与课程
一个老师可以教授多门课程
一门课程只能有一个老师教授
建表原则:一对多关系,在多的一方添加一的一方的主键作为外键
一对一关系:班级与班长关系
一个班只能有一个班长
一个班长只能负责一个班
* 该关系比较少见
建表原则:一对一关系,可以在任何一方添加另一方的主键作为外键
建表练习:
设计学生成绩管理系统数据表
1、每个教师可以教多门课程
2、每门课程可以由多个学生选修
3、每个学生可以选修多门课程
4、学生选修课程要有成绩
关系表表名,通常用两个实体表表名组合而成! 参看 teacher.sql
---------------------------------------------------------------------------------------------------------------------
笛卡尔积
当两个数据表进行关联查询时,用第一张数据表每一条记录去匹配第二张数据表每一条记录。 参看data.sql
select * from A,B;
第一张表10条数据
第二张表20条数据
使用笛卡尔积 结果 10*20 = 200 条记录
在实际开发中,需要获得笛卡尔积中有意义的记录 ? ---- 连接查询
内连接
外连接:左外连接、右外连接、全外连接
内连接 : 将两张表相同意义字段连接起来
select * from A inner join B on A.A_ID = B.B_ID; ---条件: A表中A_ID与 B表中 B_ID 相等匹配
或select * from A,B where A.A_ID = B.B_ID;
* 返回结果一定是两个表都存在的信息 , 最有意义的信息,如果第一张表记录在第二张表找不到匹配信息,不显示,第二张表记录在第一张表无匹配信息,不显示
第一张表10条数据
第二张表20条数据
内连接 结果 <= 10条
外连接:左外连接、右外连接、全外连接
左外连接 :用第一张表每条记录去匹配第二张表对应记录,无论是否找到匹配信息,都显示第一张表匹配结果
例如:每个水果价格 ? 没有价格的水果也要显示
select * from A left outer join B on A.A_ID = B.B_ID ;
第一张表10条数据
第二张表20条数据
左外连接 --- 10条
右外连接:从第二张表找第一张表匹配记录,无论是否找到,第二张表所有记录都显示
select * from A right outer join B on A.A_ID = B.B_ID ;
第一张表10条数据
第二张表20条数据
右外连接 --- 20条
全外连接:左外连接与右外连接 结果和 ---- 排除重复数据
select * from A full outer join B on A.A_ID = B.B_ID ; ----- MySQL 不支持
mysql使用union关键字实现全外连接效果
select * from A left outer join B on A.A_ID = B.B_ID
union
select * from A right outer join B on A.A_ID = B.B_ID;
------------------------------------------------------------------------------------------------------------------
关联子查询:将第一个查询结果 ,作为第二个查询条件
查询student表中年龄最大学员的信息 参看 teacher.sql
select * from student where age = (select max(age) from student);
等价于
select max(age) from student; ----- 25 年龄最大
select * from student where age = 25; ----- 学生信息
in/exists 当前查询记录在子查询结果中存在
查询所有成绩小于60分的同学名称 ( 查询 [所有成绩小于60分的] 同学名称)
select name from student where id in (select student_id from studentcourse where score < 60);
exists实现上面in 语句效果
select name from student where exists (select * from studentcourse where score < 60 and student.id = studentcourse.student_id);
* (exists和in你擅长哪个就用哪个)
* 在实际开发中 exists比 in效率要高
ANY、SOME、ALL 用法
SOME和ANY作用是相同的 ----- > any(1,2,3) 大于任何一个都可以, 等价于 > min(1,2,3)
ALL ---- 所有 > all(1,2,3) 必须同时大于三个值, 等价于 > max(1,2,3
查询获得最高分的学生学号 ( 查询 [获得最高分的] 学生学号)
select student_id from studentcourse where score = (select max(score) from studentcourse);
或
select student_id from studentcourse where score >= all(select score from studentcourse); * 自我比较(当成2张表)
*喜欢哪种方法就用哪种方法
查询编号2课程比编号1课程成绩高所有学号 ( 查询 [编号2课程比编号1课程成绩高] 所有学号)
select student_id from studentcourse where course_id = 2 and score > any(select score from studentcourse where course_id = 1);
union/union all取结果集并集
(select A_ID from A) union (select B_ID from B) 排除重复结果
(select A_ID from A) union all (select B_ID from B) 不排除重复结果
----------------------------------------------------------------------------------------------------------------------------------