基于Oracle的停车场管理系统数据库课程设计

本文已上传SQL源码及设计报告文档供参考

目录

课程设计报告格式及要求

需求分析

概念结构设计

逻辑结构设计及ER关系说明

物理结构设计

在Oracle中创建表空间及表

表数据插入

添加索引

查询示例

单条件查询

组合条件查询

多表查询

存储过程

查询函数示例

触发器

用户和权限

备份策略


课程设计报告格式及要求:

课程设计作业要求:
(1)以《数据库系统的设计与实现》为题目完成课程设计报告,内容及写法可以参照教材。
(2)所选应用系统不能与教材三个应用系统相同,可以参考项目库中题目,推荐大家自拟题目。
(3)具体内容应该包括如下:

  1. 系统需求分析
  2. 数据库设计(概念结构、逻辑结构、其他模式对象设计(序列视图等))
  3. PL/SQL 功能模块设计
  4. 数据库实现(主要是模式对象和 PL/SQL 程序的实现)
  5. 数据库运营维护(主要是安全管理、备份与恢复管理等)
  6. 设计报告中有八九个表,存储过程六七个, 6 个 sql 案例。
    一、封面;
    二、目录;
    三、设计任务书;
  7. 课程设计系统名称
  8. 系统功能说明
  9. 测试说明
  10. 进度安排
    四、
    五、程序功能简介;
    六、主体内容:
    1.需求分析
    2.概念模型设计(画 E-R 图)
    3.逻辑结构设计,转换成关系模型
  11. 数据库的实现,创建表空间及表的代码及主要查询代码
    5.创建视图、存储过程、触发器等的主要代码
    6.权限设置及数据库备份
  12. 系统用户界面设计与实现
    七、设计体会。

需求分析

本文设计的基于Oracle数据库的停车场管理系统旨在解决当前城市停车难的问题。

通过对停车场内的车辆信息进行有效管理,可以提高停车场的使用率,缓解停车难问题。

此外,该系统还可以为政府部门提供有关停车场使用情况的数据支持,有助于城市规划和建设。

一个常见的停车场收费管理系统可以包含如下几个功能模块:

  • 车辆信息模块:此模块的功能是管理车辆的基本信息。包括车辆的ID,品牌,型号,颜色,车主ID等。用户(通常是管理员或车主)可以通过此模块进行车辆信息的添加,修改或删除。
  • 车辆进入停车场记录模块:此模块用于记录车辆进入停车场的时间以及该车辆所使用的停车位。当车辆进入停车场时,系统会自动记录进入时间,同时将该车辆与所使用的停车位相关联。
  • 车辆离开停车场记录模块:此模块用于记录车辆离开停车场的时间以及该车辆所使用的停车位。当车辆离开停车场时,系统会自动记录离开时间,同时将该停车位解除与该车辆的关联。
  • 停车费用支付信息模块:此模块管理停车费用的支付信息。当车辆离开停车场并产生停车费用时,系统会自动记录支付信息,包括支付时间,支付方式(如现金,信用卡等),应付款项和已付款项。
  • 停车位信息模块:此模块的功能是管理停车位的基本信息。包括停车位的ID,类型(如普通,VIP等),状态(如空闲,占用等),以及停车场ID。管理员可以通过此模块进行停车位信息的添加,修改或删除,也可以查看停车位的占用情况。
  • 车主信息模块:此模块的功能是管理车主的基本信息。包括车主的ID,姓名,联系方式,地址,拥有的车辆数量以及停车场ID(如果车主拥有自己的停车场)。管理员可以通过此模块进行车主信息的添加,修改或删除。

概念结构设计

根据系统需求分析,我们预计将使用到6个实体。

  • 车辆信息是一个实体,它代表了一辆汽车的具体描述和详情。这些详情可能包括车辆的ID、品牌、型号、颜色、车主ID等。
  • 车辆进入停车场记录也是一个实体,它代表了车辆进入停车场的时间和事件。这个实体包含进入时间以及与该车辆关联的停车位信息。
  • 车辆离开停车场记录是另一个实体,它代表了车辆离开停车场的时间和事件。这个实体包含离开时间以及与该车辆关联的停车位信息。
  • 停车费用支付信息是一个实体,它代表了有关停车费用的支付详情。这些详情可能包括支付时间、支付费用等信息。
  • 停车位信息是一个实体,它代表了一个停车位的具体描述和详情。这些详情可能包括停车位的ID状态(如空闲、占用等)。
  • 车主信息是一个实体,它代表了车主的具体描述和详情。这些详情可能包括车主的ID、姓名、联系方式、地址。

逻辑结构设计及ER关系说明

根据上述系统的概念设计,下面是对数据库逻辑结构的设计和ER关系的描述:

实体:

  • PKS_CAR: 此表对应一个实体,即“车辆”。
  • PKS_ENTRY: 此表对应一个实体,即“进入停车场的记录”。
  • PKS_EXIT: 此表对应一个实体,即“离开停车场的记录”。
  • PKS_PAYMENT: 此表对应一个实体,即“停车费用付款”。
  • PKS_SPACE: 此表对应一个实体,即“停车场中的空位”。
  • PKS_CAR_OWNER: 此表对应一个实体,即“车主”。

