1.创建数据库
create database [if not exists] 数据库名;
2.删除数据库
drop database [if exists] 数据库名;
3.显示所有数据库
show databases;
4.使用数据库
use 数据库名;
5.显示所有的表
show tables;
设计数据库的步骤:
1.收集信息
2.标识实体
3.标识实体的属性
4.标识实体与实体之间的关系
创建表的过程就是实现数据完整性的过程。
什么是数据完整性?
数据的准确性和完整性。
数据完整性分类:
1.实体完整性
约束方法:
主键约束、唯一约束、标识列(自动增长列)
2.域完整性
约束方法:
限制数据类型、检查约束(MySQL中不起作用)、非空约束、默认值
3.引用完整性
约束方法:
外键约束
4.自定义完整性
约束方法:
规则、存储过程
创建表的步骤:
1.确认表名
2.确认有哪些列及每个列的数据类型是什么
3.添加约束(建关系)
MySQL中的列类型:
1. 数值类型
int
double
decimal
2. 日期和时间类型
date 支持的范围为'1000-01-01'到'9999-12-31'
datetime 支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'
timestamp 范围是'1970-01-01 00:00:00'到2037年
3. 字符串类型
char
varchar
text
创建表的语法:
CREATE TABLE [IF NOT EXISTS] 表名
(
列名 列类型 [字段属性][约束][索引][注释],
列名 列类型 [字段属性][约束][索引][注释],
....
列名 列类型 [字段属性][约束][索引][注释]
)[表类型][字符集][注释];
在MySchool数据库中创建年级表(Grades[gradeId,gradeName,description,state]):
CREATE TABLE IF NOT EXISTS grades
(
gradeId INT(4) NOT NULL COMMENT '年级编号',
gradeName VARCHAR(20) NOT NULL COMMENT '年级名称',
description VARCHAR(200) NULL COMMENT '年级描述',
state INT(4) NOT NULL COMMENT '年级状态'
)COMMENT='年级表';
在这里插入代码片
显示表结构:
DESC[rible] 表名;
如:
mysql> desc grades;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| gradeId | int(4) | NO | | NULL | |
| gradeName | varchar(20) | NO | | NULL | |
| description | varchar(200) | YES | | NULL | |
| state | int(4) | NO | | NULL | |
+-------------+--------------+------+-----+---------+-------+
删除表:
DROP TABLE [IF EXISTS] 表名;
如:
DROP TABLE IF EXISTS grades;
修改表:
1.修改表名
ALTER TABLE 旧表名 RENAME AS 新表名;
如:
ALTER TABLE students RENAME AS student;
2.添加字段
ALTER TABLE 表名
ADD 列名 列类型 [属性][索引][注释]
如:
ALTER TABLE students
ADD loginId INT NOT NULL COMMENT '登录名';
3.修改列
ALTER TABLE 表名
MODIFY [COLUMN] 列名 列类型 [属性][索引][注释]
如:
ALTER TABLE students
MODIFY loginId VARCHAR(20) NOT NULL COMMENT '登录名';
4.修改字段名
ALTER TABLE 表名
CHANGE 旧列名 新列名 列类型 [属性][索引][注释]
如:
ALTER TABLE students
CHANGE loginId loginName VARCHAR(20) NOT NULL COMMENT '登录名';
5.删除列
ALTER TABLE 表名
DROP [COLUMN] 列名;
如:
ALTER TABLE students
DROP loginName;
6.添加主键约束
ALTER TABLE 表名
ADD [CONSTRAINT] PK_表名 PRIMARY KEY(列名[,列名]);
如:
ALTER TABLE grades
ADD CONSTRAINT PK_grades PRIMARY KEY(gradeId);
7.添加唯一约束
ALTER TABLE 表名
ADD [CONSTRAINT] UQ_表名_列名 UNIQUE(列名);
如:
ALTER TABLE students
ADD CONSTRAINT UQ_students_identityCard UNIQUE(identityCard);
8.添加外键约束
ALTER TABLE 表名
ADD [CONSTRAINT] FK_子表名_主表名 FOREIGN KEY(列名) REFERENCES 主表名(主键列名)
如:
ALTER TABLE students
ADD CONSTRAINT FK_students_grades FOREIGN KEY(gradeId) REFERENCES grades(gradeId);
9.删除主键约束
ALTER TABLE 表名
DROP PRIMARY KEY
10.删除外键约束
ALTER TABLE 表名
DROP FOREIGN KEY 外键约束名
11.给列指定默认值
ALTER TABLE 表名
ALTER 列名 SET DEFAULT 默认值;
如:
ALTER TABLE students
ALTER sex SET DEFAULT '男';
方式2:
ALTER TABLE students
MODIFY sex CHAR(2) DEFAULT '男';
12.删除默认值
ALTER TABLE 表名
ALTER 列名 DROP DEFAULT;
如:
ALTER TABLE students
ALTER sex DROP DEFAULT;
创建表的同时添加属性及约束:
#方式1:
CREATE TABLE IF NOT EXISTS studentInfo
(
id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '编号',
name VARCHAR(20) NOT NULL UNIQUE COMMENT '姓名',
sex CHAR(2) NOT NULL DEFAULT '男' COMMENT '性别',
age INT(4) NOT NULL COMMENT '年龄',
gradeId INT(4) NOT NULL COMMENT '年级编号' REFERENCES grades(gradeId)
)COMMENT='学员信息表';
#方式2:
CREATE TABLE IF NOT EXISTS studentInfo
(
id INT(4) NOT NULL AUTO_INCREMENT COMMENT '编号',
name VARCHAR(20) NOT NULL COMMENT '姓名',
sex CHAR(2) NOT NULL DEFAULT '男' COMMENT '性别',
age INT(4) NOT NULL COMMENT '年龄',
gradeId INT(4) NOT NULL COMMENT '年级编号',
CONSTRAINT PK_studentInfo PRIMARY KEY(ID),
CONSTRAINT UQ_studentInfo_name UNIQUE(Name),
CONSTRAINT FK_studentInfo_grades FOREIGN KEY(gradeId) REFERENCES grades(gradeId)
)COMMENT='学员信息表';
DML(Data Manipulation Language)数据操纵语言
a.INSERT
b.UPDATE
c.DELETE
插入数据:
a.向表中插入单条语句语法:
INSERT INTO 表名(列名,列名,...)VALUES(列值,列值,...)
如:向年级表插入语句
INSERT INTO grades(gradeName,description,state)
VALUES('一年级','一年级',1);
注:
1.列名可省略,如果省略,列值的顺序必须和表中列的顺序一致
INSERT INTO grades VALUES('一年级','一年级',1);
2.多个列名或多个列值之间使用逗号分隔
3.值列表要和列名列表一一对应
4.如果插入的为部分数据,列名列表必填。(满足数据规范)
5.向子表中插入数据时,引用主表中的数据必须存在。
INSERT INTO students(loginPwd,studentName,borndate,phone,address,email,identityCard,gradeId)
VALUES('123456','张三','1990-09-09 09:09:09','18099999999','成都','[email protected]','530916199009091122',1)
b.向表中插入多条数据语法:
INSERT INTO 表名(列名,列名,...)
VALUES(列值,列值,...),
(列值,列值,...),
...
(列值,列值,...)
如:向年级表中插入多条数据
INSERT INTO grades(gradeName,description,state)
VALUES('二年级','二年级',1),
('三年级','三年级',1);
向科目表中插入一年级的科目信息
科目编号 名称 课时 年级编号
1 Logic Java 40 1
2 SQL Server 30 1
3 HTML&CSS 32 1
c.向已存在的其它表中插入多条数据
INSERT INTO 其它表名(列名,列名,...)
SELECT 列名,列名,...
FROM 原表名;
注:将原表的数据插入到其它表中
如:
#创建年级备份表
CREATE TABLE IF NOT EXISTS grades_bak
(
id int(4) not null primary key,
name varchar(20) not null,
desc varchar(200) null
)comment='年级备份表';
#向备份表中插入数据
INSERT INTO grades_bak(id,name,desc)
SELECT gradeId,gradeName,description
FROM grades;
d.向新表(不存在)中插入多条数据
CREATE TABLE IF NOT EXISTS 新表名
(
SELECT 列名,列名,... FROM 原表名
);
注:将原表的数据插入到新表中
CREATE TABLE IF NOT EXISTS grades_bak2
(
SELECT gradeId,gradeName,description
FROM grades
);
创建新表(不存在)和其它表的数据结构相同。
CREATE TABLE IF NOT EXISTS grades_bak3
(
SELECT *
FROM grades WHERE 1<>1
);
更新数据语法:
UPDATE 表名 SET 列名=新值,列名=新值,...
[WHERE 条件]
注:
1.一般修改数据都是有条件更新
2.修改主表的数据时,不能使子表中的数据独立。
MySQL中的运算符:
a.算术运算符
+ - * /
b.比较运算符
= <>(不等于) > >= < <=
c.逻辑运算符
and or not
......
删除数据的语法:
DELETE FROM 表名 [WHERE 条件]
注:
1.一般删除数据都是有条件删除
2.删除主表的数据时,不能使子表中的数据独立。
3.一般删除主表数据时,先删除子表的数据,再删除主表中的数据。
截断表(删除数据)的语法:
TRUNCATE TABLE 表名;
注:此方法不可恢复
基本的查询:
1.选择所有列
SELECT * FROM 表名
如:
SELECT * FROM grades;
2.选择特定列
SELECT 列名,列名,... FROM 表名
如:
SELECT gradeName,state FROM grades;
3.在查询中使用算术运算符 + - * /
SELECT studentNo,subjectNo,studentResult,studentResult+10
FROM results;
4.定义空值:
空值是不可用的、未分配的、未知的或不适用的值。
空值不同于零或空格
注:包含空值的算术表达式的计算结果也为空
SELECT studentNo,subjectNo,studentResult,studentResult+10
FROM results;
5.定义列别名
SELECT 列名 AS 新列名,列名 AS 新列名,... FROM 表名
如:
SELECT gradeId as 年级编号,
gradeName as 年级名称,
state as 状态
FROM grades;
#省略AS
SELECT gradeId 年级编号,
gradeName 年级名称,
state 状态
FROM grades;
6.使用连接符(数值+:求和 字符串-函数concat:连接)
#数值
SELECT gradeId + state as 编号加状态
FROM grades;
#字符串
SELECT CONCAT(gradeName,description) as 名称描述
FROM grades;
7.去除重复数据行
SELECT DISTINCT 列名 FROM 表名
如:
查询参加考试的学员
SELECT DISTINCT studentNo AS 学号 FROM results
8.对所选行进行限制,使用WHERE 子句可以限制返回的行
SELECT 列名,列名,... FROM 表名 WHERE 条件
如:
查询年级编号小于3的年级信息
SELECT gradeId 编号,gradeName 名称 FROM grades WHERE gradeId<3;
#注:字符串的值使用单引号括起(值不区分大小写)
SELECT gradeId 编号,gradeName 名称
FROM grades WHERE gradeName='s1';
9.MySQL中比较运算符(> >= < <= = <> ,between and,like,in,is null)
a.使用BETWEEN 运算符的范围条件
SELECT 列名,列名,... FROM 表名 WHERE 数值列名 BETWEEN 小值 AND 大值;
#查询学员考试成绩60到80之间的
SELECT studentNo 学号,subjectNo 课程号,studentResult 成绩
FROM results
WHERE studentResult BETWEEN 60 AND 80;
或
SELECT studentNo 学号,subjectNo 课程号,studentResult 成绩
FROM results
WHERE studentResult>=60 AND studentResult<=80;
b.使用IN运算符的成员条件
SELECT 列名,列名,... FROM 表名 WHERE 列名 IN(列值,列值,...)
#查询学员考试成绩是60或80的学员信息
SELECT studentNo 学号,subjectNo 课程号,studentResult 成绩
FROM results
WHERE studentResult IN(60,80);
或
SELECT studentNo 学号,subjectNo 课程号,studentResult 成绩
FROM results
WHERE studentResult=60 OR studentResult=80;
c.使用LIKE 运算符执行模式匹配
搜索条件可包含文字字符或数字:
% 表示零个或多个字符。
_ 表示一个字符。
SELECT 列名,列名,... FROM 表名 WHERE 列名 LIKE '%值%';
#查询姓张所有学员信息
SELECT * FROM students WHERE studentName LIKE '张%';
d.使用NULL 条件,使用IS NULL 运算符可测试空值
SELECT 列名,列名,... FROM 表名 WHERE 列名 IS NULL;
#查询年级描述为null年级信息
SELECT * FROM grades WHERE description IS NULL;
#查询年级描述不为null年级信息
SELECT * FROM grades WHERE description IS NOT NULL;
10.对查询结果排序
使用ORDER BY 子句可对检索行进行排序:
– ASC:(Ascending)升序,默认顺序
– DESC:(Descending)降序
ORDER BY 子句位于SELECT 语句的最后:
SELECT 列名,列名,... FROM 表名 WHERE 条件 ORDER BY 列名或表达式 [ASC/DESC];
#查询学员考试成绩,按由高到低排序
SELECT studentNo 学号,subjectNo 课程号,studentResult 成绩
FROM results ORDER BY studentResult DESC;
按多列排序,查询学员信息按学员年龄(降序)和身高(升序)进行排序
SELECT studentNo 学号,studentAge 年龄,studentHeight 身高
FROM students
ORDER BY studentAge DESC,studentHeight ASC;
11.MySQL分页查询,使用LIMIT
SELECT 列名,列名,... FROM 表名 LIMIT 位置偏移量,每页记录数;
注:第一条位置的记录为0
#查询表中第3页的数据,每页显示5条记录。
SELECT * FROM tabName LIMIT 10,5;
分页算法:
a.页码 pageNum
b.每页的记录数 pageSize
c.总记录数 totalCount
计算:
总页数 = 总记录数 % 每页记录数 == 0 ? 总记录数 / 每页记录数 : (总记录数 / 每页记录数+1);
位置偏移量 = (页码 - 1)*每页的记录数;
MySQL中的函数:
1.字符串函数
a.length(字符串) 返回字符串长度
SELECT LENGTH('hello world');
b.concat(字符串1,字符串2,...) 将字符串连接在一起
SELECT CONCAT('hello',' ','world');
c.insert(str,pos,len,newstr) 返回字符串str, 其子字符串起始于 pos[从1开始] 位置和长期被字符串 newstr取代的len 字符。 如果pos 超过字符串长度,则返回值为原始字符串。 假如len的长度大于其它字符串的长度,则从位置pos开始替换。若任何一个参数为null,则返回值为NULL。
SELECT INSERT('hello world',3,2,'new');
d.INSTR(str,substr) 返回字符串 str 中子字符串的第一个出现位置
SELECT INSTR('HELLO','L');
e.SUBSTRING(str,pos,len) 或SUBSTR(str,pos,len) 返回字符串str从pos位置开始截取长度为len之后的字符串
SELECT SUBSTRING('HELLO',3,3);
f.REPLACE(str,oldstr,newstr) 将newstr替换oldstr.
SELECT REPLACE('HELLO','L','1'); #HE110
g.TRIM(str) 清空左右空格
SELECT LENGTH(' HELLO '); #7
SELECT LENGTH(TRIM(' HELLO ')); #5
任务:
现有一批游戏卡,使用者发现卡的密码(o)哦和(0)零,
(i)和(1)分不清楚,请使用SQL语句完成表Game中password列
中的数据更新,将o替换为0,i替换为1。
答案:
UPDATE Game SET password=REPLACE(password,'o','0');
UPDATE Game SET password=REPLACE(password,'i','1');
or
UPDATE Game SET password=REPLACE(REPLACE(password,'i','1'),'o','0');
2.数学函数
a.CEILING(数值) 返回比数值大的最小整数
SELECT CEILING(1.33);
b.FLOOR(数值) 返回比数值小的最大整数
SELECT FLOOR(1.33);
c.RAND() 返回一个随机浮点值 v ,范围在 0 到1 之间 (即, 其范围为 0 ≤ v ≤ 1.0)。
SELECT RAND();
d.ROUND(x) 返回参数X, 其值接近于最近似的整数。
SELECT ROUND(5.56);
SELECT ROUND(5.46);
3.类型转换函数
a.CONVERT(值,类型) 将值转换为指定类型
SELECT CONVERT('1234',SIGNED); #将字符串转换为数值类型
b.CAST(值 AS 类型) 将值转换为指定类型
SELECT CAST('1234' AS SIGNED); #将字符串转换为数值类型
任务:将数据库表NumTab中的num列中的数据
11-101,11-11,12-1,11-110,12-104,101-1先按减号前半部分排序,
再按减号后面部分排序。
#创建表
DROP TABLE IF EXISTS NumTab;
CREATE TABLE IF NOT EXISTS NumTab
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
num varchar(20) NOT NULL
);
#插入数据
INSERT INTO numtab(num)
VALUES
('11-101'),
('11-11'),
('101-1'),
('12-1'),
('11-110'),
('12-104');
#查询所有数据
SELECT * FROM numtab;
#SELECT * FROM numtab ORDER BY num; #xxx
#实现思路
a.求出减号前面部分内容
SELECT INSTR(num,'-') as 减号位置 FROM numtab;#求减号位置
SELECT SUBSTRING(num,1,INSTR(num,'-')-1) as 减号前面内容 FROM numtab;
b.求出减号前面部分内容
SELECT SUBSTRING(num,INSTR(num,'-')+1) as 减号后面内容 FROM numtab;
c.将字符串转换为整数
SELECT CONVERT(SUBSTRING(num,1,INSTR(num,'-')-1),SIGNED) FROM NUMTAB;
d.排序
SELECT
*
FROM
numtab
ORDER BY
CONVERT(SUBSTRING(num,1,INSTR(num,'-')-1),
SIGNED),CONVERT(SUBSTRING(num,INSTR(num,'-')+1),SIGNED);
4.日期函数
a.CURDATE() 返回当前日期
SELECT CURDATE();
b.CURTIME() 返回当前时间
SELECT CURTIME();
c.NOW() 返回当前日期和时间
SELECT NOW();
d.DATEDIFF(expr,expr2) 返回起始时间 expr和结束时间expr2之间的天数。
SELECT DATEDIFF(NOW(),'1990-09-09');
SELECT YEAR(NOW()) - YEAR('1990-09-09') AS 年龄;
5.聚合函数(多行函数)
a.COUNT(expr)
返回SELECT语句检索到的行中非NULL值的数目
b.SUM([DISTINCT] expr)
返回expr 的总数。
c.AVG([DISTINCT] expr)
返回expr 的平均值。
d.MIN([DISTINCT] expr), MAX([DISTINCT] expr)
返回expr 的最小值和最大值。
#统计参数考试的人数
SELECT count(studentNo) as 考试人数 FROM results;
#求总成绩、平均成绩、最高成绩和最低成绩
SELECT
SUM(studentResult) as 总成绩,
AVG(studentResult) as 平均成绩,
MAX(studentResult) as 最高成绩,
MIN(studentResult) as 最低成绩
FROM
results;
#创建学生表
create table student(
id int(10) not null PRIMARY key auto_increment COMMENT'学号',
name varchar(20) not null COMMENT'姓名',
sex varchar(4) COMMENT'性别',
birth year COMMENT'出生年份',
department varchar(20) not null COMMENT'院系',
address varchar(50) COMMENT'家庭住址'
);
#设置主键自增初始值为901
alter table student auto_increment=901;
#创建成绩表
create table score(
id int(10) not null PRIMARY KEY auto_increment COMMENT'编号',
stu_id int(10) not null COMMENT'学号',
c_name varchar(20) COMMENT'课程名',
grade int(10) COMMENT'分数'
);
#向学生表中插入数据
insert into student
values
(901,'张老大','男','1985','计算机系','北京市海淀区'),
(default,'张老二','男','1986','中文系','北京市昌平区'),
(default,'张三','女','1990','中文系','湖南省永州市'),
(default,'李四','男','1990','英语系','辽宁省阜新市'),
(default,'王五','女','1991','英语系','福建省厦门市'),
(default,'王六','男','1988','计算机系','湖南省衡阳市');
#查询student表所有数据
SELECT * from student;
#向score表中插入数据
insert into score(stu_id,c_name,grade)
values(901,'计算机',98),
(901,'英语',80),
(902,'计算机',65),
(902,'中文',88),
(903,'中文',95),
(904,'计算机',70),
(904,'英语',92),
(905,'英语',94),
(906,'计算机',90),
(906,'英语',85);
#1.查询student表的所有记录
select * from student;
#2.查询student表的第2条到4条记录
select * from student limit 2,4;
#3.从student表查询所有学生的学号(id)、姓名(name)和院系(department)的信息
select id,name,department from student;
#4.从student表中查询计算机系和英语系的学生的信息
select * from student where department='计算机系' or department='英语系';
#或者in
select * from student where department in('计算机系','英语系');
#5.从student表中查询年龄18~22岁的学生信息,本处没有满足该条件的
select * from student where (2020-birth) between 18 and 22;
#6.从student表中查询每个院系有多少人
select distinct department 院系,count(*) 人数 from student group by department;
#7.从score表中查询每个科目的最高分
select c_name 课程名,max(grade) from score group by c_name;
#8.查询李四的考试科目(c_name)和考试成绩(grade)stu和sco是我取的别名
select stu.name 姓名,sco.c_name 考试科目,sco.grade 成绩 from student stu,score sco where stu.id=sco.stu_id and stu.name='李四';
#9.用连接的方式查询所有学生的信息和考试信息
select * from student left join score on student.id =score.stu_id;
#10.计算每个学生的总成绩
select student.name,sum(score.grade) from student,score where student.id=score.stu_id group by student.name;
#11.计算每个考试科目的平均成绩
select c_name 科目,sum(grade)/count(grade) 平均分 from score group by c_name;
#12.查询计算机成绩低于95的学生信息
select student.* from student,score where student.id = score.stu_id and score.grade<95 and score.c_name='计算机';
#13.查询同时参加计算机和英语考试的学生的信息 ==多种方式
select stu.* from student stu,score s1,score s2 where stu.id=s1.stu_id and s1.c_name='计算机' and stu.id=s2.stu_id and s2.c_name='英语';
#14.将计算机考试成绩按从高到低进行排序
select * from score where c_name = '计算机' order by grade desc;
#15.从student表和score表中查询出学生的学号,然后合并查询结果
select id from student
union
select stu_id from score;
#16.查询姓张或者姓王的同学的姓名、院系和考试科目及成绩======稍微难点的查询
select student.name 姓名,student.department 院系,score.c_name 课程,score.grade 成绩 from student,score where student.id=score.stu_id and (student.name like '张%' or name like'王%');
#17.查询都是湖南的学生的姓名、年龄、院系和考试科目及成绩
select student.name 姓名,(2020-student.birth) 年龄,student.department 院系,score.c_name 考试科目,score.grade from student,score where student.id =score.stu_id and student.address like '湖南%'