[关闭]
@SovietPower 2022-06-13T20:39:27.000000Z 字数 11181 阅读 1171

数据库 课后习题

DB



数据库常用关系代数符号:https://billc.io/2020/04/latex-relational-algebra/

.

第二章

2.14
a.
b.
c.
d.

2.15
a.
b.
c.

2.18
a.
b.
c.
d.
e.

第三章

3.11
a.

  1. select distinct ID, name
  2. from student natural join takes natural course
  3. where course.dept_name='Comp. Sci.'

b.

  1. select ID, name
  2. from student
  3. except
  4. select distinct ID, name
  5. from student natural join takes
  6. where year<2017

c.

  1. select dept_name, max(salary)
  2. from instructor
  3. group by dept_name

d.

  1. select min(max_salary)
  2. from (
  3. select dept_name, max(salary)
  4. from instructor
  5. group by dept_name ) as dept_salary(dept, max_salary)

3.12
a.

  1. insert into course
  2. values('CS-001', 'Weekly Seminar', 'Comp. Sci.', 0)

b.

  1. insert into section(course_id, sec_id, semester, year)
  2. values('CS-001', 1, 'Autumn', 2017)

c.

  1. insert into takes(ID, course_id, sec_id, semester, year)
  2. select ID, 'CS-001', 1, 'Autumn', 2017
  3. from student
  4. where dept_name='Comp. Sci.'

d.

  1. delete from takes
  2. where ID=12345 and course_id='CS-001'
  3. and sec_id=1 and semester='Autumn' and year=2017

e.

  1. delete from takes
  2. where course_id='CS-001'
  3. delete from section
  4. where course_id='CS-001'
  5. delete from course
  6. where course_id='CS-001'

因为section有引用course的外键约束,先删除course会导致违反完整性约束,删除失败。

f.

  1. delete from takes
  2. where course_id in
  3. select course_id
  4. from course
  5. where lower(title) like '%advanced%'

3.15
a.

  1. select ID, customer_name
  2. from customer
  3. except
  4. select C.ID, C.customer_name
  5. from customer as C
  6. where not exists(
  7. select branch_name
  8. from branch
  9. where branch_city='Brooklyn'
  10. except
  11. select branch_name
  12. from customer natural join depositor natural join account
  13. where customer.ID=C.ID )

b.

  1. select sum(amount)
  2. from loan

c.

  1. select branch_name
  2. from branch
  3. where assets > some(
  4. select assets
  5. from branch
  6. where branch_city='Brooklyn' )

3.16
a.

  1. select ID, person_name
  2. from employee natural join works natural join company

b.

  1. select E.ID, E.person_name
  2. from employee natural join manager_id as E, employee as M
  3. where E.manager_id=M.id
  4. and E.street=M.street and E.city=M.city

c.

  1. select ID, person_name
  2. from employee natural join works as E
  3. where E.salary > (
  4. select avg(salary)
  5. from works
  6. where company_name=E.company_name )

d.

  1. select company_name, sum(salary)
  2. from works
  3. group by company_name
  4. having sum(salary)<= all (
  5. select sum(salary)
  6. from works
  7. group by company_name )

第四章

4.15

  1. select *
  2. from section join classroom using (building, room_number)

4.16

  1. select ID
  2. from student natural left outer join takes
  3. where course_id is null

4.17

  1. select ID
  2. from student left outer join advisor on ID=s_ID
  3. where i_ID is null

第五章

