Mysql学习资料

Mysql学习资料

设计表

1.t_aug_dept(部门表)

FieldTypeNullkeyDefaultcomment
deptNoint(2)noprinull部门编号
dnamevarchar(14)yesnull部门名字
locvarchar(13)yesnull地理位置

建表语句:

CREATE TABLE t_aug_dept(
    deptNo INT(2) NOT NULL PRIMARY KEY COMMENT '部门编号',
    dename VARCHAR(14) COMMENT '部门名字',
    loc VARCHAR(13) COMMENT '地理位置'
)ENGINE = INNODB DEFAULT CHARSET = UTF8;

数据插入语句:

INSERT INTO t_aug_dept (deptNo,dname,loc) VALUES
(10,'ACCOUNTING','NEW YORK'),
(20,'RESARCH','DALLAS'),
(30,'SALES','CHICAGO'),
(40,'OPERATIONS','BOSTON');

2.t_aug_emp(员工表)

FieldTypeNullkeyDefaultcomment
empNoint(4)noprinull员工编号
eNamevarchar(10)yesnull员工姓名
jobvarchar(9)yesnull工作岗位
mgrint(4)yesnull上级编号
hiredatedateyesnull入职日期
saldouble(7,2)yesnull工资
commdouble(7,2)yesnull补助
deptNoint(2)yesnull部门编号

建表语句:

CREATE TABLE t_aug_emp(
    empNo INT(4) NOT NULL COMMENT '员工编号',
    emName VARCHAR(10) COMMENT '员工姓名',
    job VARCHAR(9) COMMENT '工作岗位',
    mgr INT(4) COMMENT '上级编号',
    hiredate DATE COMMENT '入职日期',
    sal DOUBLE(7,2) COMMENT '工资',
    comm DOUBLE(7,2) COMMENT '补助',
    deptNo INT(2) COMMENT '部门编号',
    PRIMARY KEY  (empNo)
)ENGINE = INNODB DEFAULT CHARSET = UTF8;

数据插入语句:

INSERT INTO t_aug_emp (empNo,ename,job,mgr,hiredate,sal,comm,deptno) VALUES
(7369,'SMITH','CLERK',7902,'1980-12-17',800.00,NULL,20),
(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600.00,300.00,30),
(7521,'WARD','SALESMAN',7698,'1981-02-22',1250.00,500.00,30),
(7566,'JONES','MANAGER',7839,'1981-04-02',2975.00,NULL,20),
(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250.00,1400.00,30),
(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850.00,NULL,30),
(7782,'CLARK','MANAGER',7839,'1981-06-09',2450.00,NULL,10),
(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000.00,NULL,20),
(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000.00,NULL,10),
(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500.00,0.00,30),
(7876,'ADAMS','CLERK',7788,'1987-05-23',1100.00,NULL,20),
(7900,'JAMES','CLERK',7698,'1981-12-03',950.00,NULL,30),
(7902,'FORD','ANALYST',7566,'1981-12-03',3000.00,NULL,20),
(7934,'MILLER','CLERK',7782,'1982-01-23',1300.00,NULL,10);

3.t_aug_salgrade(薪资表)

FieldTypeNullkeyDefaultcomment
gradeint(11)yesnull工资等级
losalint(11)yesnull最低工资
hisalint(11)yesnull最低工资

建表语句:

CREATE TABLE t_aug_salgrade(
    grade INT(11) NOT NULL COMMENT '工资等级',
    losal INT(11) NOT NULL COMMENT '最高工资',
    hisal INT(11) NOT NULL COMMENT '最低工资'
)ENGINE = INNODB DEFAULT CHARSET = UTF8;

数据插入语句:

INSERT INTO t_aug_salgrade (grade,losal,hisal) VALUES
(1,700,1200),
(2,1201,1200),
(3,1401,1400),
(4,2001,2000),
(5,3001,9999);