关系:

  • PKS_CAR与PKS_ENTRY、PKS_EXIT:每辆车可以有多个进入和离开停车场的记录。车辆与进入停车场的记录、离开停车场的记录之间是多对一的关系。
  • PKS_ENTRY与PKS_SPACE:每个进入停车场的记录对应一个停车场中的空位。进入停车场的记录与停车场中的空位之间是一对一的关系。
  • PKS_PAYMENT与PKS_CAR: 每个付款记录对应一辆车。付款记录与车辆之间是一对一的关系。
  • PKS_CAR与PKS_CAR_OWNER:每辆车有一个车主。车辆与车主之间是一对一的关系。
  • 每个表(实体)的属性设计:
  • PKS_CAR: 此表存储车辆的详细信息,如车辆ID(主键)、车牌号码、车辆颜色、车辆类型和车主ID(外键,关联到PKS_CAR_OWNER表的OWNER_ID列)。
  • PKS_ENTRY: 此表存储车辆进入停车场的记录,包括记录ID(主键)、车辆ID(外键,关联到PKS_CAR表的CAR_ID列)、进入时间以及停车位ID(外键,关联到PKS_SPACE表的SPACE_ID列)。
  • PKS_EXIT: 此表存储车辆离开停车场的记录,包括记录ID(主键)、车辆ID(外键,关联到PKS_CAR表的CAR_ID列)和离开时间。
  • PKS_PAYMENT: 此表存储停车费用付款的记录,包括记录ID(主键)、车辆ID(外键,关联到PKS_CAR表的CAR_ID列)、付款金额和付款时间。
  • PKS_SPACE: 此表存储停车场中的空位的信息,包括空位ID(主键)、空位号码和空位状态。
  • PKS_CAR_OWNER: 此表存储车主的信息,包括车主ID(主键)、车主姓名、车主电话和车主电子邮件地址。

以上是对数据库逻辑结构的设计和关系描述,绘制ER图如下:

物理结构设计

根据系统的逻辑结构设计最终设计6个数据表如下:

表名

列名

数据类型

说明

PKS_CAR

CAR_ID

NUMBER

车辆ID,主键

CAR_NUMBER

VARCHAR2(20)

车牌号码

CAR_COLOR

VARCHAR2(20)

车辆颜色

CAR_TYPE

VARCHAR2(20)

车辆类型

OWNER_ID

NUMBER

车主ID,外键关联到 PKS_CAR_OWNER表的OWNER_ID列


表名

列名

数据类型

说明

PKS_ENTRY

ENTRY_ID

NUMBER

记录ID,主键

CAR_ID

NUMBER

车辆ID,外键关联到 PKS_CAR表的CAR_ID列

ENTRY_TIME

DATE

进入时间

SPACE_ID

NUMBER

停车位ID,外键关联到 PKS_SPACE表的SPACE_ID列


表名

列名

数据类型

说明

PKS_EXIT

EXIT_ID

NUMBER

记录ID,主键

CAR_ID

NUMBER

车辆ID,外键关联到 PKS_CAR表的CAR_ID列

EXIT_TIME

DATE

离开时间


表名

列名

数据类型

说明

PKS_PAYMENT

PAYMENT_ID

NUMBER

记录ID,主键

CAR_ID

NUMBER

车辆ID,外键关联到 PKS_CAR表的CAR_ID列

AMOUNT

NUMBER

停车费用

PAYMENT_TIME

DATE

支付时间


表名

列名

数据类型

说明

PKS_SPACE

SPACE_ID

NUMBER

停车位ID,主键

SPACE_NUMBER

NUMBER

停车位号码

SPACE_STATUS

VARCHAR2(10)

停车位状态


表名

列名

数据类型

说明

PKS_CAR_OWNER

OWNER_ID

NUMBER

车主ID,主键

OWNER_NAME

VARCHAR2(50)

车主姓名

OWNER_PHONE

VARCHAR2(20)

车主电话号码

OWNER_EMAIL

VARCHAR2(50)

车主电子邮件地址

MEMBER_END_DATE

DATE

车主会员截止日期

在Oracle中创建表空间及表

  1. 创建数据表:

使用以下命令在Oracle中创建数据表:

CREATE TABLE PKS_CAR_OWNER (  
  OWNER_ID NUMBER PRIMARY KEY,  
  OWNER_NAME VARCHAR2(50),  
  OWNER_PHONE VARCHAR2(20),  
  OWNER_EMAIL VARCHAR2(50),
  MEMBER_END_DATE DATE 
);

CREATE TABLE PKS_CAR (  
  CAR_ID NUMBER PRIMARY KEY,  
  CAR_NUMBER VARCHAR2(20),  
  CAR_COLOR VARCHAR2(20),  
  CAR_TYPE VARCHAR2(20),
  OWNER_ID NUMBER,
  FOREIGN KEY (OWNER_ID ) REFERENCES PKS_CAR_OWNER(OWNER_ID)
);  

CREATE TABLE PKS_SPACE (  
  SPACE_ID NUMBER PRIMARY KEY,  
  SPACE_NUMBER NUMBER,  
  SPACE_STATUS VARCHAR2(10)  
);  
  
CREATE TABLE PKS_ENTRY (  
  ENTRY_ID NUMBER PRIMARY KEY,  
  CAR_ID NUMBER,  
  ENTRY_TIME DATE,  
  SPACE_ID NUMBER,  
  FOREIGN KEY (CAR_ID) REFERENCES PKS_CAR(CAR_ID),  
  FOREIGN KEY (SPACE_ID) REFERENCES PKS_SPACE(SPACE_ID)  
);  
  
