CMU15445_learning
2023
03-27
初步完成了homework1 但是上传测试结果不理想
03-28
今天来找homework中的错误,争取这次满分通过测试.
03-29
完成project-0
03-30
project0 终于运行起来了,哭。
[TOC]
数据库基本介绍
SQL语句基础
SQL 中的基本数据类型
- char(n)
- varchar(n) 指定最长为n的字符串
- numeric(p,q) 一共有p位 q位位小数位
- int
- smallint
- real precision / double precision 单精度/双精度 浮点数
- float(n) 精度至少为n的浮点数
完整性约束 概念
- primary key 主键 主码 属性: 虽然在create table时是可选的,每个元组的主键的值是不能重复的。
1 | primary key (colunm) |
- foreign key reference: 外键
1 | foreign key (column) reference (table) |
- not null 非空
1 | create table stus( |
==sql 禁止破环完整性约束的操作出现==
如果任意一条插入到当前关系中的元组有违反完整性约束的条件存在 sql就会报错。
sql 插入元组操作
1 | insert into (table) values ([v1,[v2,[v3...]]]); |
sql 删除一个关系(表)中所有元组操作
1 | delete from table_name; # 这种方式会保留表(关系)可以继续对这个表进行操作 |
sql 删除关系操作(删除表?)
1 | drop table table_name; # 删除关系 |
drop 删除了一个table 和这个table相关的外键会怎样呢?
sql 为关系增加/删除 属性
1 | alter table table_name add (column_name) (column_domain); # 属性的域就是数据类型吧 |
1 | alter table table_name drop (column_name); |
SQL 查询操作
查询操作简介
在一个关系上进行“查询操作”将查询结果构建成一个关系 作为返回。=> 关系
单关系查询
多关系查询
SQL index 索引
SQL AGGREGATES 聚集函数
作用将从结果中计算整个集合中的一些类似 sum average 这样的函数
聚集函数最后返回的是一个值,你得保证这次查询的东西都在这个结果中
- AVG() 支持DISTINCT
- MIN()
- MAX()
- SUM() 支持DISTINCT
- COUNT() 支持DISTINCT
- count(*) 是有优化的 这个更快!
1 | select count(distinct column_name) from table_name where column_name like "正则"; |
GROUP BY + 聚集函数的使用技巧
HAVING
ORDER BY
ASC
DESC
SQL中的模糊查询
使用LIKE 以及 正则匹配来进行模糊查询(匹配)
SQLite JOIN
交叉连接 CROSS JOIN
将第一个表的每一行与第二个表的每一行进行匹配 假设两个表是x y行,那么输出就是x*y行
语法示例
1 | SELECT * FROM T1 CROSS JOIN T2; |
内连接
和cross join差不多,但是在连接两个表的时候对每一次的匹配进行比较,当满足连接谓词的时候才会形成一个结果行。
语法示例
1 | SELECT * FROM T1 (INNER) JOIN T2 ON condition; |
自然连接
1 | SELECT * FROM T1 NATURAL JOIN T2; |
外连接
UNION 操作
UNION
UNION
是一种操作符,它用于将两个或多个SELECT
语句的结果集合并为一个结果集。具体来说,UNION
操作符会将多个SELECT
语句的结果集合并成一个结果集,并自动去除其中的重复行。
1 | SELECT column1, column2, ... FROM table1 |
UNION ALL
是一种用于将两个或多个SELECT
语句的结果集合并为一个结果集的操作符。它与UNION
操作符不同的是,它不会自动去除结果集中的重复行,而是将所有的行都保留下来。
1 | SELECT column1, column2, ... FROM table1 |
递归查询
递归查询的结构
- 初始查询
- 递归查询
CMU15445-HomeWork-1
==任务==:写sql脚本,使用sql语句在IMDb dataset里面查询/完成指定任务
环境配置
本机环境:VMware ==Ubuntu 22.04.2 server==
- 安装sqlite3
1 | # 查看当前linuxOS 是否默认安装了sqlite3 |
- 下载数据
1 | > wget https://15445.courses.cs.cmu.edu/fall2022/files/imdb-cmudb2022.db.gz |
- (可选) 检查数据的完整性
- 给各个表创建索引
- 了解数据中的各个表
people
title
akas
- rating
- crew
TIPS:
本次作业中,将title表称作 works
在akas表中不会使用
region
,types
,attributes
或者is_original_title
对于crew表,不会使用
job
orcharacters
,当考虑一个人的职责的时候指的就是category
作业准备
placeholder folder 的构建
1 | $ mkdir placeholder |
Q1 [0 point] 提交示例
例如按照如下的sql代码为样例写你的作业。
Q2 [5 points] 找最长时间sci_fi
要求:
- 10个最长时间的works grenre 是SCI_FI
- 输出 title premiere date(首映日期) 电影时长+(min)
1 | SELECT primary_title, premiered, CAST(runtime_minutes AS VARCHAR) || "(mins)" |
不会是少了一个空格吧
1 | SELECT primary_title, premiered, CAST(runtime_minutes AS VARCHAR) || " (mins)" |
如何在输出的东西上任意添加想要附加的字符串?
将int类型的数据映射成字符串 CAST()然后使用字符串连接符号 || 连接
Q3 [5 points] 最老的人
要求:
- 这些人需要在1900年之后出生
- 你需要考虑没死的人
- 输出:首先按照年龄排序,相同年龄按照名字的字典序排序
- 输出20个结果 并且按照 name|age 的格式输出
分析:
显然考察的是运算操作。people中born的字段是int died字段也一样。先看没死的人died是不是null
如何计算没死的人的年龄 并将他们放到一起
1 | CASE |
1 | SELECT name, |
可能是时间上出错了 今年是2023年
1 | SELECT name, |
Q4 [10 points] 出现次数最多的人
要求:
- 出现次数最多的人
- 输出格式 name 出现次数
- 最多的前20人
分析:
- 将titles 和 crew join到一起
1 | SELECT p.name,count(p.person_id) AS appear_times |
- 使用inner join 也是一个不错的选择
1 | SELECT name,count(*) AS appear_times |
出错原因:有些细节没注意。
Q5 [10 points]
要求:
- 每十年的平均评分、最高评分、最低评分、上映的电影数量
- 按照平均评分降序排序,同分按照年份升序排序,average rating 保留两位小数
分析:
- 将rating 和 title做一个inner join
1 | SELECT |
sqlite 整除 / 就是整除
sqlite 保留n位小数 round
sqlite 取整 ceil floor
Q6 [10 points] 找人
要求:
- 一个人 名字里有 Cruise 生于1962
- vote 数量最多的作品 前十
- 输出格式: 作品名称 | 投票数
分析:
- 多表联合查询
1 | SELECT t.primary_title,votes |
感觉有点慢
1 | WITH cruise_movies AS ( |
Q7 [15 points] 找特定年份的数据
要求:
- 找和Army of Thieves同年上映的电影数量
- 输出这一年的电影数量
分析:
- 嵌套查询、子查询
1 | SELECT COUNT(DISTINCT title_id) |
Q8 [15 points]
要求:
- 找到所有与Nicole Kidman (1967 出生的) 共同出演的演员
- 将所有的actor / actress按照名字的字典序排序
with 前置条件的运用
分析(过程):
- 首先将这个人的出演过的作品id列出
- 通过这个作品id查所有出现过的人的person -id (使用distinct去重)
- 查people表找上述person-id里面的人的名字
1 | SELECT title_id |
1 | WITH kidman_titles AS ( |
Q9 [15 points]
要求:
- 出生于1955年的演员
1 | WITH actors_and_movies_1955 AS ( |
Q10 [15 points]
要求:
- 使用逗号和空格连接TV 龙之家族的 所有unique titles 这些titles必须要按照字典序来
1 | with p as ( |
完成后将sql文件打包
1 | $ zip -j submission.zip placeholder/*.sql |
CMU15445-PROJECT-0
project-0 任务介绍
目标:
implement a key-value store backed by a concurrent trie
环境搭建:
使用的是本地的VMware里面的Ubuntu server 22.04.x版本的
IDE:CLion 通过ssh连接虚拟机
前置知识的学习
trie也叫 前缀树、字典树。之前没接触过。先做一下leetcode上的有关前缀树的定义的题目熟悉一下前缀树
前缀树
数据结构
is_end bool 表示是否是单词的结束 true表示当前节点为单词的结束
map
1 | class Trie { |
左值、右值、左值引用、右值引用
左值:可以放在赋值号的左边充当被赋值的对象,也可以在右边做赋值对象,充当左值的“东西”必须要有在内存上的存储空间。
右值:智能在赋值号的右边,做赋值对象,可以没有存储空间,可以只是一个在cpu寄存器上的一个数据。右值不能被修改
左值引用:引用的是一个对象。
右值引用:引用的是一个数据。这个只能作为右值,他不在内存上占有存储空间。
作用用来提高程序运行效率,避免多余的拷贝操作。
std::move() 将一个左值变为右值
使用临时对象使用的空间,赋值到目标对象中可以节省对内存的释放。
==例如==
1 | int main() { |
这个函数在程序结束时一共调用了四次析构函数
1 | Copy Assignment is called! source: Hello |
智能指针
unique_ptr()
独占资源所有权指针,该指针式moveonly的 也就是智能通过move函数将其给赋值到一个左值中
创建:
shared_ptr()
共享资源所有权指针
weak_ptr()
共享资源观察者
dynamic_cast
将一个基类的指针/引用 指向继承类的指针/引用,dynamic_cast将会判断该基类是否真的指向继承类,如果否则返回null 或者报错
Linux 一些命令的小记
创建目录:
1 | > mkdir path/directory-name |
创建文件:
1 | > touch path/file-name |
创建多个文件:
1 | > touch \ |
sqlite 执行sql文件