5.12

  1. import java.util.Scanner;
  2. import static java.lang.System.out;
  3. // JDBC
  4. import java.sql.Connection;
  5. import java.sql.Statement;
  6. import java.sql.PreparedStatement;
  7. import java.sql.ResultSet;
  8. import java.sql.SQLException;
  9. import java.sql.DriverManager;
  10. // mysql
  11. import com.mysql.cj.exceptions.MysqlErrorNumbers;
  12. // class
  13. public class Exercise_5_12
  14. {
  15. static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
  16. static final String DB_URL = "jdbc:mysql://localhost:3306/db_exercise?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
  17. static Connection conn;
  18. public static void main(String... args)
  19. {
  20. // Connect to DB
  21. // a.
  22. Scanner scanner = new Scanner(System.in);
  23. int ret;
  24. if ((ret=ConnectDB(scanner))!=0)
  25. {
  26. while(ret == MysqlErrorNumbers.ER_ACCESS_DENIED_ERROR)
  27. {
  28. out.println("Invalid Password. Access denied.");
  29. ret = ConnectDB(scanner);
  30. }
  31. if (ret != 0) {
  32. Fail();
  33. return;
  34. }
  35. }
  36. // b.
  37. if (!TaskB(scanner)) {
  38. Fail();
  39. return;
  40. }
  41. // c.
  42. int id = TaskC(scanner);
  43. if (id == 0) {
  44. Fail();
  45. return;
  46. }
  47. // d.
  48. TaskD(id);
  49. // Finish and close conn and stmt
  50. CloseConnection(conn);
  51. out.println("\nfinish!");
  52. }
  53. static void Fail()
  54. {
  55. out.println("Operation failed. Please check your config.");
  56. }
  57. static boolean TaskB(Scanner scanner)
  58. {
  59. boolean done = false;
  60. ResultSet rs = null;
  61. PreparedStatement pStmt = null;
  62. out.print("\nB: type the name: ");
  63. while(true)
  64. {
  65. String query = scanner.next();
  66. try
  67. {
  68. pStmt = conn.prepareStatement(
  69. "SELECT id, name FROM instructor "+
  70. "WHERE lower(name) like ?"
  71. );
  72. pStmt.setString(1, "%"+query+"%");
  73. rs = pStmt.executeQuery();
  74. while(rs.next())
  75. {
  76. done = true;
  77. out.printf("%d %s\n", rs.getInt(1), rs.getString(2));
  78. }
  79. } catch (SQLException se) {
  80. se.printStackTrace();
  81. return false;
  82. } catch (Exception e) {
  83. e.printStackTrace();
  84. return false;
  85. }
  86. // out.println(pStmt.toString());
  87. if (done) break;
  88. out.println("No such ID found.");
  89. }
  90. CloseResultSet(rs);
  91. ClosePreparedStatement(pStmt);
  92. return true;
  93. }
  94. static int TaskC(Scanner scanner)
  95. {
  96. int ret = 0;
  97. ResultSet rs = null;
  98. PreparedStatement pStmt = null;
  99. out.print("\nC: type the ID: ");
  100. int query = scanner.nextInt();
  101. if (query<0 || query>99999)
  102. {
  103. out.println("Invalid id.");
  104. return 0;
  105. }
  106. try
  107. {
  108. pStmt = conn.prepareStatement(
  109. "SELECT id, name FROM instructor "+
  110. "WHERE id=?"
  111. );
  112. pStmt.setInt(1, query);
  113. rs = pStmt.executeQuery();
  114. if (rs.next())
  115. {
  116. ret = rs.getInt(1);
  117. out.printf("ID Found:\n%d %s\n", rs.getInt(1), rs.getString(2));
  118. }
  119. else
  120. out.println("No such name found. Program exiting.");
  121. } catch (SQLException se) {
  122. se.printStackTrace();
  123. } catch (Exception e) {
  124. e.printStackTrace();
  125. }
  126. CloseResultSet(rs);
  127. ClosePreparedStatement(pStmt);
  128. return ret;
  129. }
  130. static void TaskD(int id)
  131. {
  132. boolean ret = false;
  133. ResultSet rs = null;
  134. PreparedStatement pStmt = null;
  135. out.printf("\nD: checking ID: %d\n", id);
  136. try
  137. {
  138. pStmt = conn.prepareStatement(
  139. "WITH temp(course_id, sec_id, semester, year, cnt) AS "+
  140. "(SELECT course_id, sec_id, semester, year, count(*) "+
  141. "FROM teaches inner join takes using(course_id, sec_id, semester, year) "+
  142. "WHERE teaches.id=? "+
  143. "GROUP BY course_id, sec_id, semester, year) "+
  144. "SELECT dept_name, course_id, title, sec_id, semester, year, cnt "+
  145. "FROM course join temp using(course_id) "+
  146. "ORDER BY dept_name, course_id, year, semester"
  147. );
  148. pStmt.setInt(1, id);
  149. rs = pStmt.executeQuery();
  150. while (rs.next())
  151. {
  152. ret = true;
  153. out.printf("%s %s %s %d %s %d %d\n", rs.getString(1), rs.getString(2), rs.getString(3), rs.getInt(4), rs.getString(5), rs.getInt(6), rs.getInt(7));
  154. }
  155. } catch (SQLException se) {
  156. se.printStackTrace();
  157. } catch (Exception e) {
  158. e.printStackTrace();
  159. }
  160. CloseResultSet(rs);
  161. ClosePreparedStatement(pStmt);
  162. if (!ret)
  163. out.println("He/She hasn't taught any course yet.");
  164. }
  165. static int ConnectDB(Scanner scanner)
  166. {
  167. out.println("Input your username and password:");
  168. // String username = "root";
  169. // String password = "GXB";
  170. String username = scanner.next();
  171. String password = scanner.next();
  172. try
  173. {
  174. Class.forName(JDBC_DRIVER);
  175. conn = DriverManager.getConnection(DB_URL, username, password);
  176. }
  177. catch(SQLException se)
  178. {
  179. if (se.getErrorCode() != MysqlErrorNumbers.ER_ACCESS_DENIED_ERROR)
  180. se.printStackTrace();
  181. return se.getErrorCode();
  182. }
  183. catch(Exception e)
  184. {
  185. e.printStackTrace();
  186. return -1;
  187. }
  188. return 0;
  189. }
  190. static void CloseConnection(Connection conn)
  191. {
  192. try {
  193. if(conn!=null) conn.close();
  194. } catch(SQLException se) {
  195. se.printStackTrace();
  196. }
  197. }
  198. static void CloseStatement(Statement stmt)
  199. {
  200. try {
  201. if(stmt!=null) stmt.close();
  202. } catch(SQLException se) {
  203. se.printStackTrace();
  204. }
  205. }
  206. static void ClosePreparedStatement(PreparedStatement pStmt)
  207. {
  208. try {
  209. if(pStmt!=null) pStmt.close();
  210. } catch(SQLException se) {
  211. se.printStackTrace();
  212. }
  213. }
  214. static void CloseResultSet(ResultSet rs)
  215. {
  216. try {
  217. if(rs!=null) rs.close();
  218. } catch(SQLException se) {
  219. se.printStackTrace();
  220. }
  221. }
  222. }