常用语句
  • 连接mysql(windows命令行窗口):mysql -uUser -pPwd

  • 创建数据库:create database mysqlStudy;

  • 删除数据库:drop database mysqlStudy;

  • 选择数据库:use mysqlStudy;

  • 导入数据(需要先创建数据库):source D:\mysqlStudy.sql

  • 导出数据库所有表(windows命令行窗口):mysqldump mysqlStudy>D:\mysqlStudy.sql -uUser -pPwd

  • 查看数据库中所有表:show tables;

  • 查看表结构语句:desc 表名;

  • 查看mysql数据库的版本号:select version();

  • 查看当前使用的数据库:select database();

  • 查看建表语句:show create table 表名;

  • 查看数据库所支持的存储引擎(mysql命令行窗口):show engines \G

  • 设置事务隔离等级:set global transaction isolation level 隔离等级;

  • 查看事务隔离等级:SELECT @@tx_isolation;

  • 创建索引:create index 索引名称 on 表名(字段名);

  • 删除索引:drop index 索引名称 on 表名;


SQL的分类

数据查询语言(DQL-Data Query Language)

代表关键字:select

数据操纵语言(DML-Data Manipulation Language)

代表关键字:insert, delete, update

数据定义语言(DDL-Data Definition Language)

代表关键字:create, drop, alter

事务控制语言(TCL-Transaction Control Language)

代表关键字:commit, rollback

数据控制语言(DCL-Data Control Language)

代表关键字:grant, revoke


DQL语句
单表查询

注:关键字后的数字为语句执行顺序

select(5)

字段名1 code1, t2.字段名2 as code2, t3.字段名3 as 'code 3'......

from(1)

表名1

where(2)

查询条件

group by(3)

分组字段

having(4)

查询条件

order by(6)

字段1 asc(默认)/desc,字段2 asc(默认)/desc

limit(7)

起始下标, 长度

多表查询(连接查询)

查询分类

1、根据语法年代分类:

SQL92:1992年的时候出现的语法

##查询员工名字和部门名字
SELECT t1.ename,t2.dname
FROM t_aug_emp t1,t_aug_dept t2
WHERE t1.`deptNo` = t2.`deptNo`;

SQL99:1999年的时候出现的语法

##查询员工名字和部门名字
SELECT t1.ename,t2.dname
FROM t_aug_emp t1
INNER JOIN t_aug_dept t2
ON t1.`deptNo` = t2.`deptNo`;
  • SQL92结构不清晰,和后期进一步的筛选条件都放到了where后面

  • SQL99结构较清晰,表连接的条件时独立的,如果需要进一步筛选,再往后继续添加where

2、根据表连接的方式分类:

内连接(无主次关系,不匹配的记录不能查询出来):

等值连接(条件为等量关系)

##查询员工名字和部门名字
SELECT t1.ename,t2.dname
FROM t_aug_emp t1
INNER JOIN t_aug_dept t2
ON t1.`deptNo` = t2.`deptNo`;

非等值连接(条件非等量关系)

##查询员工名字,薪水和薪水等级
SELECT e.ename, e.sal, s.grade
FROM t_aug_emp e
JOIN t_aug_salgrade s
ON e.`sal` BETWEEN s.`losal` AND s.`hisal`;

自连接

==自连接技巧:一张表看作两张表==

##查询员工名字和其对应领导名字
SELECT t1.ename as ename, t2.ename as leaderName
FROM t_aug_emp t1
JOIN t_aug_emp t2
ON t1.`mgr` = t2.`empNo`;

外连接(有主次关系,主表的数据全部查询出来):

左(外)连接(左表为主表)

##查询员工名字和部门名字
SELECT t1.ename,t2.dname
FROM t_aug_emp t1
LEFT OUTER JOIN t_aug_dept t2
ON t1.`deptNo` = t2.`deptNo`;

右(外)连接(右表为主表)

##查询员工名字和部门名字
SELECT t1.ename,t2.dname
FROM t_aug_emp t1
RIGHT OUTER JOIN t_aug_dept t2
ON t1.`deptNo` = t2.`deptNo`;

全连接(a表和b表均为主表)

子查询
  • select语句中嵌套select语句,被嵌套的select语句被称为子查询

##查询比最低工资高的员工姓名和员工薪水
##where子句中的子查询
SELECT ename, sal
FROM t_aug_emp
WHERE sal > (SELECT MIN(sal) FROM t_aug_emp);

##查询每个岗位的平均工资的薪资等级
##from子句中的子查询
SELECT t1.*, t2.grade
FROM 
	(SELECT job, AVG(sal) AS avgsal FROM t_aug_emp GROUP BY job) t1
