文章目录

  • 1、前言
  • 1.1、语句分类
  • 1.2、常用数据结构
  • 2、操作数据库及表
  • 3、增加、删除、修改(DML)
  • 4、查询(DQL,重点)
  • 1、查询指定字段
  • 2、As(别名)
  • 3、distinct(去重)
  • 4、表达式
  • 5、where条件语句
  • 逻辑操作符
  • 模糊查询
  • 5、联表查询(JOIN)
  • 5.1、INEER JOIN(内连接)
  • 5.2、左连接(LEFT JOIN)
  • 5.3、右连接(RIGHT JOIN)
  • 5.4、全连接(FULL JOIN)
  • 6、分页、排序
  • 6.1、分页(LIMIT)
  • 6.2、排序(ORDER BY)
  • 7、子查询或嵌套查询
  • 8、MySQL函数(count,sum...)
  • 9、分组过滤(GROUP BY,HAVING)
  • 10、三大范式


1、前言

1.1、语句分类

名称

解释

命令

DDL(数据定义语言)

定义和管理数据对象,如数据库,数据表等

CREATE、DROP、ALTER

DML(数据操作语言)

用于操作数据库中锁包含的数据

insert、update、delete

DQL(数据查询语言)

用于查询数据库

select

DCL(数据控制语言)

用于管理数据库的语言,包括管理权限及数据更改

GRANT、commit、rollback

1.2、常用数据结构

mysql_num_rows报错 mysqli_num_rows怎么使用_数据库

2、操作数据库及表

数据库:

  • create database 数据库名;创建数据库
  • use 数据库名;使用数据库
  • drop database 数据库名;删除数据库
  • show 数据库名;查看数据库

数据表
创建表:

create table [if not exists] `表名`(
    '字段名1' 列类型 [属性][索引][注释],
    '字段名2' 列类型 [属性][索引][注释],
    #...
    '字段名n' 列类型 [属性][索引][注释]
)[表类型][表字符集][注释];

实例:

-- 目标 : 创建一个school数据库
-- 创建学生表(列,字段)
 
