问卷调查系统 简易版

1.1 设计的背景和意义

在面对全方位多维度海量数据的需求日益增长时,线上问卷调查是获得数据的重要途径,在很多领域的运用已经十分广泛。就比如在我们的校园里,经常会有各种各样的问卷表单要统计信息。像期末教学评价、学生对学校食堂、校园环境以及校园管理的意见等,如果我们还是用传统的纸质调查问卷方式,则会需要在此消耗极大的精力和时间。现在我们全部改为在线填写问卷,极大的节省了纸张的消耗和各师生的时间。

网络问卷成本低、时效性强、跨地域、表现形式丰富、覆盖范围广,可极大程度上减少人力资源的使用,满足了用户基本需求。网络调查问卷没有传统问卷调查地域限制、灵活性限制、人工失误这些不可避免的缺陷,可以减少精力和时间的消耗且具有很强的实用性。

在我们这次的问卷调查系统设计中,包括了开发人员的各种信息以及对问卷的创建和对答卷时间的设定、问卷的题量和主题设置、答题人答题时间和所选择选项的填写、题目主题和选项个数的设定以及选项中编号和内容的设计。简化了数据统计的工作,丰富了数据处理的手段且操作简便,能极大的节约用户的时间。

1.2 采用的数据库开发工具和应用程序开发工具

数据库开发工具:SQLyog , MYSQL8.0

应用程序开发工具:eclipse ,JDK1.8

第2章 需求分析

2.1功能需求分析

本系统的用户类型有:开发人员、答题人员

开发用户的功能有:创建问卷、对问卷进行更新、设定问卷开始时间和结束时间、确定问卷主题以及问题的数量,选项个数及选项内容。

答题人员的功能有:选择不同主题的问卷答题、选择自己中意的选项并提交答题结果。

2.2数据需求分析

需要在数据库中记录和存储的信息有:

开发人员信息:人员编号、姓名、性别

问卷信息:问卷编号、创建人员编号、主题、创建时间、更新时间、开始时间、结束时间、问题个数

问题信息:题号、问卷编号、选择题、类型

答题人信息:答题人编号、姓名、性别、年龄

选项信息:选项编号、题号、选项内容、选项顺序

填写信息:开发人员编号、答题人编号、答卷时间

选择信息:答题人编号、选项编号

数据库总体E-R图如下图所示。

 

第4章 逻辑结构设计

4.1关系模型

开发人员(人员编号,姓名,性别)

问卷(问卷编号创建人员编号,主题,创建时间,更新时间,开始时间,

结束时间,问题个数)

答题人(答题人编号,姓名,性别,年龄)

选项(选项编号题号,内容,顺序)

问题(题号问卷编号,选择题,类型)

填写(问卷编号答题人编号,答卷时间)