5.18
修改call处的参数以查看结果。
使用//作为delimiter。

  1. drop procedure if exists find_name;
  2. create procedure find_name(in keyword varchar(64))
  3. begin
  4. select id, name
  5. from instructor
  6. where lower(name) like concat('%', keyword, '%');
  7. end
  8. //
  9. call find_name('ri');//
  10. drop procedure if exists print_error;
  11. create procedure print_error(in Message varchar(100))
  12. begin
  13. select 'Error', Message;
  14. end
  15. //
  16. drop procedure if exists query_teacher_by_id;
  17. create procedure query_teacher_by_id(in query int)
  18. begin
  19. declare res int;
  20. if (query<0 or query>99999) then
  21. call print_error("Invalid ID");
  22. else
  23. select id into res
  24. from instructor
  25. where id=query;
  26. if (res is null) then
  27. call print_error("No such id");
  28. else
  29. WITH temp(course_id, sec_id, semester, year, cnt) AS
  30. (SELECT course_id, sec_id, semester, year, count(*)
  31. FROM teaches inner join takes using(course_id, sec_id, semester, year)
  32. WHERE teaches.id=query
  33. GROUP BY course_id, sec_id, semester, year)
  34. SELECT dept_name, course_id, title, sec_id, semester, year, cnt
  35. FROM course join temp using(course_id)
  36. ORDER BY dept_name, course_id, year, semester;
  37. end if;
  38. end if;
  39. end
  40. //
  41. call query_teacher_by_id(10001);//