JOIN 
	t_aug_salgrade t2
ON 
	t1.avgsal BETWEEN t2.`losal` AND t2.`hisal`;

##查询每个员工的员工名称和部门名称
##select子句中的子查询(注:对于select后面的子查询来说,这个子查询只能一次返回一条结果)
SELECT 
	t1.`eName`, (SELECT t2.dname FROM t_aug_dept t2 WHERE t1.`deptNo` = t2.deptno)
FROM 
	t_aug_emp t1;
union合并查询结果集
##union在进行结果集合并的时候,要求两个结果集的列数和数据类型相同
##示例一:
SELECT ename, job FROM t_aug_emp WHERE job = 'MANAGER'
UNION
SELECT ename, job FROM t_aug_emp WHERE job = 'SALESMAN';
##示例二:
SELECT COUNT(ename) FROM t_aug_emp
UNION
SELECT COUNT(deptno) FROM t_aug_dept
UNION
SELECT COUNT(grade) FROM t_aug_salgrade;
limit
##将查询结果集的一部分取出来,通常使用在分页查询中
##limit startIndex(起始下标[从0开始]),length(长度)
##分页公式->第pageNo页:limit (pageNo - 1) * pageSize, pageSize
SELECT 
	ename, sal 
FROM 
	t_aug_emp 
ORDER BY 
	sal DESC 
LIMIT 0,5;

查询条件
查询条件条件含义
=等于
<>或!=不等于
<小于
<=小于等于
>大于
>=大于等于
between...and...两个值之间,闭区间(注:使用时需遵循左小右大)
is null为null(注:null 不能使用 = 衡量)
is not null不为null
and并且
or或者
in包含,相当于多个or
not in不包含
not可以取非,主要用在 is 或 in 中
like模糊查询,支持%或_匹配
%匹配任意多个字符
_匹配一个字符
单行处理函数
函数含义示例
lower(字段名)转换小写SELECT LOWER(eName) FROM t_aug_emp;
upper(字段名)转换大写SELECT UPPER(eName) FROM t_aug_emp;
substr(被截取的字符串, 起始下标, 截取的长度)取子串(注:起始下标从1开始)SELECT ename,SUBSTR(ename,1,2) FROM t_aug_emp;
length取长度SELECT ename,LENGTH(ename) FROM t_aug_emp;
trim去空格SELECT TRIM(ename) FROM t_aug_emp;
str_to_date(字符串,日期格式)将字符串转换成日期INSERT INTO t_aug_emp (empNo,ename,hiredate) VALUES ('1111','Tom',STR_TO_DATE('01-01-1990','%d-%m-%Y'));
date_format格式化日期SELECT ename, DATE_FORMAT(hiredate, '%m/%d/%Y') AS sal FROM t_aug_emp;
format(数字, 格式)设置千分位SELECT ename, FORMAT(sal,'$999,999') AS sal FROM t_aug_emp;
case...when...then...when...then...else...endSELECT ename,job,sal,(CASE job WHEN 'MANAGER' THEN sal1.1 WHEN 'SALESMAN' THEN sal1.5 ELSE sal END) AS newsal FROM t_aug_emp;
round四舍五入SELECT ROUND(1234.567,2) FROM t_aug_emp;
rand()生成随机数SELECT RAND() FROM t_aug_emp;
ifnull(字段名,字面值)可以将null转换成具体值SELECT comm,IFNULL(comm,0) FROM t_aug_emp;

注:Mysql中日期格式=>%Y/m/d/h/i/s 年/月/日/时/分/秒 【now()为Mysql当前日期函数】

分组函数(多行处理函数)
函数含义示例
count(字段名)计数SELECT COUNT(ename) FROM t_aug_emp;
sum(字段名)求和SELECT SUM(sal) FROM t_aug_emp;
avg(字段名)平均值SELECT AVG(sal) FROM t_aug_emp;
max(字段名)最大值SELECT MAX(sal) FROM t_aug_emp;
mix(字段名)最小值SELECT MIN(sal) FROM t_aug_emp;
其他函数
函数含义示例
distinct去重SELECT DISTINCT ename,job FROM t_aug_emp;