选择(答题人编号选项编号

4.2关系模式的优化

问卷关系:

函数依赖:{问卷编号→主题,问卷编号→创建时间,问卷编号→更新时间,问卷编号→开始时间,问卷编号→结束时间,问卷编号→问题个数}

候选码:问卷编号

该关系模式中每个属性的值域都是不可分的原子值,且所有非主属性都不存在对主属性的部分函数依赖和传递函数依赖,故该关系模式属于3NF。

同上可得开发人员关系、答题人关系、选项关系、问题关系、填写关系均属于3NF,选择关系为BC范式。

第5章 物理结构设计

5.1创建数据库

创建数据库survey:

CREATE DATABASE survey

DEFAULT CHARACTER SET gbk

COLLATE gbk_bin ;

5.2数据库表设计

在数据库中创建7个表。

1.开发人员

CREATE TABLE developer (

  did CHAR(12) NOT NULL COMMENT '开发人员编号',

  dname VARCHAR(20)  NOT NULL COMMENT '开发人员姓名',

  dsex CHAR(2) DEFAULT '男' COMMENT '性别',

  PRIMARY KEY (did)

) ENGINE=INNODB  COMMENT='开发人员表';

-- 添加一个按开发人员姓名dname升序的索引

CREATE INDEX developer_dname_idx ON developer(dname ASC);

-- 插入数据

INSERT INTO developer (did,dname,dsex) VALUES

('B20041302','孙晨','女'),

('B20041303','崔珍珠','女'),

('B20041366','张三','男');

SELECT * FROM developer;

2.答题人表

CREATE TABLE answer (
  aid CHAR(12) NOT NULL COMMENT '答题人编号',
  aname VARCHAR(20)  NOT NULL COMMENT '答题人姓名',
  asex CHAR(2) DEFAULT '男' COMMENT '性别',
  age INT(6) COMMENT '年龄',
  PRIMARY KEY (aid)
) ENGINE=INNODB  COMMENT='答题人表';

-- 添加一个按答题人姓名aname升序的索引
CREATE INDEX answer_aname_idx ON answer(aname ASC);
-- 插入数据
INSERT INTO answer (aid,aname,asex,age) VALUES 
('1302','小孙','女','18'),
('1303','小崔','男','20');
SELECT * FROM answer;

3.问卷表

CREATE TABLE questionnaire (
  qid CHAR(12) NOT NULL COMMENT '问卷编号',
  qname VARCHAR(255) NOT NULL COMMENT '主题',
  create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  start_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '开始时间',
  end_time TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '结束时间',
  did CHAR(12) COMMENT '创建人员编号',
  num INT(6) COMMENT '问题个数',
  PRIMARY KEY (qid),
  FOREIGN KEY (did) REFERENCES developer(did)
) ENGINE=INNODB  COMMENT='问卷表';

-- 添加一个按问卷主题qname升序的索引
CREATE INDEX questionnaire_qname_idx ON questionnaire(qname ASC);
-- 添加一个按问卷创建时间create_time降序的索引
CREATE INDEX questionnaire_create_time_idx ON questionnaire(create_date DESC);
-- 插入数据
INSERT  INTO questionnaire (qid,qname,end_time,did,num) 
VALUES 
('1','关于大学生熬夜情况调查问卷',DATE_ADD(CURRENT_TIMESTAMP,INTERVAL 24 HOUR),'B20041302','3'),
('2','关于大学生在家学习情况调查问卷',DATE_ADD(CURRENT_TIMESTAMP,INTERVAL 24 HOUR),'B20041303','5');
SELECT * FROM questionnaire;

4.问题表

CREATE TABLE problem (
  pid CHAR(12) NOT NULL COMMENT '题号',
  qid CHAR(12) NOT NULL COMMENT '问卷编号',
  problem_name VARCHAR(255) NOT NULL COMMENT '问题主题',
  choice CHAR(1)  NOT NULL DEFAULT '1' COMMENT '1单选 2多选',
  problem_type CHAR(1) DEFAULT '0' COMMENT ' 0 必填 1非必填',
  PRIMARY KEY (pid),
  FOREIGN KEY (qid) REFERENCES questionnaire(qid)
) ENGINE=INNODB COMMENT='问题表';

-- 添加一个按题号pid升序的索引
CREATE INDEX problem_pid_idx ON problem(pid ASC);
-- 添加一个按问题主题problem_name升序的索引
CREATE INDEX problem_problem_name_idx ON problem(problem_name ASC);
-- 插入数据
INSERT  INTO problem(pid,qid,problem_name,problem_type,problem_flag) VALUES 
('1','1','每天几点睡觉?','1','0'),
('2','1','睡得晚的原因?','2','0'),
('3','1','第二天几点起?','1','1');
SELECT * FROM problem;

5.选项表

CREATE TABLE optiontable(
  oid CHAR(12) NOT NULL COMMENT '选项编号',
  pid CHAR(12) COMMENT '题号',
  content VARCHAR(255) NOT NULL COMMENT '内容',
  sort INT(11) DEFAULT '0' COMMENT '排序',
  PRIMARY KEY (oid),
  FOREIGN KEY (pid) REFERENCES problem(pid)
) ENGINE=INNODB COMMENT='选项表';

-- 添加一个按选项编号oid升序的索引
CREATE INDEX optiontable_oid_idx ON optiontable(oid ASC);
-- 添加一个按选项内容content升序的索引
CREATE INDEX optiontable_content_idx ON optiontable(content ASC);
-- 添加一个按选项题号pid降序的索引
CREATE INDEX optiontable_pid_idx ON optiontable(pid DESC);
-- 插入数据
INSERT  INTO optiontable
VALUES 
('A','1','9:00','0'),
('B','1','10:00','1'),
('C','1','11:00','2'),
('D','1','12:00','3'),
('E','2','玩游戏','0'),
('F','2','看剧','1'),
('G','2','刷抖音','2'),
('H','2','做课设','3'),
('I','3','9:00','0'),
('J','3','10:00','1'),
('K','3','11:00','2'),
('L','3','12:00','3');
SELECT * FROM optiontable;

6.填写表

CREATE TABLE writetable (
  qid CHAR(12) NOT NULL COMMENT '问卷编号',
  aid CHAR(12) NOT NULL COMMENT '答题人编号',
  write_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '答卷时间',
  PRIMARY KEY (qid,aid),
  FOREIGN KEY (qid) REFERENCES problem(qid),
  FOREIGN KEY (aid) REFERENCES answer(aid)
) ENGINE=INNODB  COMMENT='填写表';

-- 添加一个按答卷时间write_time升序的索引
CREATE INDEX writetable_write_dtime_idx ON writetable(write_time ASC);
-- 插入数据
INSERT  INTO writetable(qid,aid)
VALUES ('1','1302'),
('1','1303');
SELECT * FROM writetable;

7.选择表

CREATE TABLE choose (
  oid CHAR(12) NOT NULL COMMENT '选项编号',
  aid CHAR(12) NOT NULL COMMENT '答题人编号',
  PRIMARY KEY (oid,aid),
  FOREIGN KEY (oid) REFERENCES optiontable(oid),
  FOREIGN KEY (aid) REFERENCES answer(aid)
) ENGINE=INNODB  COMMENT='选择表';

-- 添加一个按选项编号oid升序的索引
CREATE INDEX choose_oid_idx ON choose(oid ASC);
-- 添加一个按答题人编号aid降序的索引
CREATE INDEX choose_aid_idx ON choose(aid ASC);
-- 插入数据
INSERT  INTO choose
VALUES ('A','1302'),
       ('B','1303'),
       ('C','1302'),
       ('D','1303');   
SELECT * FROM choose;

第6章 数据库对象设计

6.1视图设计

在数据库中创建2个视图。

1.answer_detail 

-- 创建视图answer_detail,包括答题人编号、姓名、性别、年龄、所答问卷编号和答题时间
CREATE VIEW answer_detail
AS
SELECT answer.aid,aname,asex,age,questionnaire.qid,write_time  
FROM answer,questionnaire,writetable
WHERE answer.aid =writetable.aid AND questionnaire.qid =writetable.qid;
SELECT * FROM answer_detail;

2.questionnaire_detail

-- 创建视图questionnaire_detail,包括问卷编号、主题、开始时间、结束时间、问题个数和问题主题
CREATE VIEW questionnaire_detail
AS
SELECT questionnaire.qid,qname,start_time,end_time,num,problem_name  
FROM questionnaire INNER JOIN problem ON questionnaire.qid =problem.qid;
SELECT * FROM questionnaire_detail;

6.2存储过程设计

在数据库中创建3个存储过程。

1. questionnaire_list

/*1.在survey数据库中,创建一个存储过程questionnaire_list,功能是根据输入的问卷编号来查询该问卷的问卷名单(包括问卷主题、开始时间、结束时间、问题个数、创建人员编号、答题人编号、答题时间,并按问卷编号升序排序)*/

-- 代码:
DELIMITER $$
CREATE PROCEDURE questionnaire_list(IN qd CHAR(12))
BEGIN
  SELECT questionnaire.qid,qname,start_time,end_time,num,developer.did,answer.aid,write_time
  FROM questionnaire,developer,answer,writetable
  WHERE questionnaire.qid=writetable.qid AND answer.aid=writetable.aid 
  AND questionnaire.did=developer.did AND questionnaire.qid=qd 
  ORDER BY questionnaire.qid ASC;
END$$
DELIMITER ;

CALL questionnaire_list('1'); 

2.whether_write 

/*2. 在survey数据库中创建存储过程whether_write,其功能是当输入答题人编号,可以查询该读者是否填写过问卷,如果已答过问卷,为输出参数whether赋值1,否则赋值0。*/
-- 代码:
DELIMITER ##
CREATE PROCEDURE whether_write
(IN ad CHAR(12),OUT whether TINYINT)
BEGIN
  IF (SELECT aid FROM answer  WHERE aid IN
  (SELECT aid FROM writetable) AND aid=ad) THEN
    SET whether=1;      
 ELSE 
    SET whether=0;
END IF;
END##
DELIMITER ;

CALL whether_write('1302',@w);  
SELECT @w;

3.developer_list

/*3.在survey数据库中,创建一个存储过程developer_list,功能是根据输入的开发人员姓名或者姓名中的一部分来查询该答题人所创建的问卷编号。并按问卷编号升序排序*/
-- 代码:
DELIMITER $$
CREATE PROCEDURE developer_list(IN dnm VARCHAR(20))
BEGIN
  SELECT dname,qid
  FROM developer INNER JOIN questionnaire ON developer.did=questionnaire.did
  WHERE dname LIKE CONCAT('%',dnm,'%')
  ORDER BY qid ASC;
END$$
DELIMITER ;

CALL developer_list('晨');   

第7章 应用程序设计

7.1总体设计

创建的项目名为survey_info其中共设计了4个程序。

1.程序1:insert_developer  -- 增

(1)执行结果截图

 

(2)其中运用数据库语句相关代码

 

public class insert_developer {
	private DbUtil dbUtil=new DbUtil();
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in); 
        System.out.println("请输入开发人员编号:");   //注意输入的部门号不要重复
        String developer_did = sc.nextLine();      //取得用户输入的字符串
        System.out.println("请输入开发人员姓名:"); 
        String developer_dname = sc.nextLine();    //取得用户输入的字符串
        System.out.println("请输入开发人员性别:"); 
        String developer_dsex = sc.nextLine(); 
        //float price = sc.nextFloat(); 
        insert_developer d=new insert_developer();
		d.inser_developer(developer_did,developer_dname,developer_dsex);}
	public void inser_developer(String developer_did,String developer_dname,String developer_dsex){	
	  Connection con=null; 
	  try {
		con=dbUtil.getCon();
	    Statement stmt = con.createStatement();	
String sql = "insert into developer values ('"+developer_did +"','"+developer_dname+"','"+developer_dsex+"');";  
	    stmt.executeUpdate(sql);
	    System.out.println("插入成功!!!");}
		 catch(Exception e) {
			e.printStackTrace();}
		   finally{
			try {
				dbUtil.closeCon(con);
			} catch (Exception e) {			
				e.printStackTrace();}
		}
	}
}