第六章

6.3

每场比赛参加的队员及其得分,用关系play表示。
派生属性:
参加比赛数played_match(): 统计该player_idplay中出现多少次。
比赛总得分total_score():统计该player_idplay中的得分之和。

6.20 b

6.23

第七章

7.31

只能推出,不能推出,所以不是超键。
因为,R变为
是BCNF。没有依赖和有关,所以也是BCNF。所以分解完成。
有关的依赖都需连接,所以不是保持依赖的。

判断BCNF好像错了,需要用F的闭包而不是F。所以应该用检测算法(检查所有属性子集)。
分解算法好像也不对?

7.32
a.
,该依赖去掉都不再成立,去掉则无法推出,去掉依然可以推出,所以可以去掉

b.
不成立,所以不是超键,由分为是BCNF。没有一个依赖的两边都属于,所以也是BCNF。

c. 无损。
成立,所以无损。

d. 不保持。
后两个依赖在单独模式都不能验证,所以不是保持依赖的。

7.33
a.
右侧都没有,所以一定包含于候选键。又因为是候选键,所以只有一个。

b.
1. 是无关属性,换为换为
2. 合并两个得到

c.
1. 令
2. 添加
3. 删除

d.

7.34
a. 。(少了ACEGH)
右侧都没有,所以一定包含于候选键。
再加一个可推出,再加一个可推出,所以有两个。

b.
1. 是无关属性,换为。同理换为换为
2. 不能再更改。

c.
1. 令
2. 添加
3. 删除

d.

第十四章 索引

叶节点之间都有连接,但叶子太多改起来很麻烦就不加了

1.
(1, 2, 5, 6, 8, 10, 18, 27, 32, 39, 41, 45, 52, 58, 73, 80, 91, 99)

delete 8.

delete 10.

insert 46.

delete 52

delete 32.

delete 39.

delete 41.

delete 45.

2.
(apple, pear, apricot, peach, grape, banana, pineapple, plum, watermelon, orange, lemon, mango, strawberry, medlar, mulberry, nectarine, cherry, pomegranate)


第十五章 查询处理

15.17
a.
块。
块。
第一阶段需次块传输,初始归并段数量个。
归并次数为
块传输数,寻道次数
块传输时间,寻道时间
代价

时:

时:

b.
时:

时:

c.
块传输时间,延迟时间

时:

时:

15.19
1. 将两棵B+树的叶子节点进行归并,结果文件包含两个关系的元组地址,其中值相同的元组地址会放在一起,在排序时会被一起移动。
2. 将结果文件按一个关系的元组地址进行排序(移动时一起移动值相同的另一个关系的元组地址),然后按顺序读取、将这些元组地址替换为实际的元组。此时结果文件包含已排序的元组和未排序的元组地址。
3. 然后同原算法,对另一个关系的元组地址再进行排序、按序读取。

15.20
设:
包含的块数分别为:

1. 设B+树每个叶节点最多包含索引 个。
总传输块数:
总寻道次数:
结果文件包含的块数

2.
为缓冲区最大用于排序的块数。
初始归并段数量个。
归并次数
按序读取、替换元组需要:按序读取原关系的元组、按序读取并写回每个排好序的块。因为交替取这两个块,所以每块都要寻道?
总传输块数:
总寻道次数:

3.
用到的和第二步的元组数量相同,所以排序代价相同。只不过最后替换时不用写回。
总传输块数:
总寻道次数:

第十七章

17.15
$$

17.20
$$

第十八章

18.12
$$

18.25
$$

18.27
$$

第十九章

19.21
$$

19.23
$$

19.25
$$

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注