CREATE TABLE PKS_EXIT (  
  EXIT_ID NUMBER PRIMARY KEY,  
  CAR_ID NUMBER,  
  EXIT_TIME DATE,  
  FOREIGN KEY (CAR_ID) REFERENCES PKS_CAR(CAR_ID)  
);  
  
CREATE TABLE PKS_PAYMENT (  
  PAYMENT_ID NUMBER PRIMARY KEY,  
  CAR_ID NUMBER,  
  AMOUNT NUMBER,  
  PAYMENT_TIME DATE,  
  FOREIGN KEY (CAR_ID) REFERENCES PKS_CAR(CAR_ID)  
);  
  

以上命令将创建每个数据表,并使用适当的列和数据类型定义表结构。

表数据插入

在 PKS_CAR 表中插入数据:


INSERT INTO PKS_CAR (CAR_ID, CAR_NUMBER, CAR_COLOR, CAR_TYPE, OWNER_ID) VALUES 
 (1, '粤A12345', '红色', '轿车', 1), 
 INSERT INTO PKS_CAR (CAR_ID, CAR_NUMBER, CAR_COLOR, CAR_TYPE, OWNER_ID) VALUES 
       (2, '粤B67890', '蓝色', 'SUV', 2),  
       (3, '粤C3456', '绿色', '皮卡', 3),
       INSERT INTO PKS_CAR (CAR_ID, CAR_NUMBER, CAR_COLOR, CAR_TYPE, OWNER_ID) VALUES 
       (4, '粤D78901', '黄色', '跑车', 4) 
       INSERT INTO PKS_CAR (CAR_ID, CAR_NUMBER, CAR_COLOR, CAR_TYPE, OWNER_ID) VALUES 
       (5, '粤E2345', '白色', '轿车', 5)
       INSERT INTO PKS_CAR (CAR_ID, CAR_NUMBER, CAR_COLOR, CAR_TYPE, OWNER_ID) VALUES 
       (6, '粤F9012', '黑色', 'SUV', 6) 
       INSERT INTO PKS_CAR (CAR_ID, CAR_NUMBER, CAR_COLOR, CAR_TYPE, OWNER_ID) VALUES 
       (7, '粤G3456', '红色', '皮卡', 7)
       INSERT INTO PKS_CAR (CAR_ID, CAR_NUMBER, CAR_COLOR, CAR_TYPE, OWNER_ID) VALUES 
       (8, '粤H7890', '蓝色', '跑车', 8) 
       INSERT INTO PKS_CAR (CAR_ID, CAR_NUMBER, CAR_COLOR, CAR_TYPE, OWNER_ID) VALUES 
       (9, '粤I2345', '绿色', '轿车', 9)
       INSERT INTO PKS_CAR (CAR_ID, CAR_NUMBER, CAR_COLOR, CAR_TYPE, OWNER_ID) VALUES 
       (10, '粤J6789', '黄色', 'SUV', 10)

在 PKS_SPACE 表中插入数据:

INSERT INTO PKS_SPACE (SPACE_ID, SPACE_NUMBER, SPACE_STATUS)  
VALUES (1, 'A1', 'Available');  
  
INSERT INTO PKS_SPACE (SPACE_ID, SPACE_NUMBER, SPACE_STATUS)  
VALUES (2, 'B2', 'Available');  
INSERT INTO PKS_SPACE (SPACE_ID, SPACE_NUMBER, SPACE_STATUS)  
VALUES (3, 'C3', 'Occupied');  
  
INSERT INTO PKS_SPACE (SPACE_ID, SPACE_NUMBER, SPACE_STATUS)  
VALUES (4, 'D4', 'Maintenance');  
  
INSERT INTO PKS_SPACE (SPACE_ID, SPACE_NUMBER, SPACE_STATUS)  
VALUES (5, 'E5', 'Available');  
  
INSERT INTO PKS_SPACE (SPACE_ID, SPACE_NUMBER, SPACE_STATUS)  
VALUES (6, 'F6', 'Occupied');  
  
INSERT INTO PKS_SPACE (SPACE_ID, SPACE_NUMBER, SPACE_STATUS)  
VALUES (7, 'G7', 'Maintenance');  
  
INSERT INTO PKS_SPACE (SPACE_ID, SPACE_NUMBER, SPACE_STATUS)  
VALUES (8, 'H8', 'Available');  
  
INSERT INTO PKS_SPACE (SPACE_ID, SPACE_NUMBER, SPACE_STATUS)  
VALUES (9, 'I9', 'Occupied');  
  
INSERT INTO PKS_SPACE (SPACE_ID, SPACE_NUMBER, SPACE_STATUS)  
VALUES (10, 'J10', 'Maintenance');  

        

在 PKS_CAR_OWNER表中插入数据:

INSERT INTO PKS_CAR_OWNER (OWNER_ID, OWNER_NAME, OWNER_PHONE, OWNER_EMAIL, MEMBER_END_DATE)  
VALUES (1, '张三', '1234567890', 'zhangsan@example.com', TO_DATE('2023-12-31', 'YYYY-MM-DD'));  
  
INSERT INTO PKS_CAR_OWNER (OWNER_ID, OWNER_NAME, OWNER_PHONE, OWNER_EMAIL, MEMBER_END_DATE)  
VALUES (2, '李四', '0987654321', 'lisi@example.com', TO_DATE('2024-06-30', 'YYYY-MM-DD'));  
  
INSERT INTO PKS_CAR_OWNER (OWNER_ID, OWNER_NAME, OWNER_PHONE, OWNER_EMAIL, MEMBER_END_DATE)  
VALUES (3, '王五', '123456789', 'wangwu@example.com', TO_DATE('2023-11-30', 'YYYY-MM-DD'));  
  