程序2:delete_developer  -- 删

(1)执行结果截图

 (2)其中运用数据库语句相关代码

package survey_info;
import survey_info.DbUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Scanner;
public class delete_developer {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	    Scanner sc = new Scanner(System.in); 
	    System.out.println("请输入要删除的开发人员编号:");//注意输入的编号不要重复
	    String developer_did = sc.nextLine(); 
	    delete1_developer d=new delete1_developer();
	    d.delete_d(developer_did);}
	private DbUtil dbUtil=new DbUtil();
	public void delete_d(String developer_did){	
	  Connection con=null;
	  PreparedStatement pstmt = null;// 准备语句
	  boolean rs ; //结果集
	  try {
		con=dbUtil.getCon();
		String sql="DELETE FROM developer WHERE did=?;";
		// 获取执行sql语句对象
        pstmt=con.prepareStatement(sql);  
        // 执行查询操作
        pstmt.setString(1,developer_did); 
        rs=pstmt.execute();
        //处理结果集
        System.out.println("删除成功! ! !");}
		 catch(Exception e){
			e.printStackTrace();}
		   finally{
			try {
				dbUtil.closeCon(con);
			} catch (Exception e) {
				e.printStackTrace();}
		}
}
}

程序3:select_developerlist  -- 查

(1)执行结果截图

