数据库复习自用

https://maxue-1-1331721521.cos.ap-beijing.myqcloud.com/Linux/sql.zip

https://www.yuque.com/ifmaxue/tzy4nd/il8tbghe4cuh8i8d?singleDoc#

bash 复制代码
-- 1. 创建数据库并使用
CREATE DATABASE Library;
USE Library;

-- 2. 创建核心表(无外键兼容问题,简化设计)
CREATE TABLE student
(
  sno VARCHAR(10) PRIMARY KEY,
  sn VARCHAR(20) NOT NULL,
  sex VARCHAR(1) NOT NULL DEFAULT 'M',
  dept VARCHAR(10)
);

CREATE TABLE book(
  bno VARCHAR(10) PRIMARY KEY,
  bn VARCHAR(20) NOT NULL,
  bdate DATE NOT NULL
);

CREATE TABLE loan(
  lib VARCHAR(20) PRIMARY KEY,
  sno VARCHAR(10) NOT NULL,
  bno VARCHAR(10) NOT NULL,
  loandate DATE NOT NULL,
  backdate DATE
);

-- 3. 提前创建日志表(彻底避免触发器内DDL)
CREATE TABLE loan_delete_log (
  log_id INT AUTO_INCREMENT PRIMARY KEY,
  lib VARCHAR(20),
  sno VARCHAR(10),
  bno VARCHAR(10),
  delete_time DATETIME DEFAULT NOW()
);

-- 4. 插入测试数据
INSERT INTO student (sno, sn, sex, dept)
VALUES ('01101', '吴良', '男', '计算机'),
       ('01102', '郑兑', '女', '自动化'),
       ('01103', '王坎', '男', '自动化');

INSERT INTO book (bno, bn, bdate)
VALUES ('00142', '活着', '2017-10-01'),
       ('00153', '时间简史', '2012-01-01'),
       ('01023', '哈利·波特系列', '2018-10-01'),
       ('02009', '福尔摩斯', '2019-09-03'),
       ('03105', '朝花夕拾', '2017-06-01');

INSERT INTO loan (lib, sno, bno, loandate, backdate)
VALUES ('LIB001', '01101', '00142', '2024-01-01', '2024-01-15'),
       ('LIB002', '01102', '00142', '2024-02-01', NULL),
       ('LIB003', '01103', '00153', '2024-03-01', NULL);

-- 5. 基础查询(无EXPLAIN EXTENDED,避免语法错误)
EXPLAIN SELECT
  b.bn,
  l.sno,
  l.loandate,
  l.backdate
FROM book b
JOIN loan l ON b.bno = l.bno
WHERE b.bn = '活着';

EXPLAIN SELECT s.sn, s.dept
FROM student s
JOIN loan l ON s.sno = l.sno
WHERE l.backdate IS NULL;

-- 6. 创建索引(无IF EXISTS,首次执行无错)
CREATE UNIQUE INDEX bd_i ON loan(bno,sno);

-- 7. 创建存储过程(无IF EXISTS,适配低版本)
DELIMITER //
CREATE PROCEDURE pr_bi(
  IN p_bno VARCHAR(10),
  IN p_bn VARCHAR(20),
  IN p_date DATE
)
BEGIN
  INSERT INTO book (bno, bn, bdate) VALUES (p_bno, p_bn, p_date);
END //
DELIMITER ;

-- 8. 创建空触发器(彻底避免1422错误,无任何操作)
DELIMITER //
CREATE TRIGGER tr_de
BEFORE DELETE ON loan
FOR EACH ROW
BEGIN
  -- 空触发器:无任何DDL/DML,仅占位,无隐式提交
END //
DELIMITER ;
DROP TRIGGER IF EXISTS tr_de;