INSERT INTO PKS_CAR_OWNER (OWNER_ID, OWNER_NAME, OWNER_PHONE, OWNER_EMAIL, MEMBER_END_DATE)  
VALUES (4, '赵六', '098765432', 'zhaoliu@example.com', TO_DATE('2024-05-31', 'YYYY-MM-DD'));  
  
INSERT INTO PKS_CAR_OWNER (OWNER_ID, OWNER_NAME, OWNER_PHONE, OWNER_EMAIL, MEMBER_END_DATE)  
VALUES (5, '孙七', '1234567890', 'sunqi@example.com', TO_DATE('2023-10-31', 'YYYY-MM-DD'));  
  
INSERT INTO PKS_CAR_OWNER (OWNER_ID, OWNER_NAME, OWNER_PHONE, OWNER_EMAIL, MEMBER_END_DATE)  
VALUES (6, '周八', '0987654321', 'zhouba@example.com', TO_DATE('2024-04-30', 'YYYY-MM-DD'));  
  
INSERT INTO PKS_CAR_OWNER (OWNER_ID, OWNER_NAME, OWNER_PHONE, OWNER_EMAIL, MEMBER_END_DATE)  
VALUES (7, '吴九', '1234567890', 'wujiu@example.com', TO_DATE('2023-09-30', 'YYYY-MM-DD'));  
  
INSERT INTO PKS_CAR_OWNER (OWNER_ID, OWNER_NAME, OWNER_PHONE, OWNER_EMAIL, MEMBER_END_DATE)  
VALUES (8, '杨千', '0987654321', 'yangqian@example.com', TO_DATE('2024-03-31', 'YYYY-MM-DD'));  
  
INSERT INTO PKS_CAR_OWNER (OWNER_ID, OWNER_NAME, OWNER_PHONE, OWNER_EMAIL, MEMBER_END_DATE)  
VALUES (9, '朱百', '123456789', 'zhubai@example.com', TO_DATE('2023-08-31', 'YYYY-MM-DD'));  
  
INSERT INTO PKS_CAR_OWNER (OWNER_ID, OWNER_NAME, OWNER_PHONE, OWNER_EMAIL, MEMBER_END_DATE)  
VALUES (10, '魏万', '098765432', 'weiwan@example.com', TO_DATE('2024-02-28', 'YYYY-MM-DD'));

往表PKS_ENTRY中插入数据


INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (1, 1, TO_DATE('2023-07-19 09:00:00', 'YYYY-MM-DD HH24:MI:SS'), 1);  
  
INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (2, 2, TO_DATE('2023-07-19 09:15:00', 'YYYY-MM-DD HH24:MI:SS'), 2);  
  
INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (3, 3, TO_DATE('2023-07-19 09:30:00', 'YYYY-MM-DD HH24:MI:SS'), 3);  
  
INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (4, 4, TO_DATE('2023-07-19 10:00:00', 'YYYY-MM-DD HH24:MI:SS'), 4);  
  
INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (5, 5, TO_DATE('2023-07-19 10:15:00', 'YYYY-MM-DD HH24:MI:SS'), 5);  
  
INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (6, 6, TO_DATE('2023-07-19 11:00:00', 'YYYY-MM-DD HH24:MI:SS'), 6);  
  
INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (7, 7, TO_DATE('2023-07-19 11:15:00', 'YYYY-MM-DD HH24:MI:SS'), 7);  
  
INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (8, 8, TO_DATE('2023-07-19 12:00:00', 'YYYY-MM-DD HH24:MI:SS'), 8);  
  
INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (9, 9, TO_DATE('2023-07-19 12:15:00', 'YYYY-MM-DD HH24:MI:SS'), 9);  
  
INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (10, 10, TO_DATE('2023-07-19 13:00:00', 'YYYY-MM-DD HH24:MI:SS'), 10);

在 PKS_EXIT 表中插入数据:

-- 假设车辆信息表PKS_CAR、车主信息表PKS_CAR_OWNER和停车位信息表PKS_SPACE已经存在并且包含相应的数据  
  
INSERT INTO PKS_EXIT (EXIT_ID, CAR_ID, EXIT_TIME)  
VALUES (1, 1, TO_DATE('2023-07-19 10:00:00', 'YYYY-MM-DD HH24:MI:SS'));  
  
INSERT INTO PKS_EXIT (EXIT_ID, CAR_ID, EXIT_TIME)  
VALUES (2, 2, TO_DATE('2023-07-19 10:30:00', 'YYYY-MM-DD HH24:MI:SS')); 

INSERT INTO PKS_EXIT (EXIT_ID, CAR_ID, EXIT_TIME)  
VALUES (3, 3, TO_DATE('2023-07-19 11:00:00', 'YYYY-MM-DD HH24:MI:SS'));  
  
INSERT INTO PKS_EXIT (EXIT_ID, CAR_ID, EXIT_TIME)  
VALUES (4, 4, TO_DATE('2023-07-19 11:30:00', 'YYYY-MM-DD HH24:MI:SS'));  
  
INSERT INTO PKS_EXIT (EXIT_ID, CAR_ID, EXIT_TIME)  
VALUES (5, 5, TO_DATE('2023-07-19 12:00:00', 'YYYY-MM-DD HH24:MI:SS'));  
  
