公开课Introduction to Data Science的关系数据库总结
来源:互联网 发布:it服务管理系统 编辑:程序博客网 时间:2024/05/16 18:42
最近在学习公开课 Introduction to Data Science
第二部分讲到关系数据库与关系代数(Relational Databases,Relational Algebra)
SQL与RA 的关系
下图表达了基本的SQL语句与关系代数的关系。
1. 选择selection, 负号σc(R) 表示查询表R中符合条件c的列,
例如 σSalary > 40000 (Employee) 表示
"select * from Employee where Salary > 40000"
2. 投影Projection, 负号Π A1,…,An (R) 表示查询表R中的A1... An列,
例如ΠName,Salary(Employee) 表示
“select Name, Salary from Employee;
3. 集合运算,符合R X S ,表示R与S做笛卡尔积(R中列与S总的列的所有组合)
例如J X P 表示
”select * from J,P;
如果J是一个2行3列的表,P是一个4行5列的表,那么结果是一个2*4行3+5列的表。
4. 连接Join, 条件连接,左连接,右连接
4.1 条件连接,符号R θ S, 表示RXS中符合条件θ的 组合,
例如
select * from J JOIN P ON J.id = P.id"
等同于
"select * from J,P where J.id = p.id"
注INNER JOIN 同JOIN相同。
4.2 左外连接R S, 表示列出R中与S中符合条件的组合,如果S中没有对应的项,则其值认为是null,
例如
select * from P LEFT OUTER JOIN ON P.age = J.age;
其中 LEFT OUTER JOIN 等同于LEFT JOIN.
4.3 右外链接,与左外链接相反.
5. Union 符号R1∪R2, 表示组合两个表,这两个表必须具有相同的格式,
例如
select age from P UNION (select age from J);
如果P中有两列age分别为(1,2), J中有两列age分被为(2,3) 那么结果就是(1,2,3) ,注意这里小区了重复的记录,使用UNION ALL 可以得到(1,2,2,3) 带有重复记录的所有结果。
6. intersection 符号R1∩R2, 表示列出R1与R2相同的记录,
R1 ∩ R2 = R1 – (R1 – R2) , R1 ∩ R2 = R1 θ R2 条件是记录相同。
7. difference 符号R1-R2, 表示列出R1中的在R2中查不到的记录
select * from P where age not in (select age from J);
SQL优化
下图表示相同的查询结果用不同的方法会有不同的耗时。
课程中讲到 SQL is what, not how。 意思是SQL 定义了我们需要的结果,而不是如数如何操作的? 实际上DB会在SQL上做一些优化比如 Sqlite 的 The SQLite Query Planner, Mysql 的 优化Optimization , 实际中还是需要手工优化的,当需要在多个表之间做操作的时候,比如下面的例子
表结构如下
CREATE TABLE `Frequency` ( `docid` varchar(255) NOT NULL DEFAULT '', `term` varchar(255) NOT NULL DEFAULT '', `count` int(11) DEFAULT NULL, PRIMARY KEY (`docid`,`term`),)
在课后作业similarity matrix 中需要计算两两文档的相似性,这个实际是一个矩阵运算(有意思的一点)。
1) 代码如下,用时1m22.042s
select x.docid,y.docid,sum(x.count*y.count)as count from Frequency x, Frequency y where x.term = y.term and x.docid < y.docid group by x.docid, y.docid ORDER BY count ASC;
2) 提交答案只需要,结果中的某一个, 用时 1m10.919s, 可以看出这里实际还是计算了所有文档的相似性后截取的,DB并没有优化。
select * from (select x.docid as a ,y.docid as b,sum(x.count*y.count)as count from Frequency x, Frequency y where x.term = y.term and x.docid < y.docid group by x.docid, y.docid ORDER BY count ASC)x where x.a="10080_txt_crude" and x.b="17035_txt_earn";
3) 手工将上面的where限定语句放入计算过程中, 用时0m0.005s
select * from (select x.docid as a ,y.docid as b,sum(x.count*y.count)as count from Frequency x, Frequency y where x.term = y.term and x.docid < y.docid and x.docid="10080_txt_crude" and y.docid="17035_txt_earn" group by x.docid, y.docid ORDER BY count ASC)x;
a)将上面的例子放入mysql 中 执行时间对比
sql代码sqlite执行时间mysql执行时间1)计算所相似性1m19.892s49m48.016s2)计算所有相似性,然后选择某对文档的值1m9.073s49m52.044s3)选择某对文档,计算相似性0m0.003s0m0.005s
可以看出 1),2) 之间差距不大,因为都对其计算了相似性,但是2),3)的差距非常大,可以看出DB不能在这种组合查询预判优化。
有意思的地方是mysql执行的时间比sqlite长很多。下面尝试去分析其原因。
b) 分析我们的SQL,可以看出我们需要查询列docid 和term ,创建INDEX, 然后去执行,
CREATE INDEX docid_index ON Frequency(docid);CREATE INDEX term_index ON Frequency(term);sql代码sqlite执行时间
mysql执行时间
1)计算所相似性1m56.473s7m36.114s2)计算所有相似性,然后选择某对文档的值1m39.954s7m51.956s3)选择某对文档,计算相似性0m0.003s0m0.007s计算结果中可以看出 sqlite 没有性能的提升,原因分析,因为原先的表就存在主键PRIMARY KEY (`docid`,`term`), sqlite对这个主键的处理分配到了每个column里面形成index,所以我们创建的index算是冗余的了?
MySQL带来了很大的性能提高,但是仍然跟sqlite有很大差距。这里MySQL默认使用的是InnoDB engine,InnoDB支持更多的功能,如transaction row lock,这样带来了并发性,但同时在影响了单任务的性能,这里受到影响的如下有一个query cache. 这个cache 有辅助在表不变化的情况下,执行相同query 会提高速度,比如我们执行两次SQL 2)语句,那么第二次用时0m0.006s就得到了结果,因为其从cache中直接找到了结果。
mysql> SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000018 |
| Waiting for query cache lock | 0.000004 |
| checking query cache for query | 0.000029 |
| checking permissions | 0.000004 |
| Opening tables | 0.000007 |
| init | 0.000010 |
| optimizing | 0.000004 |
| executing | 0.000011 |
| end | 0.000003 |
| query end | 0.000003 |
| closing tables | 0.000003 |
| freeing items | 0.000014 |
| logging slow query | 0.000002 |
| cleaning up | 0.000002 |
+--------------------------------+----------+
相关测试脚本
https://github.com/trumanz/coursera/tree/master/datasci/assignment_Relation_DB/performance_test
课后题答案
上传到了github
https://github.com/trumanz/coursera/tree/master/datasci/assignment_Relation_DB
- 公开课Introduction to Data Science的关系数据库总结
- 用于数据科学项目的公开数据库—19 Free Public Data Sets For Your First Data Science Project
- 看后总结(Introduction to Computer Science and Programming,MIT 600)
- Introduction to Data Mining
- Introduction to Big Data
- 【edX公开课】Introduction to Linux(Linux导论)笔记
- Key Points from "Introduce to Data Science"
- How to Get Started in Data Science
- AirbnB uses R to scale data science
- introduction to data oriented design
- An Introduction to Data Mining
- An Introduction to Data Mining
- An Introduction to Data Mining
- An Introduction to Data Mining
- An Introduction to Data Mining
- 6.00 Introduction to Computer Science and Programming lec1
- 6.00 Introduction to Computer Science and Programming lec2
- 6.00 Introduction to Computer Science and Programming lec3 & lec4
- 第二届SDN大赛--必答题2
- Oracle dump函数
- leetcode 22 -- Generate Parentheses
- 用户体验来源于深入实践
- C语言获取当前工作路径
- 公开课Introduction to Data Science的关系数据库总结
- U-Boot启动Linux过程
- strtok和strtok_r函数
- Cocos2d-x 3.4 之 消灭星星 > 第三篇(终) <
- 线程池的总结
- 错误1error LNK2019: 无法解析的外部符号 "public: __thiscall chain<int>::~chain<int>(void)" (??1?$chain@H@@QAE@
- hibernate必须的包下载以及各个包的作用
- android学习Activity笔记
- POJ 1042 Gone Fishing