(2)其中运用数据库语句相关代码

package survey_info;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import survey_info.DbUtil;
import survey_info.select_developerlist;
public class select_developerlist {
	public static void main(String[] args) {
		select_developerlist sd=new select_developerlist();
	    sd.sel_developer();}	
	private DbUtil dbUtil=new DbUtil();
	public void sel_developer(){	
	  Connection con=null;
	  PreparedStatement pstmt = null;// 准备语句
      ResultSet rs = null; //结果集
	  try {
		con=dbUtil.getCon();
		String sql="SELECT * FROM developer;";
		// 获取执行sql语句对象
        pstmt=con.prepareStatement(sql);      
        // 执行查询操作
        rs=pstmt.executeQuery();
        //处理结果集
        int flag=1;
        while (rs.next()) {  
        	if (flag==1){        	
            System.out.println("did"+"\t\t\t"+"dname"+"\t\t"+"dsex");
            System.out.println(rs.getString(1)+"\t\t"+rs.getString(2)+"\t\t"+rs.getString(3));
            flag=0;}
        	else{
System.out.println(rs.getString(1)+"\t\t"+rs.getString(2)+"\t\t"+rs.getString(3));}
        	}
            }
		 catch(Exception e){
			e.printStackTrace();}
		   finally{
			try {
				dbUtil.closeCon(con);
			} catch (Exception e) {
				e.printStackTrace();} }
	}
}

 