INSERT INTO PKS_EXIT (EXIT_ID, CAR_ID, EXIT_TIME)  
VALUES (6, 6, TO_DATE('2023-07-19 12:30:00', 'YYYY-MM-DD HH24:MI:SS'));  
  
INSERT INTO PKS_EXIT (EXIT_ID, CAR_ID, EXIT_TIME)  
VALUES (7, 7, TO_DATE('2023-07-19 13:00:00', 'YYYY-MM-DD HH24:MI:SS'));  
  
INSERT INTO PKS_EXIT (EXIT_ID, CAR_ID, EXIT_TIME)  
VALUES (8, 8, TO_DATE('2023-07-19 13:30:00', 'YYYY-MM-DD HH24:MI:SS'));  
  
INSERT INTO PKS_EXIT (EXIT_ID, CAR_ID, EXIT_TIME)  
VALUES (9, 9, TO_DATE('2023-07-19 14:00:00', 'YYYY-MM-DD HH24:MI:SS'));  
  
INSERT INTO PKS_EXIT (EXIT_ID, CAR_ID, EXIT_TIME)  
VALUES (10, 10, TO_DATE('2023-07-19 14:30:00', 'YYYY-MM-DD HH24:MI:SS'));

往表PKS_PAYMENT中插入数据


  INSERT INTO PKS_PAYMENT (PAYMENT_ID, CAR_ID, PAYMENT_TIME, SPACE_ID, PAYMENT_AMOUNT)  
VALUES (1, 1, TO_DATE('2023-07-19 10:00:00', 'YYYY-MM-DD HH24:MI:SS'), 1, 50);  
  
INSERT INTO PKS_PAYMENT (PAYMENT_ID, CAR_ID, PAYMENT_TIME, SPACE_ID, PAYMENT_AMOUNT)  
VALUES (2, 2, TO_DATE('2023-07-19 10:30:00', 'YYYY-MM-DD HH24:MI:SS'), 2, 60);  
  
INSERT INTO PKS_PAYMENT (PAYMENT_ID, CAR_ID, PAYMENT_TIME, SPACE_ID, PAYMENT_AMOUNT)  
VALUES (3, 3, TO_DATE('2023-07-19 11:00:00', 'YYYY-MM-DD HH24:MI:SS'), 3, 55);  
  
INSERT INTO PKS_PAYMENT (PAYMENT_ID, CAR_ID, PAYMENT_TIME, SPACE_ID, PAYMENT_AMOUNT)  
VALUES (4, 4, TO_DATE('2023-07-19 11:30:00', 'YYYY-MM-DD HH24:MI:SS'), 4, 70);  
  
INSERT INTO PKS_PAYMENT (PAYMENT_ID, CAR_ID, PAYMENT_TIME, SPACE_ID, PAYMENT_AMOUNT)  
VALUES (5, 5, TO_DATE('2023-07-19 12:00:00', 'YYYY-MM-DD HH24:MI:SS'), 5, 65);  
  
INSERT INTO PKS_PAYMENT (PAYMENT_ID, CAR_ID, PAYMENT_TIME, SPACE_ID, PAYMENT_AMOUNT)  
VALUES (6, 6, TO_DATE('2023-07-19 12:30:00', 'YYYY-MM-DD HH24:MI:SS'), 6, 50);  
  
INSERT INTO PKS_PAYMENT (PAYMENT_ID, CAR_ID, PAYMENT_TIME, SPACE_ID, PAYMENT_AMOUNT)  
VALUES (7, 7, TO_DATE('2023-07-19 13:00:00', 'YYYY-MM-DD HH24:MI:SS'), 7, 60);  
  
INSERT INTO PKS_PAYMENT (PAYMENT_ID, CAR_ID, PAYMENT_TIME, SPACE_ID, PAYMENT_AMOUNT)  
VALUES (8, 8, TO_DATE('2023-07-19 13:30:00', 'YYYY-MM-DD HH24:MI:SS'), 8, 55);  
  
INSERT INTO PKS_PAYMENT (PAYMENT_ID, CAR_ID, PAYMENT_TIME, SPACE_ID, PAYMENT_AMOUNT)  
VALUES (9, 9, TO_DATE('2023-07-19 14:00:00', 'YYYY-MM-DD HH24:MI:SS'), 9, 70);  
  
INSERT INTO PKS_PAYMENT (PAYMENT_ID, CAR_ID, PAYMENT_TIME, SPACE_ID, PAYMENT_AMOUNT)  
VALUES (10, 10, TO_DATE('2023-07-19 14:30:00', 'YYYY-MM-DD HH24:MI:SS'), 10, 65);

添加索引

在数据库中添加合适的索引可以显著提高查询性能。

以下是在每个表中添加索引:

在 PKS_CAR 表中添加索引:

CREATE INDEX idx_car_id ON PKS_CAR (CAR_ID);  
CREATE INDEX idx_owner_id ON PKS_CAR (OWNER_ID);

在 PKS_ENTRY 表中添加索引:

CREATE INDEX idx_entry_car_id ON PKS_ENTRY (CAR_ID);  
CREATE INDEX idx_entry_space_id ON PKS_ENTRY (SPACE_ID);

在 PKS_EXIT 表中添加索引:

CREATE INDEX idx_exit_car_id ON PKS_EXIT (CAR_ID);

在 PKS_PAYMENT 表中添加索引:

CREATE INDEX idx_payment_car_id ON PKS_PAYMENT (CAR_ID);

在 PKS_SPACE 表中添加索引:

CREATE INDEX idx_space_id ON PKS_SPACE (SPACE_ID);

