SQL的笛卡尔积简记

本文介绍了SQL中的笛卡尔积,包括其定义、产生原因及解决办法,并通过一个为员工分配权限的角色分配实例展示了如何在特定情况下利用笛卡尔积。笛卡尔积通常在缺少关联条件或Oracle误判执行计划时产生,解决方法包括检查关联条件和使用执行计划提示。
摘要由CSDN通过智能技术生成

SQL的笛卡尔积简记

摘要:

简单记录一下SQL中的笛卡尔积与简单应用;

1 什么是笛卡尔积?

/*
 * 什么是笛卡尔积?
 * 笛卡尔积:在SQL中的实现方式就是交叉链接(CROSS join) 所有连接方式都会
 * 生成临时笛卡尔积表;笛卡尔积是关系代数里的一个概念,表示两个表中的每一行数据任意组合.
 * 在实际应用中,笛卡尔积本身大多没有什么实际应用,只有两张表连接查询时加上限制条件,才会有意义
 */

2 笛卡尔积产生的原因

/*
 * 笛卡尔积产生的原因?
 * 1 表连接缺少关联条件;
 * 2 表连接有关联条件,但是oracle判断用笛卡尔积更快,也会出现笛卡尔积,这个时候要看实际执行速度;
 * oracle这样判断,一般是表比较小,这个时候要特别检查表的数据量是不是真的很少,以免oracle因为统计信息错误
 * 而误判
 */ 

3 解决笛卡尔积的方式

/*
 * 笛卡尔积的解决方案?
 * 1 针对 接缺少关联条件导致的笛卡尔积,一般业务是不会直接这么操作的,如果SQL是这样的需要查看SQL是否正确。
 * 2 针对有关联条件, oracle仍然采用了笛卡尔积的方式 有两种情况
		2.1 由于ORACLE判断作笛卡尔积,说明两表关联,至少有一张表是小表,查看执行计划的基数 这个指数如果与			  实际相同,则建议不作优化修改即可。
		2.2 如果查看执行计划的基数与实际基数不同,则由可能是oracle数据误判表的基数,则可采用hint方式,改				变SQL的执行过程。
 */

4 创造笛卡尔积

