SchoolWork-LaTeX/数据库系统原理与实践/平时作业/第九次作业.tex

390 lines
15 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

\documentclass[全部作业]{subfiles}
\input{mysubpreamble}
\begin{document}
\setcounter{chapter}{8}
\chapter{第九次作业}
\section*{数据库案例设计综合练习}
某金融数据库系统背景:
某银行为了建设金融管理系统,需要对该系统的数据库进行设计,针对该系统,主要将对象分为客户、银行卡、理财产品、保险、基金。假设该系统存在着以下关系:客户可以办理银行卡,同时客户可以购买不同的银行产品,如理财产品,基金和保险。购买后的银行产品统称为客户的资产。
数据库系统业务需求描述:
\begin{itemize}
\item 客户可以办理多张银行卡,不仅可以办理储蓄卡,如果符合要求还可以办理信用卡,客户办理成功后获得银行卡的卡号。
\item 银行提供多种理财产品,客户根据理财产品的信息(包括产品编号,产品名称,产品描述)购买理财产品,一个客户可以购买多种理财产品,不同的理财产品有不同的购买金额和理财年限。
\item 银行提供多种保险,客户根据保险的信息(包括保险编号,保险名称,适用人群,保险项目)购买理财产品,一个客户可以购买多种保险,不同的保险有不同的保险金额和保险年限。
\item 银行提供多种基金,客户根据基金的信息(包括基金编号,基金名称,基金类型,风险等级和基金管理者)购买理财产品,一个客户可以购买多种基金,不同的基金有不同的基金金额。
\item 客户购买银行产品(理财产品、保险、基金)成为自己的资产后,需要记录这些资产的状态(可用,冻结),每个资产的购买数量,每个资产的收益和购买时间。
\end{itemize}
项目具体要求:
\begin{itemize}
\renewcommand{\labelitemi}{-}
\item 创建finance数据库作为项目数据库数据库编码为UTF-8。
\item 在finance模式下完成金融管理系统中所有数据库对象数据表的创建并完成数据的填充可以由navicat自动生成。其中客户数据不少于20条银行卡数据不少于10条其他数据不少于5条
\item 对表添加外键约束,在银行信息表和资产信息表中,都存在每个银行卡必须有一个持卡者、每份资产必须都有一个资产拥有者这样的对应关系。因此针对这种对应关系,创建外键约束。
\item 在理财产品表、保险信息表和基金信息表中都存在金额这个属性在现实生活中金额不会存在负数。因此针对表中金额的属性增加大于0的约束条件。
\item 可以增加其他自定义约束。(可以用触发器来实现,不强制要求)
\end{itemize}
本次作业要求:
1. 分析系统功能提交相应的E-R图可以用画图软件如visio进行E-R图设计或者手绘后拍照上传超星平台 (30分)
2. 根据设计完成的E-R图转换对应的关系模式包括对象的具体属性描述和对象之间的关系描述需至少满足3NF要求(30分)
3. 在MySQL中创建数据库并加入适量的测试数据某个关系截图不用所有的关系都截图即可10分
4. 根据需求创建合适的视图、存储过程、函数、触发器提交代码20分
5. 设计一个简单的用户界面通过JDBC连接到该金融数据库并测试完成简单的功能测试代码和演示视频10分
注意本次作业注重数据库设计包括E-R图、关系模式转换以及数据库实践SQL操作的综合练习第5步仅做一个简单的UI界面即可语言不限不用太复杂。
\section*{解答}
\begin{enumerate}
\questionandanswer[]{
分析系统功能提交相应的E-R图可以用画图软件如visio进行E-R图设计或者手绘后拍照上传超星平台 (30分)
}{
% \includesvgpdf[0.9]{9.1.1.drawio}
\includegraphics[width=0.9\linewidth]{svg-inkscape/9.1.1.png}
}
\questionandanswer[]{
根据设计完成的E-R图转换对应的关系模式包括对象的具体属性描述和对象之间的关系描述需至少满足3NF要求(30分)
}{
转换对应的关系模式为:
{
customer(\underbar{customer_id})
card(\underbar{card_id})
product(\underbar{product_id}, name, description, price, year)
insurance(\underbar{insurance_id}, name, appliacable_people, coverage, price, year)
fund(\underbar{fund_id}, name, type, risk_rating, manager, price)
customer_card(\underbar{customer_id}, \underbar{card_id}, status, number, profit, buying_time)
customer_product(\underbar{customer_id}, \underbar{product_id}, status, number, profit, buying_time)
customer_insurance(\underbar{customer_id}, \underbar{insurance_id}, status, number, profit, buying_time)
customer_fund(\underbar{customer_id}, \underbar{fund_id}, status, number, profit, buying_time)
}
检查是否满足第三范式。这里有个问题是例如productname是否能确定description, price, year也就是是否允许同名产品存在。这里为了方便起见就认为不存在这样的函数依赖也就是允许同名产品存在。
那么这样的关系模式就满足第三范式了。
}
\questionandanswer[]{
在MySQL中创建数据库并加入适量的测试数据某个关系截图不用所有的关系都截图即可10分
}{}
{\kaishu
\begin{minted}{SQL}
create table customer(
customer_id int auto_increment primary key
);
create table card(
card_id int auto_increment primary key
);
create table product(
product_id int auto_increment primary key comment '产品编号',
name varchar(255) comment '产品名称',
description varchar(255) comment '产品描述',
price decimal(10, 2) comment '购买金额',
year year comment '理财年限'
);
create table insurance(
insurance_id int auto_increment primary key comment '保险编号',
name varchar(255) comment '保险名称',
applicable_people varchar(255) comment '适用人群',
coverage varchar(255) comment '保险项目',
price decimal(10, 2) comment '保险金额',
year year comment '保险年限'
);
create table fund(
fund_id int auto_increment primary key comment '基金编号',
name varchar(255) comment '基金名称',
type varchar(128) comment '基金类型',
risk_rating int(3) comment '风险等级',
manager varchar(64) comment '基金管理者',
price decimal(10, 2) comment '基金金额'
);
create table customer_card(
customer_id int,
card_id int,
status varchar(64) comment '状态',
number int comment '购买数量',
profit decimal(10, 2) comment '收益',
buying_time datetime comment '购买时间',
foreign key (customer_id) references customer(customer_id),
foreign key (card_id) references card(card_id)
);
create table customer_product(
customer_id int,
product_id int,
status varchar(64) comment '状态',
number int comment '购买数量',
profit decimal(10, 2) comment '收益',
buying_time datetime comment '购买时间',
foreign key (customer_id) references customer(customer_id),
foreign key (product_id) references product(product_id)
);
create table customer_insurance(
customer_id int,
insurance_id int,
status varchar(64) comment '状态',
number int comment '购买数量',
profit decimal(10, 2) comment '收益',
buying_time datetime comment '购买时间',
foreign key (customer_id) references customer(customer_id),
foreign key (insurance_id) references insurance(insurance_id)
);
create table customer_fund(
customer_id int,
fund_id int,
status varchar(64) comment '状态',
number int comment '购买数量',
profit decimal(10, 2) comment '收益',
buying_time datetime comment '购买时间',
foreign key (customer_id) references customer(customer_id),
foreign key (fund_id) references fund(fund_id)
);
\end{minted}
\noindent\includegraphics[width=1\linewidth]{imgs/2024-12-10-21-22-33.png}
}
\questionandanswer[]{
根据需求创建合适的视图、存储过程、函数、触发器提交代码20分
}{}
{\kaishu
外键应该已经创建好了。那还剩下金额了。
\begin{minted}{SQL}
alter table product add constraint _price_gt_0 check ( price > 0 );
alter table insurance add constraint _price_gt_0 check ( price > 0 );
alter table fund add constraint _price_gt_0 check ( price > 0 );
\end{minted}
}
\questionandanswer[]{
设计一个简单的用户界面,通过 JDBC 连接到该金融数据库,并测试完成简单的功能(测
试代码和演示视频10 分)
}{}
{\kaishu
\begin{minted}{python}
# -*- coding: utf-8 -*-
################################################################################
# Form generated from reading UI file 'designerLjvxhA.ui'
##
# Created by: Qt User Interface Compiler version 5.15.2
##
# WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import pymysql
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.verticalLayout_2 = QVBoxLayout(self.centralwidget)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.label = QLabel(self.centralwidget)
self.label.setObjectName(u"label")
self.horizontalLayout.addWidget(self.label)
self.host_edit = QLineEdit(self.centralwidget)
self.host_edit.setObjectName(u"host_edit")
self.horizontalLayout.addWidget(self.host_edit)
self.label_2 = QLabel(self.centralwidget)
self.label_2.setObjectName(u"label_2")
self.horizontalLayout.addWidget(self.label_2)
self.user_edit = QLineEdit(self.centralwidget)
self.user_edit.setObjectName(u"user_edit")
self.horizontalLayout.addWidget(self.user_edit)
self.label_3 = QLabel(self.centralwidget)
self.label_3.setObjectName(u"label_3")
self.horizontalLayout.addWidget(self.label_3)
self.password_edit = QLineEdit(self.centralwidget)
self.password_edit.setObjectName(u"password_edit")
self.horizontalLayout.addWidget(self.password_edit)
self.label_4 = QLabel(self.centralwidget)
self.label_4.setObjectName(u"label_4")
self.horizontalLayout.addWidget(self.label_4)
self.database_edit = QLineEdit(self.centralwidget)
self.database_edit.setObjectName(u"database_edit")
self.horizontalLayout.addWidget(self.database_edit)
self.connect_button = QPushButton(self.centralwidget)
self.connect_button.setObjectName(u"connect_button")
self.horizontalLayout.addWidget(self.connect_button)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.verticalLayout = QVBoxLayout()
self.verticalLayout.setObjectName(u"verticalLayout")
self.sql_edit = QPlainTextEdit(self.centralwidget)
self.sql_edit.setObjectName(u"sql_edit")
self.verticalLayout.addWidget(self.sql_edit)
self.horizontalLayout_2 = QHBoxLayout()
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.submit_button = QPushButton(self.centralwidget)
self.submit_button.setObjectName(u"submit_button")
sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.submit_button.sizePolicy().hasHeightForWidth())
self.submit_button.setSizePolicy(sizePolicy)
self.horizontalLayout_2.addWidget(self.submit_button)
self.verticalLayout.addLayout(self.horizontalLayout_2)
self.verticalLayout_2.addLayout(self.verticalLayout)
self.result_text = QTextBrowser(self.centralwidget)
self.result_text.setObjectName(u"result_text")
self.verticalLayout_2.addWidget(self.result_text)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName(u"menubar")
self.menubar.setGeometry(QRect(0, 0, 800, 23))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
self.setup_other()
# setupUi
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
self.label.setText(QCoreApplication.translate("MainWindow", u"\u4e3b\u673a", None))
self.label_2.setText(QCoreApplication.translate("MainWindow", u"\u7528\u6237\u540d", None))
self.label_3.setText(QCoreApplication.translate("MainWindow", u"\u5bc6\u7801", None))
self.label_4.setText(QCoreApplication.translate("MainWindow", u"\u6570\u636e\u5e93\u540d", None))
self.connect_button.setText(QCoreApplication.translate("MainWindow", u"\u8fde\u63a5", None))
self.submit_button.setText(QCoreApplication.translate("MainWindow", u"\u63d0\u4ea4", None))
# retranslateUi
def setup_other(self):
self.host_edit.setText("localhost")
self.user_edit.setText("test_user2")
self.password_edit.setText("Rie4OhYi")
self.database_edit.setText("finance")
self.connect_button.clicked.connect(self.on_connect_clicked)
self.submit_button.clicked.connect(self.on_submit_clicked)
def on_connect_clicked(self):
# 打开数据库连接
self.conn = pymysql.connect(
host=self.host_edit.text(), user=self.user_edit.text(), passwd=self.password_edit.text())
self.conn.select_db(self.database_edit.text())
self.result_text.setText("连接成功")
def on_submit_clicked(self):
cur = self.conn.cursor()
cur.execute(self.sql_edit.toPlainText())
all_result = ""
while 1:
res=cur.fetchone()
if res is None:
#表示已经取完结果集
break
all_result += str(res) + "\n"
self.result_text.setText(all_result)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QMainWindow()
main_window = Ui_MainWindow()
main_window.setupUi(window)
window.show()
app.exec_()
\end{minted}
\noindent\includegraphics[width=1\linewidth]{imgs/2024-12-13-21-18-22.png}
}
\end{enumerate}
\end{document}