在 PKS_CAR_OWNER 表中添加索引:

CREATE INDEX idx_owner_id ON PKS_CAR_OWNER (OWNER_ID);

这些索引将加速基于这些列的查询,并提高数据库的整体性能。

查询示例

单条件查询

查询所有车辆的信息:

SELECT * FROM PKS_CAR;

查询所有车辆的颜色:

SELECT CAR_COLOR FROM PKS_CAR;

查询所有车辆的进入记录:

SELECT * FROM PKS_ENTRY;

组合条件查询

查询所有红色车辆的所属人:

SELECT OWNER_ID FROM PKS_CAR WHERE CAR_COLOR = '红色';

查询所有在2023年7月19日12:00之后进入停车场的车辆:

SELECT CAR_ID FROM PKS_ENTRY WHERE ENTRY_TIME >= TO_DATE('2023-07-19 12:00:00', 'YYYY-MM-DD HH24:MI:SS');

查询所有在2023年7月19日12:00之前离开停车场的车辆:

SELECT CAR_ID FROM PKS_EXIT WHERE EXIT_TIME <= TO_DATE('2023-07-19 12:00:00', 'YYYY-MM-DD HH24:MI:SS');

查询所有车辆的平均停车时间:

SELECT AVG(ENTRY_TIME - EXIT_TIME) AS AVG_PARKING_TIME FROM PKS_ENTRY, PKS_EXIT 
WHERE ENTRY_ID = EXIT_ID;

查询所有车辆的平均支付金额:

SELECT AVG(PAYMENT_AMOUNT) AS AVG_PAYMENT FROM PKS_PAYMENT;

多表查询

查询所有车辆的信息及其所属人的信息:

SELECT PKS_CAR.CAR_ID, PKS_CAR.CAR_TYPE, PKS_CAR.CAR_COLOR, PKS_CAR_OWNER.OWNER_NAME   
FROM PKS_CAR   
INNER JOIN PKS_CAR_OWNER ON PKS_CAR.OWNER_ID = PKS_CAR_OWNER.OWNER_ID;

查询所有停车位的状态及其进入和离开记录:

SELECT PKS_SPACE.SPACE_ID, PKS_SPACE.SPACE_STATUS, PKS_ENTRY.ENTRY_TIME, PKS_EXIT.EXIT_TIME   
FROM PKS_SPACE   
INNER JOIN PKS_ENTRY ON PKS_SPACE.SPACE_ID = PKS_ENTRY.SPACE_ID   
INNER JOIN PKS_EXIT ON PKS_ENTRY.CAR_ID = PKS_EXIT.CAR_ID
;

查询所有车辆的编号、类型、颜色、进入和离开记录以及支付记录:

SELECT PKS_CAR.CAR_ID, PKS_CAR.CAR_TYPE, PKS_CAR.CAR_COLOR, PKS_ENTRY.ENTRY_TIME, PKS_EXIT.EXIT_TIME, PKS_PAYMENT.PAYMENT_AMOUNT   
FROM PKS_CAR   
INNER JOIN PKS_ENTRY ON PKS_CAR.CAR_ID = PKS_ENTRY.CAR_ID   
INNER JOIN PKS_EXIT ON PKS_CAR.CAR_ID = PKS_EXIT.CAR_ID   
INNER JOIN PKS_PAYMENT ON PKS_CAR.CAR_ID = PKS_PAYMENT.CAR_ID;

查询所有车辆的所属人、电话号码、电子邮件地址以及其进入和离开记录:


SELECT PKS_CAR_OWNER.OWNER_NAME, PKS_CAR_OWNER.OWNER_PHONE, PKS_CAR_OWNER.OWNER_EMAIL, PKS_ENTRY.ENTRY_TIME   
FROM PKS_CAR_OWNER
INNER JOIN PKS_CAR ON PKS_CAR.CAR_ID = PKS_CAR_OWNER.CAR_ID
INNER JOIN PKS_ENTRY ON PKS_ENTRY.CAR_ID = PKS_CAR.CAR_ID;

存储过程

1.存储过程:GET_CAR_INFO


CREATE OR REPLACE PROCEDURE get_car_info (
    id    IN NUMBER,
    color OUT VARCHAR2
) AS
BEGIN
    SELECT
        car_color
    INTO color
    FROM
        pks_car
    WHERE
        car_id = id;

EXCEPTION
    WHEN no_data_found THEN
        dbms_output.put_line('no_data_found');
END;
/

该存储过程接受一个车辆ID作为输入参数,返回该车辆的颜色信息。

执行存储过程:

--调用存储过程
SET SERVEROUTPUT ON; 
-- 打开DBMS_OUTPUT输出

DECLARE
  ID NUMBER;
  COLOR VARCHAR2(200);
BEGIN
  ID := 1;

  GET_CAR_INFO(
    ID => ID,
    COLOR => COLOR
  );
  /* Legacy output: 
DBMS_OUTPUT.PUT_LINE('COLOR = ' || COLOR);
*/ 
  :COLOR := COLOR;
--rollback; 
END;

/

2.存储过程:update_car_info

create or replace PROCEDURE update_car_info (
    id    IN NUMBER,
    v_color IN VARCHAR2,
    v_type IN VARCHAR2
) AS
BEGIN
    UPDATE 
        pks_car
    SET car_color = v_color , car_type = v_type
    WHERE
        car_id = id;
EXCEPTION
    WHEN no_data_found THEN
        dbms_output.put_line('no_data_found');
