数据库学习
2023-02-02;
1.候选码:若关系中的某一属性或属性组的值能唯一标识一个元组,则称该属性或属性组为候选码。
2023-02-21;
1.1NF:第一范式:若关系模式R的每一个分量都是不可再分的数据项,则关系模式R属于第一范式。记为R∈1NF。
2.1NF包含2NF包含3NF包含BCNF包含4NF包含5NF。
3.关系的描述称为关系模式(Relation Schema)。R(U,D,dom,F),通常简记为R(U)或R(A下标1,A下标2,A下标3,...A下标n),其中R为关系名,A下标1,A下标2,A下标3,...A下标n为属性名。
4.2NF:第二范式:若关系模式R∈1NF,且每一个非主属性完全依赖于码,则关系模式R属于2NF。即,当1NF消除了非主属性对码的部分函数依赖,则称为2NF。
5.依赖;
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>6.0.5</version> </dependency>
6.Spring优点:
6.1是一个开源的免费的框架(容器)!
6.2Spring是一个轻量级的、非入侵式的框架!
6.3控制反转(IOC),面向切面编程(AOP)!
6.4支持事务的处理,对框架整合的支持!
2023-02-22;
7.组成;
8.函数依赖:设R(U)是一个属性集U上的关系模式,X和Y是U的子集。若对于R(U)的任意一个可能的关系r,r中不可能存在两个元祖在X上的属性值相等,而在Y上的属性值不等,记作X->Y(备注,读作:X决定Y);
备注:可以结合函数的概念,y=f(x),对于每个x,都有唯一的y;
例如U={SNO, SNAME, AGE, DEPT},R(U)为:Student(SNO, SNAME, AGE, DEPT);sno决定sname,sno决定age,sno决定dept;sname不决定dept,例子:sname='李军',dept='CS';sname='李军',dept='IS';
9.3NF:第三范式:当2NF消除了非主属性对码的传递函数依赖,则称为3NF;
假定某学生关系表(学号,姓名,年龄,所在学院,学院地点,学院电话),关键字为“学号”,由于存在以下决定关系:
(学号)->(姓名,年龄,所在学院,学院地点,学院电话),所以是符合2NF的,可是不符合3NF,由于存在如下决定关系:
(学号)->(所在学院)->(学院地点,学院电话);存在非关键字段“学院地点”、“学院电话”对关键字“学号”的传递函数依赖。
10.现代化的Java开发!说白就是基于Spring的开发!
11.Spring Boot:一个快速开发的脚手架;基于Spring Boot可以快速开发单个微服务;约定大于配置;
12.Spring Cloud:是基于SpringBoot实现的;
13.因为现在绝大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及SpringMVC!
2023-02-23;
14.BCNF:关系模式R属于1NF,若X决定Y且Y不包含于X时,X必含有码,则关系模式R属于BCNF。
BCNF不是研究非主属性的。
若R属于BCNF,则每一个决定属性集(因素)都包含(候选)码。
例14.1:在关系模式STJ(S, T, J)中,S表示学生,T表示教师,J表示课程。
每个教师只教一门课。每门课由若干老师教,某一学生选某门课,就确定了一个固定的教师。某个学生选修某个教师的课就确定了所选课的名称:
(S, J)决定T,(S, T)决定J,T决定J。
(S, J)是码;(S, T)也是码。主属性的定义:构成候选码的属性,都是主属性。所以S, T, J都是主属性。连非主属性都没有,所以肯定是2NF。同样也没有非主属性对码的传递依赖,所以一定是3NF。但是,T决定J,而T不是码,所以不是BCNF。
例14.2:关系模式SJP(S, J, P),S是学生,J是课程,P是排名(这里假设每个学生每门课程的排名是不重复的,不会出现并列的情况);
函数依赖(S, J)决定P即学生和课程知道了排名就知道了,(J, P)决定S即课程和排名知道了学生就知道了,
(S, J)是码,(J, P)也是码,所以S, J, P都是主属性。所以一定是2NF,也一定是3NF。又因为同时满足“所有的决定因素都是码”,所以是BCNF。
15.Spring弊端:发展了了太久之后,违背了原来的理念!配置十分繁琐,人称:“配置地狱!”;
16.IOC理论推导;
16.1我们之前的:
16.1.1UserDao 接口;
16.1.2UserDaoImpl 实现类;
16.1.3UserService 业务接口;
16.1.4UserServiceImpl 业务实现类;
2023-02-24;
17.问题1;
(1)我的解答:业主关系的候选键:业主身份证号;
答案:我做错了。候选键是(房号,业主身份证号)。因为一个身份证号可能买了不止一套房。
(2)我的解答:是2NF;因为主键是一个属性“业主身份证号”;即,不存在非主属性对“业主身份证号”的部分函数依赖。
答案:我做错了。不是2NF。候选键(房号,业主身份证号)部分决定非主属性“房屋面积”。
(3)我的解答:A1(主键:业主身份证号;业主姓名,房号);A2(主键:房号;房屋面积);
答案:我做错了。分解后的关系模式:A1(主键:房号及业主身份证号),A2(主键:房号;房屋面积),A3(主键:业主身份证号;业主姓名)。
18.问题2;
(1)我的解答:车位编号以及使用年份;
答案:我做对了。
(2)我的解答:不是。因为存在非主属性(汽车品牌,汽车颜色)对码的传递函数依赖:车位编号决定车牌号,车牌号决定汽车品牌和汽车颜色;
答案:我做对了。
(3)我的解答:B1(主键:车位编号;房号,车牌号);B2(主键:车位编号及使用年份;费用);B3(主键:车牌号;汽车品牌,汽车颜色);
答案:答案里B1我没看明白,下次再看。B1(主键:使用年份;费用),B2(主键:车牌号;汽车品牌,汽车颜色),B3(主键:车位编号和使用年份;房号,车牌号)或B3(主键:使用年份和房号;车位编号,车牌号)或B3(主键:使用年份和车牌号;车位编号,房号)。
19.问题3;
我的解答:临时停车(主键:车牌号及进入小区时间;离开小区时间,停车时长,每小时单价,费用);车进入小区时新增记录,记录车牌号及进入小区时间、每小时单价,车离开时更新离开小区时间,计算停车时长、费用,更新记录;
答案:答案(主键:车牌号;进入时间,离开时间)。答案说是唯一主键是车牌号,我觉得答案错了。我认为主键应是车牌号及进入小区时间。因为临时车可能多次进入小区,有多条记录。
2023-02-25;
20.案例16.2.2;
问题1我缺少了下图中红线:投资方、创业公司和员工三方参与项目联系。
问题2:
我的回答:(a)所属公司代码;(b)投资方编号;
答案:我漏了这两个应该加上外键标识:(a)所属公司代码;(b)投资方编号;(备注:应该是分段的虚下划线,但是在这个编辑器里不好打出来);
问题3我答对了;
2023-02-26;
21.例题16.2.1;
问题2;我的解答:(1)球队编号;(2)球队编号;我答对了。
问题1和3我原版错误解答:
正确的E-R图:
2023-02-28;
22.建表SQL;
CREATE TABLE SUPPLIER ( supplier_no CHAR(5) NOT NULL UNIQUE, supplier_name CHAR(30) UNIQUE, supplier_status CHAR(8), city CHAR(20), PRIMARY KEY (supplier_no) ) ; CREATE TABLE PRODUCT ( product_no CHAR(6) NOT NULL UNIQUE, product_name CHAR(30) NOT NULL, color CHAR(8), weight NUMERIC (6, 2), origin_place CHAR(20), PRIMARY KEY (product_no) ) ; CREATE TABLE SUPPLIER_PRODUCT ( supplier_no CHAR(5), product_no CHAR(6), supplier_status CHAR(8), quantity NUMERIC (9), PRIMARY KEY (supplier_no, product_no), FOREIGN KEY (supplier_no) REFERENCES SUPPLIER (supplier_no), FOREIGN KEY (product_no) REFERENCES PRODUCT (product_no) ) ;
SQL已执行验证。
2023-03-01;
23.SQL基本域类型:
类型 | 说明 |
char(n) | 固定长度字符串,表示n个字符的固定长度字符串 |
varchar(n) | 可变长度字符串,表示最多可以有n个字符的字符串 |
int | 整型,也可以用integer |
smallint | 短整型 |
numeric(p,d) | 定点数p为整数位,d位小数位 |
real | 浮点型 |
double precision | 双精度浮点型 |
float(n) | n为浮点型 |
boolean | 布尔型 |
date | 日期型 |
time | 时间型 |
24.例16.1.2;
CREATE TABLE VENDING_MACHINE ( vending_machine_no CHAR(8) NOT NULL UNIQUE, location CHAR(30), PRIMARY KEY (vending_machine_no) ) ; CREATE TABLE GOODS ( good_no CHAR(8) NOT NULL UNIQUE, brand CHAR(8), price NUMERIC (5, 2), PRIMARY KEY (good_no) ) ; CREATE TABLE SALES ( sales_no CHAR(8) NOT NULL UNIQUE, vending_machine_no CHAR(8) NOT NULL, good_no CHAR(8) NOT NULL, sales_date DATE, sales_time TIME, PRIMARY KEY (sales_no), FOREIGN KEY (vending_machine_no) REFERENCES VENDING_MACHINE (vending_machine_no), FOREIGN KEY (good_no) REFERENCES GOODS (good_no) ) ; CREATE TABLE OUT_OF_STOCK ( vending_machine_no CHAR(8) NOT NULL, good_no CHAR(8) NOT NULL, sales_date DATE, sales_time TIME, PRIMARY KEY ( vending_machine_no, good_no, sales_date, sales_time ) ) ; CREATE TABLE SALES1 ( sales_no CHAR(8) PRIMARY KEY, vending_machine_no CHAR(8) REFERENCES VENDING_MACHINE (vending_machine_no), good_no CHAR(8) REFERENCES GOODS (good_no), sales_date DATE, sales_time TIME ) ;
SQL已验证。
2023-03-03;
25.例16.1.2问题2;
CREATE VIEW SALES_TOTAL(vending_machine_no, good_no, sales_date, amount) AS SELECT vending_machine_no, good_no, sales_date, COUNT(*) FROM SALES GROUP BY vending_machine_no, good_no, sales_date; CREATE VIEW SALES_DETAIL(vending_machine_no, location, good_no, brand, price, amount, sales_date) AS SELECT VM.vending_machine_no, VM.location, GOODS.good_no, GOODS.brand, GOODS.price, SALES_TOTAL.amount, SALES_TOTAL.sales_date FROM VENDING_MACHINE VM, GOODS, SALES_TOTAL WHERE SALES_TOTAL.vending_machine_no = VM.vending_machine_no AND SALES_TOTAL.good_no = GOODS.good_no;
我做时视图SALES_TOTAL定义里,GROUP BY语句,我漏了sales_date。
SQL已验证。
2023-03-06;
27.例16.1.2问题3;
原答案:
CREATE TRIGGER OUT_OF_STOCK_TRG AFTER INSERT ON SALES REFERENCING new row AS nrow FOR EACH ROW BEGIN INSERT INTO OUT_OF_STOCK SELECT SALES.vending_machine_no, SALES.good_no, SALES.sales_date, getTime() FROM SALES WHERE SALES.vending_machine_no = nrow.vending_machine_no AND SALES.good_no = nrow.good_no AND SALES.sales_date = nrow.sales_date GROUP BY SALES.vending_machine_no, SALES.good_no, SALES.sales_date HAVING count(*) > 0 AND mod(count(*), 10) = 0; END
MySQL验证:
DELIMITER $ CREATE TRIGGER OUT_OF_STOCK_TRG AFTER INSERT ON SALES FOR EACH ROW BEGIN INSERT INTO OUT_OF_STOCK SELECT SALES.vending_machine_no, SALES.good_no, SALES.sales_date, getTime() FROM SALES WHERE SALES.vending_machine_no = NEW.vending_machine_no AND SALES.good_no = NEW.good_no AND SALES.sales_date = NEW.sales_date GROUP BY SALES.vending_machine_no, SALES.good_no, SALES.sales_date HAVING count(*) > 0 AND mod(count(*), 10) = 0; END$ DELIMITER ;
删除触发器:
DROP TRIGGER OUT_OF_STOCK_TRG;
2023-04-10;
例16.1.2;
问题4;
/* 所有SELECT的字段,除聚合函数中的字段,都必须在GROUP BY中出现 */ SELECT GOODS.`good_no`, GOODS.`brand`, COUNT(*) FROM GOODS, SALES WHERE GOODS.`good_no` = SALES.`good_no` AND SALES.`sales_date` = CURDATE() GROUP BY GOODS.`good_no`, GOODS.`brand` HAVING COUNT(*) >= ALL ( SELECT COUNT(*) FROM SALES S WHERE S.`sales_date` = CURDATE() GROUP BY S.`good_no`);
问题5;
SELECT GOODS.`good_no`, GOODS.`brand` FROM GOODS WHERE GOODS.`good_no` NOT IN ( SELECT DISTINCT S.`good_no` FROM SALES S);
例16.1.1;
问题1;
CREATE TABLE EMPLOYEE ( EMPLOYEE_NO CHAR(10) NOT NULL, EMPLOYEE_NAME CHAR(10), AGE INT, SEX CHAR(2), TITLE CHAR(10), PRIMARY KEY (EMPLOYEE_NO)); CREATE TABLE COMPANY ( COMPANY_NO CHAR(10) NOT NULL, COMPANY_NAME CHAR(50), CITY CHAR(10), PRIMARY KEY (COMPANY_NO));
2023-04-11;
例16.1.1;
问题1;
CREATE TABLE WORKS ( EMPLOYEE_NO CHAR(10) REFERENCES EMPLOYEE(EMPLOYEE_NO), COMPANY_NO CHAR(4) REFERENCES COMPANY(COMPANY_NO), SALARY INT CHECK (SALARY >= 1500), PRIMARY KEY (EMPLOYEE_NO, COMPANY_NO));
问题2(1);
CREATE VIEW v_female_employee(EMPLOYEE_NO, EMPLOYEE_NAME, COMPANY_NO, COMPANY_NAME, SALARY) AS SELECT EMPLOYEE.`EMPLOYEE_NO`, EMPLOYEE.`EMPLOYEE_NAME`, COMPANY.`COMPANY_NO`, COMPANY.`COMPANY_NAME`, WORKS.`SALARY` FROM EMPLOYEE, COMPANY, WORKS WHERE EMPLOYEE.`EMPLOYEE_NO` = WORKS.`EMPLOYEE_NO` AND EMPLOYEE.`SEX` = '女' AND COMPANY.`COMPANY_NO` = WORKS.`COMPANY_NO`; /* 删除视图 */ DROP VIEW v_female_employee; /* 删除表(包括表结构及数据) */ DROP TABLE WORKS;
问题2(2);
DELIMITER $ CREATE TRIGGER trig_salary_u AFTER UPDATE ON EMPLOYEE FOR EACH ROW BEGIN UPDATE WORKS SET SALARY = func_salary_value (NROW.EMPLOYEE_NO) WHERE WORKS.`EMPLOYEE_NO` = NROW.EMPLOYEE_NO ; END $ DELIMITER ;
问题3(1);
SELECT COMPANY.`COMPANY_NO`, COMPANY.`COMPANY_NAME` FROM COMPANY, WORKS WHERE COMPANY.`COMPANY_NO` = WORKS.`COMPANY_NO` GROUP BY COMPANY.`COMPANY_NO`, COMPANY.`COMPANY_NAME` HAVING COUNT(*) >= ALL (SELECT COUNT(*) FROM WORKS W GROUP BY W.`COMPANY_NO`);
问题3(2);
SELECT E.`EMPLOYEE_NO`, E.`EMPLOYEE_NAME` FROM EMPLOYEE E WHERE E.`EMPLOYEE_NO` NOT IN (SELECT W.`EMPLOYEE_NO` FROM COMPANY C, WORKS W WHERE C.`COMPANY_NO` = W.`COMPANY_NO` AND C.`COMPANY_NAME` = '中国银行北京分行');
2023-04-12;
例12.4;
系统重启后,有DBMS根据日志对数据库进行恢复,将已提交的事务对数据库的修改写入硬盘。输入数据违反完整性约束导致的数据库故障属于事务故障。
2023-05-31;
例12.2.7;
E-SQL(Embedded SQL)是一种在编程语言中嵌入SQL语句的技术。
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 设置数据库事务的隔离级别为serializable,也就是串行化。
2023-06-01;
2023-06-05(继续做上次题目并批改上次的内容);
例12.3;
(1)D;(2)A
例12.2.7;
问题1;
A剩余8张;
B剩余9张;
C剩余7张;
错误的调度:A、B。
产生错误的原因:对于R_i(A,x),W_i(A,x)这一组操作过程中,没有对资源(剩余机票数)进行禁止读写的加锁操作。
(错。正确答案:因为破坏了事务的隔离性。一个事务的执行结果被另一个事务覆盖)
问题2;
(1)
(a)判定事务并发执行正确性的准则是什么?
事务并发执行的正确性由ACID准则来保证:
原子性(Atomicity)[ˌætəˈmɪsəti] :事务的所有操作在数据库中要么全做要么全都不做。如银行转账中的两个操作必须作为一个单位来处理,不能只进行部分操作。
一致性(Consistency)[kənˈsɪstənsi] :一个事务独立执行的结果,将保持数据的一致性,即数据不会因为事务的执行而遭到破坏。数据的一致性是对现实世界的真实状态的描述,如银行转账业务,一旦执行该业务后应该是账目平衡的。数据库在运行过程中会出现瞬间的不一致状态,如从A账户减去x元到给B账户加上x元之前的这段时间数据是不一致的,但这种不一致只能出现在事务执行过程中,并且不一致的数据不能被其他事务所访问。一致性可以由DBMS的完整性约束机制来自动完成,而复杂的事务则由应用程序来完成。
隔离性(Isolation)[ˌaɪsəˈleɪʃən] :一个事务的执行不能被其他事务干扰。并发事务在执行过程中可能会对同一数据进行操作,这些事务的操作应该不会相互干扰,是相互隔离的。如事务执行中数据不一致性状态出现时不能让其他事务读取到不一致的数据。
持久性(Durability)[dərəˈbɪləti]:一个事务一旦提交,它对数据库的改变必须是永久的,即便系统出现故障时也是如此。如转账事务执行成功后,A、B两个账户上的余额就是一个新的值,在没有出现下一个事务对其修改之前一直保持不变,即使系统出现故障 ,也应该恢复到这个值。
(错。正确答案:判定事务并发执行正确性的准则是满足可串行化调度。)
(b)如何保证并发事务正确地执行?
(正确答案:要保证并发事务正确地执行,采用两段锁协议(2PL))
(2)xlockA, R(A,x), W(A,x-a), UlockA
(3)
(a)balance = x(错。正确答案:balance = :x where fight = 'A')
(b)commit(错。正确答案:EXEC SQL COMMIT WORK)
下一步:P467页;学习例12.2.7问题2的(1)。