SELECT * FROM student s,course c
SELECT * from student CROSS JOIN course
##上面两种方式都可以出现笛卡尔积现象
# 查询结果:
#	stu_id	stu_username	stu_password	c_id	cla_id	c_id	c_name
1	"1"			"张三"		"123"			"1"		"1"		"1"		"数学"
2	"1"			"张三"		"123"			"1"		"1"		"2"		"语文"
3	"1"			"张三"		"123"			"1"		"1"		"3"		"英语"
4	"1"			"张三"		"123"			"1"		"1"		"4"		"物理"
5	"1"			"张三"		"123"			"1"		"1"		"5"		"化学"
6	"1"			"张三"		"123"			"1"		"1"		"6"		"生物"
7	"2"			"李四"		"234"			"2"		"2"		"1"		"数学"
8	"2"			"李四"		"234"			"2"		"2"		"2"		"语文"
9	"2"			"李四"		"234"			"2"		"2"		"3"		"英语"
10	"2"			"李四"		"234"			"2"		"2"		"4"		"物理"
11	"2"			"李四"		"234"			"2"		"2"		"5"		"化学"
12	"2"			"李四"		"234"			"2"		"2"		"6"		"生物"
13	"3"			"王五"		"258"			"2"		"1"		"1"		"数学"
14	"3"			"王五"		"258"			"2"		"1"		"2"		"语文"
15	"3"			"王五"		"258"			"2"		"1"		"3"		"英语"
16	"3"			"王五"		"258"			"2"		"1"		"4"		"物理"
17	"3"			"王五"		"258"			"2"		"1"		"5"		"化学"
18	"3"			"王五"		"258"			"2"		"1"		"6"		"生物"
19	"4"			"赵六"		"5689"			"3"		"1"		"1"		"数学"
20	"4"			"赵六"		"5689"			"3"		"1"		"2"		"语文"
21	"4"			"赵六"		"5689"			"3"		"1"		"3"		"英语"
22	"4"			"赵六"		"5689"			"3"		"1"		"4"		"物理"
23	"4"			"赵六"		"5689"			"3"		"1"		"5"		"化学"
24	"4"			"赵六"		"5689"			"3"		"1"		"6"		"生物"
25	"5"			"孙七"		"56896"			"[NULL]""3"		"1"		"数学"
26	"5"			"孙七"		"56896"			"[NULL]""3"		"2"		"语文"
27	"5"			"孙七"		"56896"			"[NULL]""3"		"3"		"英语"
28	"5"			"孙七"		"56896"			"[NULL]""3"		"4"		"物理"
29	"5"			"孙七"		"56896"			"[NULL]""3"		"5"		"化学"
30	"5"			"孙七"		"56896"			"[NULL]""3"		"6"		"生物"
31	"7"			"悟空"		"45899"			"4"		"2"		"1"		"数学"
32	"7"			"悟空"		"45899"			"4"		"2"		"2"		"语文"
33	"7"			"悟空"		"45899"			"4"		"2"		"3"		"英语"
34	"7"			"悟空"		"45899"			"4"		"2"		"4"		"物理"
35	"7"			"悟空"		"45899"			"4"		"2"		"5"		"化学"
36	"7"			"悟空"		"45899"			"4"		"2"		"6"		"生物"
37	"8"			"李四"		"234"			"2"		"2"		"1"		"数学"
38	"8"			"李四"		"234"			"2"		"2"		"2"		"语文"
39	"8"			"李四"		"234"			"2"		"2"		"3"		"英语"
40	"8"			"李四"		"234"			"2"		"2"		"4"		"物理"
41	"8"			"李四"		"234"			"2"		"2"		"5"		"化学"
42	"8"			"李四"		"234"			"2"		"2"		"6"		"生物"
43	"9"			"王五"		"258"			"2"		"1"		"1"		"数学"
44	"9"			"王五"		"258"			"2"		"1"		"2"		"语文"
45	"9"			"王五"		"258"			"2"		"1"		"3"		"英语"
46	"9"			"王五"		"258"			"2"		"1"		"4"		"物理"
47	"9"			"王五"		"258"			"2"		"1"		"5"		"化学"
48	"9"			"王五"		"258"			"2"		"1"		"6"		"生物"

发现所有行的数据相互组合出现了上述问题

5 实际中使用

/**
 * 一般情况下我们应该避免笛卡尔积的出现,因为如果两张表的数据有一个或一个以上的数据量比较大的时候,就会导致"数	据爆表"
 * 但是当两张表的数据都比较小的时候就可以使用笛卡尔积来解决问题.
 * */

需要给所有的Employee分配几个权限(Role)

-- 建表语句
create table employees
(
    empid int  primary key,
    empname varchar(20) not null
)
create table role
(
    roleid int  primary key,
    description varchar(50) not null
)
create table emp_role
(
    empid int ,
    roleid int
)
-- 插入数据
insert into employees values(1,'Jacky')
insert into employees values(2,'Wendy')
insert into employees values(3,'David')
insert into employees values(4,'Lucy');
insert into employees values(5,'Tom');
insert into employees values(6,'Ann');
insert into role values(1,'Create Training')
insert into role values(2,'Training')
insert into role values(3,'Manage Employee')
insert into role values(4,'Manage Deparement')
-- 使用笛卡尔积给用户赋予权限
# 操作前查询一下没有数据
select * from emp_role er

# 操作
INSERT INTO emp_role SELECT empid, roleid FROM employees e
CROSS JOIN roles r WHERE r.roleid IN(1,2)

# 操作后数据
#	empid	roleid
1	"1"		"1"
2	"1"		"2"
3	"2"		"1"
4	"2"		"2"
5	"3"		"1"
6	"3"		"2"
7	"4"		"1"
8	"4"		"2"
9	"5"		"1"
10	"5"		"2"
11	"6"		"1"
12	"6"		"2"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liu.kai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值