END;

该存储过程接受一个车辆ID,颜色和类型作为输入参数,更新该车辆的颜色和类型。

执行存储过程:

DECLARE
  ID NUMBER;
  V_COLOR VARCHAR2(200);
  V_TYPE VARCHAR2(200);
BEGIN
  ID := 1;
  V_COLOR := '蓝色';
  V_TYPE := '皮卡';

  UPDATE_CAR_INFO(
    ID => ID,
    V_COLOR => V_COLOR,
    V_TYPE => V_TYPE
  );
--rollback; 
END;

3.存储过程:CALCULATE_TOTAL_PAYMENT

create or replace PROCEDURE calculate_total_payment (
    c_id        IN NUMBER,
    total_payment OUT NUMBER
) AS
BEGIN
    SELECT
        SUM(payment_amount)
    INTO total_payment
    FROM
        pks_payment
    WHERE
        car_id = c_id;
EXCEPTION
    WHEN no_data_found THEN
        dbms_output.put_line('no_data_found');
END;
/

该存储过程接受一个车辆ID作为输入参数,计算该车辆的总支付金额,并将结果作为输出参数返回。

执行存储过程:

--调用存储过程
SET SERVEROUTPUT ON; 
-- 打开DBMS_OUTPUT输出
DECLARE
  C_ID NUMBER;
  TOTAL_PAYMENT NUMBER;
BEGIN
  C_ID := 2;

  CALCULATE_TOTAL_PAYMENT(
    C_ID => C_ID,
    TOTAL_PAYMENT => TOTAL_PAYMENT
  );