注意事项
  • 取别名含空格方式:SELECT deptno '编 号',dname AS'名字',loc adress FROM t_aug_dept;

  • 字段可以使用数学表达式:SELECT ename,sal*12 AS '年薪' FROM t_aug_emp;

  • 查询条件含_等特殊字符需转义:SELECT ename FROM t_aug_emp WHERE ename LIKE '%_%';

  • 只要有null参与的数学运算,最终结果为null;

  • 分组函数自动忽略null值;

  • 分组函数不能直接使用在where条件后;

  • 分组函数在使用时必须先进行分组,然后才能使用。如果没有对数据进行分组,整张表默认为一组;

  • 分组函数可以组合起来一起用;

  • 在一条select语句中如果有group by语句,select后面的查询值只能跟参加分组的字段以及分组函数,其他的一律不能跟;在mysql中跟其他的字段无意义,在oracle中会报语法错误

  • having可以对分完组后的数据进一步过滤,having不能单独使用,不能代替where,必须和group by联合使用

  • distinct只能出现在所有字段的最前方,distinct出现在两个字段之前,表示两个字段联合去重

  • 笛卡尔积现象:两张表进行连接查询时,没有任何条件的限制

  • 表连接次数越多,效率越低,尽量避免表的连接次数

  • 一条sql中内连接和外连接可以混合,都可以出现

  • union的效率要比join高一些。对于表连接来说,每连接一次新表,则匹配次数满足笛卡尔积,成倍地翻;但是union可以减少匹配次数,在减少匹配次数的情况下,还可以完成两个结果集的拼接(union把乘法变成了加法)


DDL语句
建表的语法格式

##示例一(列级约束):

create table 表名(

字段名1 数据类型 [not null] [unique] [primary key] [auto_increment],

字段名2 数据类型 [foreign key] [comment],

字段名3 数据类型

)ENGINE = INNODB DEFAULT CHARSET = UTF8;

##示例二(表级约束):

##多个字段联合起来添加某一个约束

create table 表名(

字段名1 数据类型 [not null],

字段名2 数据类型,

字段名3 数据类型

[primary key(字段名1, 字段名2)] [unique(字段名1, 字段名2)]

)ENGINE = INNODB DEFAULT CHARSET = UTF8;

注:复制表>create table t_aug_emp2 as select * from t_aug_emp;

将查询结果插入到一张表>insert into 表名1 select * from 表名2;

删表的语法格式

drop table if exists 表名;

mysql中常见的数据类型
数据类型含义备注
varchar(255)可变长度字符会根据实际数据长度动态分配空间。节省空间,速度慢
char(255)固定长度字符串分配固定长度的空间去存储数据。使用不当可能会导致空间的浪费,速度快
int(11)数字中的整数型
bigint数字中的长整型
float单精度浮点型
double双精度浮点型
date短日期类型Mysql默认格式:%Y-%m-%d
datetime长日期类型Mysql默认格式:%Y-%m-%d %h:%i:%s
clob字符大对象最多可以存储4G的字符串【Character Large OBject】
blob二进制大对象专门用来存储图片、声音、视频等流媒体数据,需要使用IO流【Binary Large OBject】

DML语句
insert语法格式

##字段名和值要一一对应

insert into 表名 (code1,code2,code3) values

(value1,value2,value3),

(value1,value2,value3),

(value1,value2,value3);

update语法格式

update 表名 set 字段名1 = 值1, 字段名2 = 值2, 字段名3 = 值3 where 条件;

delete语法格式

delete from 表名 where 条件;

##删除表数据
##表中的数据被删除了,但是这个数据在硬盘上的真实存储空间不会被释放(DML)
##优点:支持回滚,后悔了可以再回复数据
##缺点:删除效率低
delete from 表名;

##表被一次截断,物理删除(DDL)
##优点:快速
##缺点:不支持回滚
truncate table 表名;

约束
约束类型

非空约束:not null

唯一性约束:unique

主键约束:primary key

外键约束:foreign key

检查约束:check(mysql不支持,oracle支持)