CREATE TABLE IF NOT EXISTS `student` (
  `id` int(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
  `name` varchar(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
  `sex` varchar(2) NOT NULL DEFAULT '男' COMMENT '性别',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
  • COMMENT;注释
  • AUTO_INCREMENT;表示自增
  • ENGINE=InnoDB;选择引擎为InnoDB
  • DEFAULT CHARSET=utf8;编码格式

修改表:

  • ALTER TABLE 旧表名 RENAME AS 新表名:修改表名
  • ALTER TABLE 表名 ADD字段名 列属性[属性]:添加字段

修改字段 :

  • ALTER TABLE 表名 MODIFY 字段名 列类型[属性]:插入一个字段
    例:ALTER TABLE grade MODIFY newname VARCHAR(20) FIRST:(将字段newname插入到表的第一个位置)
  • ALTER TABLE 表名 CHANGE 旧字段名 新字段名 列属性[属性]:修改字段
  • ALTER TABLE 表名 DROP 字段名:删除字段

删除数据表:

  • DROP TABLE [IF EXISTS] 表名 IF EXISTS为可选 , 判断是否存在该数据表
    如删除不存在的数据表会抛出错误

其他:

1. 可用反引号(`)为标识符(库名、表名、字段名、索引、别名)包裹,以避免与关键字重名!中文也可以作为标识符!
 
2. 每个库目录存在一个保存当前数据库的选项文件db.opt。
 
3. 注释:
    单行注释 # 注释内容
    多行注释 /* 注释内容 */
    单行注释 -- 注释内容        (标准SQL注释风格,要求双破折号后加一空格符(空格、TAB、换行等))
    
4. 模式通配符:
    _    任意单个字符
    %    任意多个字符,甚至包括零字符
    单引号需要进行转义 \'
    
5. CMD命令行内的语句结束符可以为 ";", "\G", "\g",仅影响显示结果。其他地方还是用分号结束。delimiter 可修改当前对话的语句结束符。
6. SQL对大小写不敏感 (关键字)
7. 清除已有语句:\c

3、增加、删除、修改(DML)

增加(insert):

INSERT INTO 表名[(字段1,字段2,字段3,...)] VALUES('值1','值2','值3')

示例:

insert into `user`(id,username) values (1,'好好玩')

修改(update):

UPDATE 表名 SET column_name=value [column_name2=value2,...] [WHERE condition];

示例:

UPDATE student set address='上海',name='很好' WHERE id=1009
-- 修改id=1009的那行,多个修改用逗号隔开

删除(delete):

DELETE FROM 表名 [WHERE condition];

示例:

-- 删除数据(不推荐,会删除所有数据)
delete from `user`

-- 删除id=1005以及id=1023的数据
delete from student where id=1005 or id=1023

truncate 命令:
作用:清空表的数据,表的结构、索引、约束不会变

TRUNCATE [TABLE] table_name;

示例:

-- 清空学生表
TRUNCATE student

delete 与 truncate的区别:

  • 相同:都能删除表的数据且不删除表的结构,但是truncate更快
  • 不同:使用truncate会重置自增,且不会对事务有影响

4、查询(DQL,重点)

select语法:

SELECT [ALL | DISTINCT]
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
FROM table_name [as table_alias]
    [left | right | inner join table_name2]  -- 联合查询
    [WHERE ...]  -- 指定结果需满足的条件
    [GROUP BY ...]  -- 指定结果按照哪几个字段来分组
    [HAVING]  -- 过滤分组的记录必须满足的次要条件
    [ORDER BY ...]  -- 指定查询记录按一个或多个条件排序
    [LIMIT {[offset,]row_count | row_countOFFSET offset}];
    --  指定查询的记录从哪条至哪条,分页
--  [ ] 括号代表可选的 , { }括号代表必选得

1、查询指定字段

-- 查询所有学生信息
select * from student

-- 查询指定字段(查询学生表中的id和name字段)(id,name)
select id,name from student

2、As(别名)

作用:可以给数据列或者表取一个新别名,后续可以使用这个新别名代替数据列或者表名

-- 为列取别名(as可以省略)
SELECT studentid AS 学id,studentname AS nameFROM student;
 
-- 为表取别名(as可以省略)
SELECT studentid AS id,studentname AS name FROM student AS s;
 
-- 使用as,为查询结果取一个新名字
-- CONCAT()函数拼接字符串
SELECT CONCAT('姓名:',studentname) AS 新姓名 FROM student;

3、distinct(去重)

作用:去掉SELECT查询返回的记录结果中重复的记录 ( 返回所有列的值都相同 ) , 只返回一条

-- 查看哪些同学参加了考试(学号)  去除重复项
--  查看哪些同学参加了考试,但是学生id可能重复
SELECT studentid FROM score; 

-- 了解:DISTINCT 去除重复项 , (默认是ALL)
SELECT DISTINCT studentid FROM score;

4、表达式

-- selcet查询中可以使用表达式
SELECT @@auto_increment_increment; -- 查询自增步长
SELECT VERSION(); -- 查询版本号
SELECT 100*3-1 AS 计算结果; -- 表达式
 
-- 学员考试成绩集体提分一分查看
SELECT studentid,studentscore+1 AS '提分后' FROM score;

5、where条件语句

逻辑操作符

mysql_num_rows报错 mysqli_num_rows怎么使用_mysql_02

-- 满足条件的查询(where)
SELECT studentid,studentscore FROM score;
 
-- 查询考试成绩在95-100之间的,AND也可以写成 &&
SELECT studentid,studentscore
FROM score
WHERE studentscore>=95 AND studentscore<=100;
 
-- 除了1000号同学,要其他同学的成绩
SELECT studentid,studentscore
FROM score
WHERE studentid!=1000;
模糊查询

mysql_num_rows报错 mysqli_num_rows怎么使用_表名_03

-- 模糊查询
-- =============================================
-- LIKE :  % (代表0到任意个字符)  _ (一个字符)
-- 查询姓刘的同学的学号及姓名
SELECT studentid,studentname FROM student
WHERE studentname LIKE '刘%';
 
-- 查询姓刘的同学,后面只有一个字的
SELECT studentid,studentname FROM student
WHERE studentname LIKE '刘_';
 
-- 查询姓刘的同学,后面只有两个字的
SELECT studentid,studentname FROM student
WHERE studentname LIKE '刘__';
 
-- 查询姓名中含有 好 字的
SELECT studentid,studentname FROM student
WHERE studentname LIKE '%好%';
 -- =============================================
-- IN
-- 查询学号为1000,1001,1002的学生姓名
SELECT studentid,studentname FROM student
WHERE studentidIN (1000,1001,1002);

-- 查询地址在北京,南京,河南洛阳的学生
SELECT studentid,studentname,address FROM student
WHERE address IN ('北京','南京','河南洛阳');
-- =============================================
-- NULL 空   :  is null
-- 查询出生日期没有填写的同学
SELECT studentname FROM student
WHERE birthday IS NULL;

-- 查询出生日期填写的同学
SELECT studentname FROM student
WHERE birthday IS NOT NULL;

-- 查询没有写家庭住址的同学(空字符串不等于null)
SELECT studentname FROM student
WHERE Address='' OR Address IS NULL;

5、联表查询(JOIN)

七种join:

mysql_num_rows报错 mysqli_num_rows怎么使用_表名_04


现在有两张表A,B

A:

mysql_num_rows报错 mysqli_num_rows怎么使用_字段_05

B:

mysql_num_rows报错 mysqli_num_rows怎么使用_表名_06

5.1、INEER JOIN(内连接)

mysql_num_rows报错 mysqli_num_rows怎么使用_mysql_07


求的结果是A和B的交集

-- inner join 内连接
select A.name,subject,score
from A INNER JOIN B
ON A.studentid=B.studentid
-- 注意,在这里可以使用where,但是其他连接不能,只能使用on
-- 虽然结果一样

执行结果:

mysql_num_rows报错 mysqli_num_rows怎么使用_字段_08

5.2、左连接(LEFT JOIN)

mysql_num_rows报错 mysqli_num_rows怎么使用_表名_09


求的是表A中的所有值,在B中没有的会使用NULL代替

-- LEFT JOIN 左连接
select A.name,subject,score
from A LEFT JOIN B
ON A.studentid=B.studentid

执行结果:

mysql_num_rows报错 mysqli_num_rows怎么使用_表名_10

5.3、右连接(RIGHT JOIN)

mysql_num_rows报错 mysqli_num_rows怎么使用_数据库_11


求的是所有在表B中有的数据,若是在A中没有,则用NULL代替

-- RIGHT JOIN 右连接
select A.name,subject,score
from A RIGHT JOIN B
ON A.studentid=B.studentid

执行结果:

mysql_num_rows报错 mysqli_num_rows怎么使用_mysql_12

5.4、全连接(FULL JOIN)

mysql_num_rows报错 mysqli_num_rows怎么使用_表名_13


求的是A表和B表中的并集

6、分页、排序

6.1、分页(LIMIT)

作用:缓解数据库压力,给人的体验更好

语法 :

-- LIMIT m,n 从第m+1行开始,查询n条数据
SELECT * FROM table_name LIMIT 起始行,页面大小

示例:

-- 分页 LIMIT 0,3   :从第一行开始,查询3条
select * from B LIMIT 0,3

执行结果:

mysql_num_rows报错 mysqli_num_rows怎么使用_字段_14

6.2、排序(ORDER BY)

升序(ASC):

-- 升序 ASC
select * from B ORDER BY score ASC

执行结果:

mysql_num_rows报错 mysqli_num_rows怎么使用_mysql_15


降序(DESC):

-- 降序
select * from B ORDER BY score DESC

执行结果:

mysql_num_rows报错 mysqli_num_rows怎么使用_数据库_16

7、子查询或嵌套查询

本质就是在where里面嵌套一个查询语句,类似
where (select * from )

-- 子查询 查询参与了考试学生姓名与学号
SELECT studentid,`name` 
FROM A 
WHERE A.studentid in (
    SELECT studentid FROM B
    )

执行结果:

mysql_num_rows报错 mysqli_num_rows怎么使用_表名_17

8、MySQL函数(count,sum…)

-- ================ 内置函数 ================
 -- 数值函数
 abs(x)            -- 绝对值 abs(-10.9) = 10
 format(x, d)    -- 格式化千分位数值 format(1234567.456, 2) = 1,234,567.46
 ceil(x)            -- 向上取整 ceil(10.1) = 11
 floor(x)        -- 向下取整 floor (10.1) = 10
 round(x)        -- 四舍五入去整
 mod(m, n)        -- m%n m mod n 求余 10%3=1
 pi()            -- 获得圆周率
 pow(m, n)        -- m^n
 sqrt(x)            -- 算术平方根
 rand()            -- 随机数
 truncate(x, d)    -- 截取d位小数
 
 -- 时间日期函数
 now(), current_timestamp();     -- 当前日期时间
 current_date();                    -- 当前日期
 current_time();                    -- 当前时间
 date('yyyy-mm-dd hh:ii:ss');    -- 获取日期部分
 time('yyyy-mm-dd hh:ii:ss');    -- 获取时间部分
 date_format('yyyy-mm-dd hh:ii:ss', '%d %y %a %d %m %b %j');    -- 格式化时间
 unix_timestamp();                -- 获得unix时间戳
 from_unixtime();                -- 从时间戳获得时间
 
 -- 字符串函数
 length(string)            -- string长度,字节
 char_length(string)        -- string的字符个数
 substring(str, position [,length])        -- 从str的position开始,取length个字符
 replace(str ,search_str ,replace_str)    -- 在str中用replace_str替换search_str
 instr(string ,substring)    -- 返回substring首次在string中出现的位置
 concat(string [,...])    -- 连接字串
 charset(str)            -- 返回字串字符集
 lcase(string)            -- 转换成小写
 left(string, length)    -- 从string2中的左边起取length个字符
 load_file(file_name)    -- 从文件读取内容
 locate(substring, string [,start_position])    -- 同instr,但可指定开始位置
 lpad(string, length, pad)    -- 重复用pad加在string开头,直到字串长度为length
 ltrim(string)            -- 去除前端空格
 repeat(string, count)    -- 重复count次
 rpad(string, length, pad)    --在str后用pad补充,直到长度为length
 rtrim(string)            -- 去除后端空格
 strcmp(string1 ,string2)    -- 逐字符比较两字串大小
 
 -- 聚合函数
 count()    -- 返回满足条件的语句行数
 sum();     -- 求和
 max();     -- 最大值
 min();     -- 最小值
 avg();     -- 平均值
 
 -- 其他常用函数
 md5();     -- md5加密
 default();

9、分组过滤(GROUP BY,HAVING)

分组(GROUP BY):

-- 分组  GROUP BY
-- 查询每个科目的平均分
SELECT `subject`,AVG(`score`) 平均分 FROM B
GROUP BY `subject`

执行结果:

mysql_num_rows报错 mysqli_num_rows怎么使用_mysql_num_rows报错_18


过滤(HAVING):

当使用分组后需要过滤需要使用此语句

-- 查询语文的平均成绩
SELECT `subject`,AVG(`score`) 平均分 FROM B
GROUP BY `subject`
HAVING `subject`='语文'
-- 分组后过滤不能用where,只能用having

执行结果:

mysql_num_rows报错 mysqli_num_rows怎么使用_字段_19

10、三大范式

为什么需要数据规范化?

不合规范的表设计会导致的问题:

  • 信息重复:造成数据冗余,浪费空间
  • 更新异常:当使用外键时,更新可能发生异常
  • 插入异常:当使用外键时,插入可能发生异常
  • 删除异常:当使用外键时,删除可能发生异常

三大范式:
三大范式实际上就是我们创建数据库表的一种规范
我们常用的是第一范式(1NF)、第二范式(2NF)、第三范式(3NF),即“三大范式”

第一范式(1NF):要求每一列都是不可分割的原子数据项,例:

mysql_num_rows报错 mysqli_num_rows怎么使用_mysql_20


上表中的个人信息可以拆分为性别和年龄,如下:

mysql_num_rows报错 mysqli_num_rows怎么使用_表名_21


满足了第一范式第二范式(2NF):在第一范式的基础上,要求表中的每列都和主键相关,即每个表只完成一件事,例:

mysql_num_rows报错 mysqli_num_rows怎么使用_数据库_22


上表中,一个订单可能有不同的产品,所以此表的主键是订单号和产品号联合主键,但是从表中可发现,产品数量订单号和产品号有关,但订单金额仅和订单号有关,产品价格也仅与产品号有关,所以需要调整,才满足第二范式,如下:

mysql_num_rows报错 mysqli_num_rows怎么使用_字段_23


进行了分表之后,满足了第二范式第三范式(3NF):在第一、第二范式的基础上,要求每一列都和主键直接相关,而不是间接相关

mysql_num_rows报错 mysqli_num_rows怎么使用_mysql_num_rows报错_24


如上表,辅导员性别与主键学号并无直接关联,而是和辅导员直接关联,所以修改如下

mysql_num_rows报错 mysqli_num_rows怎么使用_数据库_25


分表之后,满足了第三范式