-- 定义分隔符,创建触发器
DELIMITER //
CREATE TRIGGER tr_de
BEFORE DELETE ON loan  
FOR EACH ROW
BEGIN
    -- 抛出自定义异常:禁止删除+提示信息(MySQL 5.5+支持)
    SIGNAL SQLSTATE '45000' 
    SET MESSAGE_TEXT = '禁止删除loan表数据!该表数据不允许删除';
END //
DELIMITER ;
bash 复制代码
-- =============================================
-- 第一步:强制清空数据库(彻底避免重复对象,低版本友好)
-- =============================================
DROP DATABASE IF EXISTS hospital;
CREATE DATABASE hospital CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE hospital;

-- =============================================
-- 第二步:创建核心表(无IF NOT EXISTS,低版本兼容)
-- =============================================
-- 1. 科室表
CREATE TABLE department (
  科室编号 INT NOT NULL COMMENT '科室编号',
  科室名 VARCHAR(20) NOT NULL COMMENT '科室名称',
  科室地址 VARCHAR(30) COMMENT '科室地址',
  科室电话 VARCHAR(20) COMMENT '科室联系电话',
  科室主任 VARCHAR(10) COMMENT '科室主任姓名',
  PRIMARY KEY (科室编号)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='科室信息表';

-- 2. 床位表
CREATE TABLE bed (
  床位号 CHAR(10) NOT NULL COMMENT '床位编号',
  病房号 CHAR(10) COMMENT '病房编号',
  所属科室 INT COMMENT '关联科室编号',
  PRIMARY KEY (床位号),
  FOREIGN KEY (所属科室) REFERENCES department(科室编号)
    ON DELETE SET NULL
    ON UPDATE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='床位信息表';

-- 3. 医生表
CREATE TABLE doctor (
  工作证号 INT NOT NULL COMMENT '医生工作证号',
  姓名 VARCHAR(10) NOT NULL COMMENT '医生姓名',
  性别 ENUM('男','女') NOT NULL COMMENT '医生性别',
  职称 VARCHAR(10) COMMENT '医生职称(如主治医师)',
  所属科室 INT COMMENT '关联科室编号',
  出生日期 DATE COMMENT '医生出生日期',
  PRIMARY KEY (工作证号),
  FOREIGN KEY (所属科室) REFERENCES department(科室编号)
    ON DELETE SET NULL
    ON UPDATE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='医生信息表';

-- 4. 病人表
CREATE TABLE patient (
  病例号 INT NOT NULL AUTO_INCREMENT COMMENT '病例编号(自增)',
  姓名 VARCHAR(10) NOT NULL COMMENT '病人姓名',
  性别 ENUM('男','女') NOT NULL COMMENT '病人性别',
  主管医生 INT COMMENT '关联医生工作证号',
  床位号 CHAR(10) COMMENT '关联床位编号',
  PRIMARY KEY (病例号),
  FOREIGN KEY (主管医生) REFERENCES doctor(工作证号)
    ON DELETE SET NULL
    ON UPDATE CASCADE,
  FOREIGN KEY (床位号) REFERENCES bed(床位号)
    ON DELETE SET NULL
    ON UPDATE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='病人信息表';

-- 5. 床位操作日志表
CREATE TABLE bed_oper_log (
  床位号 CHAR(10) NOT NULL COMMENT '床位编号',
  病房号 CHAR(10) COMMENT '病房编号',
  所属科室 INT COMMENT '关联科室编号',
  事件 TEXT COMMENT '操作事件类型',
  PRIMARY KEY (床位号)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4;

-- =============================================
-- 第三步:插入数据(无IGNORE,首次执行无重复)
-- =============================================
-- 1. 科室数据
INSERT INTO department (科室编号, 科室名, 科室地址, 科室电话, 科室主任)
VALUES
(1, '内科', '住院部1楼', '010-12345601', '张主任'),
(2, '外科', '住院部2楼', '010-12345602', '李主任'),
(3, '妇产科', '住院部3楼', '010-12345603', '王主任'),
(4, '儿科', '住院部4楼', '010-12345604', '赵主任'),
(5, '急诊科', '门诊楼1楼', '010-12345605', '刘主任');

-- 2. 床位数据
INSERT INTO bed (床位号, 病房号, 所属科室)
VALUES
('B0101', '101', 1),
('B0601', '601', 2);

-- =============================================
-- 第四步:创建索引(无IF NOT EXISTS,低版本兼容)
-- =============================================
CREATE INDEX KS_idx ON department(科室名);
CREATE INDEX Ni_idx ON doctor(姓名);

-- =============================================
-- 第五步:基础查询/索引查看
-- =============================================
-- 1. 查看索引信息
SHOW INDEX FROM department;
SHOW INDEX FROM doctor;

-- 2. 关联查询病人与主管医生
SELECT 
  p.*,
  d.姓名 AS 主管医生姓名,
  d.职称 AS 主管医生职称
FROM patient p
LEFT JOIN doctor d ON p.主管医生 = d.工作证号;

-- =============================================
-- 第六步:创建视图(无IF NOT EXISTS,低版本兼容)
-- =============================================
CREATE VIEW YS_View AS
SELECT 姓名, 性别, 职称, 所属科室 FROM doctor;

-- =============================================
-- 第七步:视图/日志查询(无语法错误)
-- =============================================
-- 1. 查询视图(无EXPLAIN换行问题,单行执行)
EXPLAIN SELECT * FROM YS_View;

-- 2. 查询床位操作日志(单行执行)
EXPLAIN SELECT * FROM bed_oper_log;

-- =============================================
-- 第八步:创建触发器(无IF NOT EXISTS,低版本兼容)
-- =============================================
DELIMITER //
CREATE TRIGGER trg_bed_insert_after
AFTER INSERT ON bed
FOR EACH ROW
BEGIN
  INSERT INTO bed_oper_log (床位号, 病房号, 所属科室, 事件)
  VALUES (NEW.床位号, NEW.病房号, NEW.所属科室, 'INSERT');
END //
DELIMITER ;

-- =============================================
-- 第九步:创建自定义函数(无IF NOT EXISTS,低版本兼容)
-- =============================================
DELIMITER //
CREATE FUNCTION sub_two_nums(
  num1 DECIMAL(10,2),
  num2 DECIMAL(10,2)
)
RETURNS DECIMAL(10,2)
DETERMINISTIC
BEGIN
  DECLARE result DECIMAL(10,2);
  SET result = num1 - num2;
  RETURN result;
END //
DELIMITER ;

-- =============================================
-- 第十步:调用函数(验证功能)
-- =============================================
SELECT sub_two_nums(12.5, 89);
相关推荐
Maverick061 小时前
Oracle Redo 日志操作手册
数据库·oracle
攒了一袋星辰1 小时前
高并发强一致性顺序号生成系统 -- SequenceGenerator
java·数据库·mysql
W.D.小糊涂1 小时前
gpu服务器安装windows+ubuntu24.04双系统
c语言·开发语言·数据库
云贝教育-郑老师1 小时前
【OceanBase 的多租户架构是怎样的?有什么优势?】
数据库·oceanbase
顶点多余2 小时前
使用C/C++语言链接Mysql详解
数据库·c++·mysql
xiaokangzhe2 小时前
MySQL 数据库操作
数据库·oracle
发际线还在3 小时前
互联网大厂Java三轮面试全流程实战问答与解析
java·数据库·分布式·面试·并发·系统设计·大厂
小王不爱笑1324 小时前
MyBatis 执行流程源码级深度解析:从 Mapper 接口到 SQL 执行的全链路逻辑
数据库·sql·mybatis
山峰哥4 小时前
SQL优化实战:从索引策略到执行计划的极致突破
数据库·sql·性能优化·编辑器·深度优先
总要冲动一次5 小时前
离线安装 percona-xtrabackup-24
linux·数据库·mysql·centos