注意事项
  • 唯一性约束的字段不能重复,可以为null

  • not null只有列级约束,没有表级约束

  • unique 和not null可以联合使用(在mysql中联合使用,该字段自动变为主键)

  • 主键特征:主键字段值既不能为null,也不能重复

  • 复合主键:多个字段联合起来做主键(不建议使用复合主键,建议使用单一主键)

  • 一张表主键约束只能添加一个

  • 主键值一般都是数字,一般都是定长的(建议使用int,bigint,char等类型)

  • 外键值可以为null,但外键字段所引用的字段需要具有唯一性


存储引擎

存储引擎是一个表存储/组织数据的方式,不同的存储引擎,表存储数据的方式不一样

存储引擎类型
EngineSupportCommentTransactionsXASavepoints
InnoDBDEFAULTSupports transactions, row-level locking, and foreign keysYESYESYES
MRG_MYISAMYESCollection of identical MyISAM tablesNONONO
MEMORYYESHash based, stored in memory, useful for temporary tablesNONONO
BLACKHOLEYES/dev/null storage engine (anything you write to it disappears)NONONO
MyISAMYESMyISAM storage engineNONONO
CSVYESCSV storage engineNONONO
ARCHIVEYESArchive storage engineNONONO
PERFORMANCE_SCHEMAYESPerformance SchemaNONONO
FEDERATEDNOFederated MySQL storage engineNULLNULLNULL
存储引擎概述
存储引擎特征特点
MyISAM存储引擎使用三个文件表示每个表: --格式文件--存储表结构的定义(mytable.frm) --数据文件--存储表行的内容(mytable.MYD) --索引文件--存储表上的索引(mytable.MYI)--可被转换为压缩、只读表来节省空间 --不支持事务机制,安全性低
InnoDB存储引擎--每个InnoDB表在数据库目录中以.frm格式文件表示 --InnoDB表空间(tablespace)被用于存储表的内容【表空间存储数据+索引】 --提供一组用来记录事务性活动的日志文件 --用commit(提交)、savepoint 及 rollback(回滚)支持事务处理 --提供ACID兼容 --在mysql服务器崩溃后提供自动恢复 --多版本(MVCC)和行级锁定 --支持外键及引用的完整性,包括级联删除和更新--支持事务,可以保证数据的安全,效率不高 --不能压缩,不能转换为只读,所以不能很好地节省空间
Memory(Heap)存储引擎--在数据库目录内,每个表均以.frm格式的文件表示 --表数据及索引被存储在内存中(查询快) --表级锁机制 --不能包含Text或Blob类型的字段--数据存储在内存中,且行的长度固定,查询效率非常高 --数据和索引都存在内存中,关机之后数据消失,不安全
注意事项
  • ENGINE用来指定表存储引擎(mysql默认INNODB)

  • CHARSET用来指定表字符集编码格式(mysql默认UTF8)


事务

一个事务其实就是一个完整的业务逻辑(保证业务的安全)

事务开启了(start transaction):

insert...

insert...

delete...

update...

update...

事务结束了:

在事务执行过程中,每一条DML的操作都会记录到"事务性活动的日志文件"中。

在事务执行过程中,我们可以提交事务,也可以回滚事务。

提交事务(commit):

清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。

提交事务标志着事务的结束,并且是一种全部成功的结束。

回滚事务(rollback):

将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件。

回滚事务标志着事务的结束,并且是一种全部失败的结束。

事务的特性

A:原子性

说明事务时最小的工作单元,不可再分。

C:一致性

所有事务,要求在同一个事务中,所有操作必须同时成功,或者同时失败。

I:隔离性

A事务和B事务之间具有一定的隔离性。

D:持久性

事务最终结束的一个保障。事务提交,就相当于将没有保存到硬盘上的数据保存到了硬盘上。

事务的隔离级别

读未提交:read uncommitted(最低的隔离级别)

释义:事务A可以读到事务B未提交的数据。

特点:存在脏读现象。

读已提交:read committed

释义:事务A只能读到事务B提交之后的数据。

特点:解决了脏读现象,不可重复读。

可重复读:repeatable read

释义:事务A开启后,不管时多久,只要事务A不结束,每一次在事务A中读取到的数据都是一致的。即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是没有发生变化。

特点:解决了不可重复读,可能会出现幻影读现象。

序列化/串行化:serializable(最高隔离级别)