程序4:questionnaire_list  -- 存储过程

(1)执行结果截图

(2)其中运用数据库语句相关代码

package survey_info;
import java.util.Scanner;   
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import survey_info.DbUtil;
public class questionnaire_list {
	public static void main(String[] args) {
	       Scanner sc = new Scanner(System.in); 
	        System.out.println("请输入问卷编号:"); 
	        int questionqid = sc.nextInt();      //取得用户输入的字符串 
	        questionnaire_list s=new questionnaire_list();
	        s.ser(questionqid); }
	private DbUtil dbUtil=new DbUtil();
	public void ser(int rm){	
		  Connection con=null;
		  PreparedStatement pstmt = null;
	      ResultSet rs = null;
		  try {
			con=dbUtil.getCon();
			String sql="call  questionnaire_list(?);"; //一个问号一个参数,多个中间加逗号// 获取执行sql语句对象
	        pstmt=con.prepareStatement(sql);
	        // 准备参数
	        pstmt.setInt(1,rm); 
	        // 执行查询操作
	        rs=pstmt.executeQuery();
	        //处理结果集
	        int flag=1;
	        while (rs.next()) {  
	        	if (flag==1){        	
System.out.println("qid"+"\t"+"qname"+"\t\t\t"+"start_time"+"\t\t"+"end_time"+"\t\t"+"num"+"\t"+"developer.did"+"\t"+"answer.aid"+"\t"+"write_date");
System.out.println(rs.getString(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3)+"\t"+rs.getString(4)+"\t"+rs.getString(5)+"\t"+rs.getString(6)+"\t"+rs.getString(7)+"\t\t"+rs.getString(8));
	            flag=0;}else{
System.out.println(rs.getString(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3)+"\t"+rs.getString(4)+"\t"+rs.getString(5)+"\t"+rs.getString(6)+"\t"+rs.getString(7)+"\t\t"+rs.getString(8));} }
	            }
			 catch(Exception e){
				e.printStackTrace();}
			   finally{
				try {dbUtil.closeCon(con);
				} catch (Exception e) {
					e.printStackTrace();}
			}  }  }

 

第8章 设计总结

(1)问题一:在刚开始的时候,不清楚如何找到实体,对各个实体之间的关系也很模糊导致E-R图绘制不正确以及关系模式错误。

解决办法:在网上查找资料,小组内根据资料分析确定实体。在老师的帮助下理清各个实体之间的关系,改善E-R图并纠正关系模式的错误。

问题二:在表中插入数据时,因外键约束而导致插入失败。

解决办法:检查插入的外键数据是否存在于所参照的表中已有的主键数据中。

问题三:在eclipse中编写程序时,调用存储过程时出现错误。

解决办法:上网查阅资料,查找以前所做实验代码,更改类型,更改Java程序中的SQL语句。

问题四:在eclipse中编写删除程序时,出现运行成功但是数据还在的情况。

解决办法:上网查阅资料,更改类中的方法,更改SQL语句,组内思考讨论并咨询Java老师,成功解决问题。

我们在这次的课程设计中还遇到了许多因粗心和焦躁而导致的问题,在不断的查找问题和改正问题的过程中我们认识到了细心和耐心的重要性。

  1. 要想做好这次的课程设计,必须对本学习所学的数据库知识非常熟悉,并且能把他们紧密联系到一起。我们在做完这次课程设计后都对本课程的理论知识有了更深入的认识。
  2. 极大的锻炼了我们对问题的思考能力,我们能找出问题,思考问题,并寻找解决问题的办法,不仅对我们的创造力有很大提高,也培养了我们独立思考、解决问题的能力。

(4)通过这次的课程设计,我们的数据库设计能力都得到了极大的提高,数据库设计是一门实践性的学科,绝对不能只学理论。如果不自己动手写的话,永远都学不会。我们不仅能在实践中发现许多平常不注意的问题,还能在实践中对数据库设计有更加深刻的体会、领悟和理解。

参考文献

数据库原理及应用(MySQL版)

CSDN网站

  • 7
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值