数据库复习自用

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);
相关推荐
托尼吴17 分钟前
milvus 向量数据库学习笔记-基础认识
数据库·学习·milvus
徐同保18 分钟前
使用n8n中的HTTP Request节点清空pinecones向量数据库
数据库·网络协议·http
小北方城市网31 分钟前
第 9 课:Python 全栈项目性能优化实战|从「能用」到「好用」(企业级优化方案|零基础落地)
开发语言·数据库·人工智能·python·性能优化·数据库架构
ChineHe32 分钟前
Redis入门篇001_Redis简介与特性
数据库·redis·缓存
仓颉也为难32 分钟前
全表扫和索引在哪种场景哪个效率高、基线分水岭在哪
数据库
Anthony_23134 分钟前
MySql常用SQL命令
服务器·数据库·sql·mysql·http·oracle·udp
一直在追38 分钟前
大数据转型的“降维打击”:当分布式架构遇上向量数据库 (Milvus & ES 实战)
大数据·数据库
E_ICEBLUE43 分钟前
PPT 智能提取与分析实战:把演示文档变成结构化数据
数据库·python·powerpoint
困知勉行19851 小时前
Redis数据结构及其底层实现
数据库·redis·缓存
一直在追1 小时前
告别 WHERE id=1!大数据工程师的 AI 觉醒:手把手带你拆解向量数据库 (RAG 核心)
大数据·数据库