释义:表示事务排队,不能并发(事务同步)。

特点:解决了上三级事务的所有问题,每一次读取到的数据都是最真实的,效率最低。

##设置事务隔离等级
set global transaction isolation level 隔离等级;
##查看事务隔离等级
SELECT @@tx_isolation;

注意事项
  • 只有DML语句才有事务一说

  • 事务的本质:多条DML语句同时成功,或者同时失败

  • 假设所有的业务,只需要一条DML语句就能完成,那么就没必要存在事务机制

  • mysql默认情况下是支持自动提交事务的(自动提交)

  • oracle默认事务隔离级别为:read committed

  • mysql默认事务隔离级别为:repeatable read

  • 可重复读案例:银行总账统计


索引

索引是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制。

一张表的一个字段可以添加一个索引,也可以多个字段联合起来添加索引。

索引相当于一本书的目录,是为了缩小扫描范围而存在的以一种机制。

索引在mysql中是自平衡二叉树(B-Tree)数据结构。遵循左小右大原则存放,采用中序遍历方式遍历数据。

添加索引的条件:

  • 数据量庞大

  • 该字段经常出现在where的后面,以条件的形式存在

  • 该字段很少的DML操作(DML操作后,索引需要重新排序)

索引的创建和删除
##创建索引
CREATE INDEX emp_ename_index ON t_aug_emp(ename,job);
##删除索引
DROP INDEX emp_ename_index ON t_aug_emp;
##查看索引是否生效
EXPLAIN SELECT * FROM t_aug_emp WHERE ename = 'KING';
索引失效的情况
##模糊查询以%开始,索引失效
select * from t_aug_emp where ename like '%N';
##使用or的时候,索引失效(如果or两边的条件字段都有索引,则索引不失效)
select * from t_aug_emp where ename = 'SMITH' OR job = 'SALESMAN';
##使用复合索引的时候,没有使用左侧的列查找,索引失效
select * from t_aug_emp where job = 'SALESMAN';
##在where当中索引列参加了数学运算,索引失效
select * from t_aug_emp where sal + 1 = 800;
##在where当中索引列使用了函数,索引失效
select * from t_aug_emp where lower(ename) = 'smith';
索引类型

单一索引:一个字段上添加索引

复合索引:两个字段或者更多字段上添加为一个索引

主键索引:主键上添加索引

唯一性索引:具有unique约束的字段上添加索引

注意事项
  • 唯一性比较弱的字段上添加索引用处不大


视图

视图相当于一条sql的复制,视图对象可以看作是一张表,对视图对象进行操作会导致原表数据被操作

视图的创建和删除
##创建视图对象
create view dept2_view as select * from t_aug_dept2;

##删除视图对象
drop view dept2_view;

视图应用场景:假设有一条复杂的sql语句,而这条语句需要在不同的位置上反复使用,此时可以把这条复杂的sql语句以视图对象的形式创建,在需要使用这条sql语句的位置直接使用视图对象。大大简化了开发,并且利于后期维护,修改的时候只需要修改视图对象所映射的sql语句

注意事项
  • 只有DQL语句才能以view的形式创建(create view dept2_view as DQL)

  • 对视图对象的操作会导致原表被操作

  • 视图对象和表一样,存储在硬盘上

数据库设计三范式
三范式内容

第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分。

第二范式:建立在第一范式的基础上,要求所有非主键字段完全依赖主键,不要产生部分依赖。

第三范式:建立在第二范式的基础上,要求所有非主键字段直接依赖主键,不要产生传递依赖。

注意事项
  • 三范式的目的:避免表中数据的冗余,空间的浪费。

  • 多对多设计:多对多,三张表,关系表两个外键。

  • 一对多设计:一对多,两张表,多的表加外键。

  • 一对一设计(一张表字段太多):一对一,外键唯一。

注:数据库设计三范式式理论上的,实践和理论有时候有偏差,最终目的都是为了满足客户的需求,有时候会拿冗余换执行速度。因为在sql当中,表和表之间的连接次数越多,效率越低(笛卡尔积)。

有时候可能会存在冗余,但是为了减少表的连接次数,这样做也是合理的。对于开发人员来说,sql语句的编写难度也会降低。

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值