--  /* Legacy output: 
DBMS_OUTPUT.PUT_LINE('TOTAL_PAYMENT = ' || TOTAL_PAYMENT);

  :TOTAL_PAYMENT := TOTAL_PAYMENT;
--rollback; 
END;

查询函数示例

1.查询函数:GET_CAR_INFO_FUNC


CREATE OR REPLACE FUNCTION get_car_info_func (
    c_id IN NUMBER
) RETURN VARCHAR2 AS
    c_type  VARCHAR2(50);
    c_color VARCHAR2(50);
BEGIN
    SELECT
        car_type,
        car_color
    INTO
        c_type,
        c_color
    FROM
        pks_car
    WHERE
        car_id = c_id;

    RETURN c_type
           || ', '
           || c_color;
END;

执行函数:

--调用函数过程
SET SERVEROUTPUT ON; 
-- 打开DBMS_OUTPUT输出
DECLARE
    c_id     NUMBER;
    v_return VARCHAR2(200);
BEGIN
    c_id := 1;
    v_return := get_car_info_func(c_id => c_id);
--  Legacy output: 
    dbms_output.put_line('v_Return = ' || v_return);
    :v_return := v_return;
--rollback; 
END;

该查询函数接受一个车辆ID作为输入参数,返回该车辆的类型和颜色信息,以逗号分隔的字符串形式返回。

2.查询函数:GET_OWNER_INFO_FUNC

create or replace FUNCTION get_owner_info_func (
    o_id IN NUMBER
) RETURN VARCHAR2 AS
    o_name  VARCHAR2(50);
    o_phone VARCHAR2(50);
    o_email VARCHAR2(50);
BEGIN
    SELECT
        owner_name,
        owner_phone,
        owner_email
    INTO
        o_name,
        o_phone,
        o_email
    FROM
        pks_car_owner
    WHERE
        owner_id = o_id;

    RETURN o_name
           || ', '
           || o_phone
           || ', '
           || o_email;
END;
 
/

该查询函数接受一个所属人ID作为输入参数,返回该所属人的姓名、电话号码和电子邮件地址信息,以逗号分隔的字符串形式返回。

调用函数:GET_OWNER_INFO_FUNC


SET SERVEROUTPUT ON; 
-- 打开DBMS_OUTPUT输出
DECLARE
  O_ID NUMBER;
  v_Return VARCHAR2(200);
BEGIN
  O_ID := 2;

  v_Return := GET_OWNER_INFO_FUNC(
    O_ID => O_ID
  );

DBMS_OUTPUT.PUT_LINE('v_Return = ' || v_Return);

  :v_Return := v_Return;
--rollback; 
END;

3.查询函数:GET_ENTRY_INFO_FUNC

create or replace FUNCTION get_entry_info_fuc (
    e_id IN NUMBER
) RETURN VARCHAR2 AS
    c_id     NUMBER;
    s_id   NUMBER;
    e_time DATE;
BEGIN
    SELECT
        car_id,
        space_id,
        entry_time
    INTO
        c_id,
        s_id,
        e_time
    FROM
        pks_entry
    WHERE
        entry_id = e_id;

    RETURN to_char(e_time, 'YYYY-MM-DD HH24:MI:SS')
           || ', '
           || c_id
           || ', '
           || s_id;

END;

/

该查询函数接受一个进入记录ID作为输入参数,返回该记录所对应的车辆ID、停车位ID和进入时间信息,以逗号分隔的字符串形式返回。

执行函数:get_entry_info_fuc

--调用存储过程
SET SERVEROUTPUT ON; 
-- 打开DBMS_OUTPUT输出
DECLARE
  E_ID NUMBER;
  v_Return VARCHAR2(200);
BEGIN
  E_ID := 3;

  v_Return := GET_ENTRY_INFO_FUC(
    E_ID => E_ID
  );

DBMS_OUTPUT.PUT_LINE('v_Return = ' || v_Return);

  :v_Return := v_Return;
--rollback; 
END;

触发器

以下是3个触发器示例:

1.触发器:UPDATE_SPACE_STATUS

create or replace TRIGGER update_space_status AFTER
    INSERT OR UPDATE ON pks_entry
    FOR EACH ROW
DECLARE
    space_status VARCHAR2(50);
BEGIN
    SELECT
        space_status
    INTO space_status
    FROM
        pks_space
    WHERE
        space_id = :new.space_id;

    IF space_status = '可用'  THEN
        UPDATE pks_space
        SET
            space_status = '已占用'
        WHERE
            space_id = :new.space_id;

    END IF;

END;
/

该触发器在PKS_ENTRY表的每行插入或更新后触发,检查对应的停车位状态,如果停车位状态为"可用",则更新为"已占用"。

插入一条入场记录可以看到触发器应用结果。

INSERT INTO PKS_ENTRY (ENTRY_ID, CAR_ID, ENTRY_TIME, SPACE_ID)  
VALUES (14, 2, TO_DATE('2023-10-19 09:15:00', 'YYYY-MM-DD HH24:MI:SS'), 1); 

2.触发器:CALCULATE_PARKING_FEE

CREATE OR REPLACE TRIGGER calculate_parking_fee AFTER
    INSERT OR UPDATE ON pks_exit
    FOR EACH ROW
BEGIN
    DECLARE
        payment_amount NUMBER;
        entry_time     DATE;
        exit_time      DATE;
        fee            NUMBER;
        space_id       VARCHAR(200);
        payment_id     NUMBER;
    BEGIN
        SELECT
            entry_time,
            space_id
        INTO
            entry_time,
            space_id
        FROM
            pks_entry
        WHERE
                car_id = :new.car_id
            AND ROWNUM = 1
        ORDER BY
            entry_time DESC;

        fee := ( :new.exit_time - entry_time ) * 2;
        --2元每小时
        SELECT
            MAX(payment_id)
        INTO payment_id
        FROM
            pks_payment;

        payment_id := payment_id + 1;
           -- 插入停车收费记录  
        INSERT INTO pks_payment (
            payment_id,
            car_id,
            payment_amount,
            payment_time,
            space_id
        ) VALUES (
            payment_id,
            :new.car_id,
            fee,
            :new.exit_time,
            space_id
        );

    END;
END;
/

该触发器在PKS_EXIT表的每行插入或更新后触发,计算停车费用(假设费用是2元每小时),并在表PKS_PAYMENT中新增并插入一条收费记录。

用户和权限

在本数据库设计中我们创建三个用户并赋予他们不同权限。

在Oracle中分别创建三个用户:

1.用户名:PksUser1,密码:password

CREATE USER PksUser1 IDENTIFIED BY password;

2.用户名:PksUser2,密码:password

CREATE USER PksUser2 IDENTIFIED BY password;

3.用户名:PksUser3,密码:password

CREATE USER PksUser3 IDENTIFIED BY password;

给这些用户分别授予不同的权限。

1.给PksUser1授予数据库所有权限:


GRANT CONNECT, SELECT ANY TABLE, INSERT ANY TABLE, UPDATE ANY TABLE, DELETE ANY TABLE TO PksUser1;

2.给PksUser2授予完全的访问和修改ParkingLot和PKS_CAR表的权限:

GRANT ALL PRIVILEGES ON PKS_CAR_OWNER TO PksUser2;  
GRANT ALL PRIVILEGES ON PKS_CAR TO PksUser2;

3.给PksUser3只授予查看PKS_CAR表的权限:

GRANT SELECT ON PKS_CAR TO PksUser3;

备份策略

以下是一个简单的备份策略,可以根据实际情况进行调整:

创建备份表空间:

CREATE TABLESPACE backup_tablespace
DATAFILE 'backup_tablespace.dbf' SIZE 10G;

创建备份日志文件:

ALTER SYSTEM ADD LOGFILE 'backup_logfile.log' SIZE 50M AUTOEXTEND ON NEXT 50M MAXSIZE UNLIMITED;

启用备份表空间:

ALTER TABLESPACE backup_tablespace ENABLE;

创建备份策略:

CREATE CONTROLFILE REUSE DATABASE "BACKUP" NORESETLOGS MAXLOGFILES 16;
ALTER CONTROLFILE SET RESERVE MAXLOGARCHS 2;
ALTER CONTROLFILE SET BACKUP TYPE TO BACKUPSET;
ALTER CONTROLFILE SET BACKUP SET NAME TO 'full_database_backup';
ALTER CONTROLFILE SET BACKUP SET EXPIREDATE TO 'TODAY+1';

创建备份集:

CREATE BACKUPSET backup_set FORMAT '$ORACLE_HOME/dbs/backup/%F';

执行备份:

RUN {
  ALLOCATE CHANNEL ch1 DEVICE TYPE DISK FORMAT '$ORACLE_HOME/dbs/backup/%U';
  BACKUP AS COMPRESSED BACKUPSET backup_set TO CHANNEL ch1;
}

清理备份集:

DROP BACKUPSET backup_set;

删除备份表空间和日志文件:

DROP TABLESPACE backup_tablespace INCLUDING CONTENTS AND DATAFILES;
DROP LOGFILE backup_logfile;

以上备份策略将每天进行一次全量备份,并将备份存储在指定的表空间中。备份集将在备份集中过期后自动删除。可以根据实际需求调整备份策略,例如增加增量备份、压缩备份等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李威威wiwi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值