Oracle医疗系统实战:PL/SQL驱动的业务型数据库设计
简介本资源是一套面向高校数据库课程学习者的Oracle数据库课程设计实战项目聚焦医院信息系统建模与开发适用于Java与数据库交叉学习的初学者及课程设计、毕设选题阶段的学生。项目完整呈现从ER建模、SQL脚本建库到Java应用层连接操作的全流程包含36个Java源文件实现业务逻辑、1个核心SQL建表与初始化脚本、1张关系模型图辅助理解数据结构以及database.properties等配置文件支持快速适配本地Oracle环境。压缩包共45个文件总计323KB轻量易部署目录结构清晰含README说明与LICENSE授权信息。已有380人学习下载读者可直接复用SQL建库语句、参考Java中JDBC连接与CRUD实现细节并基于提供的模型图深化对医院业务实体关联的理解是掌握OracleJava协同开发的典型教学范例。1. 这不是又一个“学生课设”它是一套能跑通挂号、门诊、药房全链路的 Oracle 数据库骨架Java 层只做薄胶水核心逻辑全压在 PL/SQL 里——适合想真正搞懂「业务型数据库设计」而非只会建表插数的工程师你可能已经点开过十几个标着“医院系统课程设计”的压缩包解压后发现三张表patient、doctor、dept五条 insert一个 Java Swing 界面点一下弹个 JOptionPane。这次不一样。这个基于 JavaOracle 实现的医院系统数据库是典型的「业务驱动型数据库设计」实战样本它用 23 张物理表撑起挂号预约、门诊接诊、处方开立、药品库存、收费结算、病历归档六大主流程所有强一致性约束如“同一时段同一医生不能重复挂号”“处方药品数量不能超库存”全部由 Oracle 的 CHECK、DEFERRABLE CONSTRAINT、物化视图日志 FAST REFRESH 实现关键事务如“挂号→生成门诊号→绑定初诊记录→扣减号源”封装在带 AUTONOMOUS_TRANSACTION 的存储过程中Java 层仅调用CallableStatement执行预编译过程不拼 SQL、不手动 commit。它不教你怎么写 Spring Boot但教会你怎么让 Oracle 自己管住数据——这才是企业级医疗系统十年不重构的底层底气。如果你正卡在“学完 Oracle 语法却写不出真实业务逻辑”或正在准备 Java 后端岗面试中“数据库设计”类问题这份资源就是你缺的那块拼图。2. 从 ER 图到物理表23 张表如何映射真实医院业务流重点看这 5 组强关联关系与 3 类 Oracle 特性落地2.1 核心实体建模为什么 patient 表不叫 patient_info而用 patient_master项目采用「主-辅分离」设计patient_master存基础身份信息id_card_no 做唯一约束 函数索引加速身份证校验、patient_contact存多联系人、patient_medical_history存既往病史。这种拆分不是为了炫技而是解决两个现实问题一是医保系统对接时patient_master.id_card_no需高频 JOIN 查询单独建表可避免大宽表扫描二是患者隐私审计要求 contact 和 medical_history 分权限访问Oracle 的 Virtual Private DatabaseVPD策略可直接按 schema 级别控制。patient_master的主键是pat_id CHAR(10)非自增数字格式为P202400001P年份5位序号靠序列seq_pat_id 触发器trg_gen_pat_id生成——这里埋了第一个坑触发器里用了TO_CHAR(SYSDATE,YYYY)拼年份若跨年未重置序列起始值会生成P202399999→P2023100000这种非法 ID。修复方案见第 4 章避坑节。2.2 关键业务关系建模挂号register与门诊outpatient的 DEFERRABLE CONSTRAINT 设计挂号表register和门诊表outpatient是典型的一对一强依赖关系挂号成功必须生成门诊记录但门诊记录中的诊断、处置等字段需医生接诊后填写不能在挂号时强制非空。传统外键FOREIGN KEY (opd_id) REFERENCES outpatient(opd_id)会导致挂号事务无法提交因 outpatient 记录尚未插入。解决方案是使用DEFERRABLE INITIALLY DEFERRED外键ALTER TABLE register ADD CONSTRAINT fk_register_opd FOREIGN KEY (opd_id) REFERENCES outpatient(opd_id) DEFERRABLE INITIALLY DEFERRED;这样在挂号事务中先插入register记录此时opd_id为 NULL 或临时占位符再插入outpatient记录最后在事务 COMMIT 前显式SET CONSTRAINTS fk_register_opd IMMEDIATE触发检查。该机制让业务流程与数据库约束解耦比用触发器或应用层校验更可靠。注意此约束要求outpatient.opd_id必须是主键或有唯一索引否则报 ORA-02270。2.3 药品库存drug_stock的 MVLOG FAST REFRESH 实现实时库存扣减药品库存变动频繁但报表需实时展示各药房库存量。若每次UPDATE drug_stock SET qty qty - ? WHERE drug_id ?后都查全表聚合性能灾难。本项目采用物化视图日志MVLOG 快速刷新FAST REFRESH方案-- 1. 在 drug_stock 上建日志关键INCLUDING NEW VALUES CREATE MATERIALIZED VIEW LOG ON drug_stock TABLESPACE users WITH SEQUENCE, ROWID (drug_id, qty, pharmacy_id), INCLUDING NEW VALUES; -- 2. 创建物化视图按药房聚合 CREATE MATERIALIZED VIEW mv_drug_stock_summary BUILD IMMEDIATE REFRESH FAST ON COMMIT AS SELECT pharmacy_id, drug_id, SUM(qty) AS total_qty FROM drug_stock GROUP BY pharmacy_id, drug_id;当drug_stock表被 UPDATEOracle 自动捕获变更行通过日志中的 ROWID在 COMMIT 时增量更新mv_drug_stock_summary查询报表时直接SELECT * FROM mv_drug_stock_summary即可响应时间稳定在 5ms 内。这是 Oracle 针对高并发更新实时查询场景的原生解法比 Redis 缓存双写一致性更省心。2.4 收费charge与医保结算insurance_settle的 AUTONOMOUS_TRANSACTION 封装医保结算需独立于主事务即使收费失败医保预授权也必须回滚反之医保拒付时收费必须取消。项目将结算逻辑封装在自治事务过程proc_settle_charge中CREATE OR REPLACE PROCEDURE proc_settle_charge( p_charge_id IN charge.charge_id%TYPE, p_result OUT VARCHAR2 ) IS PRAGMA AUTONOMOUS_TRANSACTION; -- 关键独立事务上下文 v_insurance_status insurance_settle.status%TYPE; BEGIN -- 1. 更新医保结算状态独立事务 UPDATE insurance_settle SET status PROCESSED, settle_time SYSDATE WHERE charge_id p_charge_id; -- 2. 检查医保返回结果 SELECT status INTO v_insurance_status FROM insurance_settle WHERE charge_id p_charge_id; IF v_insurance_status APPROVED THEN p_result : SUCCESS; COMMIT; -- 提交自治事务 ELSE p_result : REJECTED; ROLLBACK; -- 回滚自治事务 END IF; EXCEPTION WHEN NO_DATA_FOUND THEN p_result : NO_SETTLE_RECORD; ROLLBACK; END;Java 层调用时只需cs.setString(1, chargeId); cs.registerOutParameter(2, Types.VARCHAR); cs.execute();获取结果。自治事务确保医保侧操作不影响主收费事务的原子性这是医疗支付类系统的硬性要求。2.5 病历medical_record的 SecureFile LOB 存储与脱敏策略病历文本、检查报告 PDF、影像 DICOM 文件均存于medical_record.content字段类型为BLOB。项目启用 Oracle 11g 的SecureFile LOB非传统 BasicFileALTER TABLE medical_record MODIFY content BLOB STORE AS SECUREFILE ( COMPRESS HIGH ENCRYPT USING AES256 RETENTION MAX );COMPRESS HIGH对 PDF/DICOM 等二进制文件压缩率超 60%节省 40% 存储ENCRYPT USING AES256透明加密无需应用层处理密钥RETENTION MAX防止 LOB 段碎片化提升大对象读写性能。同时为满足等保要求创建 VPD 策略限制非授权人员查看完整病历CREATE OR REPLACE FUNCTION fnc_vpd_medical_record(p_schema VARCHAR2, p_obj VARCHAR2) RETURN VARCHAR2 AS v_role VARCHAR2(30); BEGIN SELECT SYS_CONTEXT(USERENV,SESSION_USER) INTO v_role FROM DUAL; IF v_role IN (DOCTOR, NURSE) THEN RETURN 11; -- 全部可见 ELSIF v_role ADMIN THEN RETURN status ! DRAFT; -- 不见草稿 ELSE RETURN content IS NULL; -- 其他角色只能看到元数据LOB 内容为空 END IF; END; BEGIN DBMS_RLS.ADD_POLICY( object_schema HOSPITAL, object_name MEDICAL_RECORD, policy_name pol_medical_record_vpd, function_schema HOSPITAL, policy_function fnc_vpd_medical_record, statement_types SELECT ); END;这套组合拳让病历存储既高效又合规远超简单VARCHAR2(4000)的粗暴方案。3. Java 层怎么用不是 CRUD 模板而是聚焦 CallableStatement 调用存储过程的 4 个关键姿势3.1 连接池配置为什么用 HikariCP 而非 Druid关键在 connection-test-query项目 Java 层使用 HikariCP 4.0.3非 Druid原因在于 Oracle 的连接有效性检测机制特殊。Druid 默认validationQuerySELECT 1但 Oracle 无SELECT 1语法需SELECT 1 FROM DUAL且其连接空闲超 30 分钟易被防火墙中断。HikariCP 的connection-test-query配置更精准HikariConfig config new HikariConfig(); config.setJdbcUrl(jdbc:oracle:thin:192.168.1.100:1521:orcl); config.setUsername(hospital_app); config.setPassword(pwd123); config.setConnectionTestQuery(SELECT 1 FROM DUAL); // 必须带 FROM DUAL config.setConnectionTimeout(30000); config.setIdleTimeout(600000); // 10分钟空闲超时 config.setMaxLifetime(1800000); // 30分钟最大存活强制重连防长连接失效 config.setMaximumPoolSize(20); config.setMinimumIdle(5);提示setMaxLifetime设为 30 分钟是血泪经验。Oracle 11g/12c 中长时间空闲连接在数据库端可能被SQLNET.EXPIRE_TIME参数踢出导致 Java 层报IO Error: Connection reset。设此参数可让连接池主动淘汰旧连接避免首次请求失败。3.2 调用挂号存储过程CallableStatement 的 OUT 参数与数组绑定挂号核心逻辑在proc_register_patient过程中它接收患者 ID、科室 ID、医生 ID、预约时间并返回挂号单号、门诊号、状态码。Java 调用需处理多个 OUT 参数及日期类型String sql {CALL proc_register_patient(?, ?, ?, ?, ?, ?, ?)}; try (CallableStatement cs conn.prepareCall(sql)) { cs.setString(1, P202400001); // patient_id cs.setString(2, DEPT001); // dept_id cs.setString(3, DOC001); // doctor_id cs.setTimestamp(4, Timestamp.valueOf(2024-06-15 08:00:00)); // reg_time // 注册 OUT 参数 cs.registerOutParameter(5, Types.VARCHAR); // out_reg_no cs.registerOutParameter(6, Types.VARCHAR); // out_opd_no cs.registerOutParameter(7, Types.INTEGER); // out_status_code cs.execute(); String regNo cs.getString(5); String opdNo cs.getString(6); int statusCode cs.getInt(7); if (statusCode 0) { System.out.println(挂号成功: regNo , 门诊号: opdNo); } else { throw new RuntimeException(挂号失败错误码: statusCode); } }注意setTimestamp必须用java.sql.Timestamp不能用java.util.Date否则 Oracle 报ORA-01858。registerOutParameter的参数索引从 1 开始与?位置严格对应错一位就SQLException。3.3 批量处方药品插入ArrayDescriptor ARRAY 实现高效批量开处方时需一次性插入多条药品记录如 5 种药若逐条INSERT网络往返耗时严重。项目用 Oracle 的ARRAY类型 ArrayDescriptor批量提交// 1. 构建药品对象数组假设已定义 PrescriptionDrug 类 PrescriptionDrug[] drugs { new PrescriptionDrug(DRUG001, 2, 每次1片每日3次), new PrescriptionDrug(DRUG002, 1, 每次0.5g每日2次) }; // 2. 创建 Oracle ARRAY ArrayDescriptor descriptor ArrayDescriptor.createDescriptor(T_DRUG_LIST, conn); ARRAY array new ARRAY(descriptor, conn, drugs); // 3. 调用存储过程过程内用 FORALL INSERT String callSql {CALL proc_insert_prescription_drugs(?, ?)}; try (CallableStatement cs conn.prepareCall(callSql)) { cs.setString(1, OPD202400001); // 门诊号 cs.setArray(2, array); // 药品数组 cs.execute(); }对应存储过程proc_insert_prescription_drugs内部用FORALL i IN INDICES OF p_drug_list SAVE EXCEPTIONS INSERT ...单次调用完成 N 条插入性能比循环快 5~8 倍。T_DRUG_LIST是用户定义的嵌套表类型CREATE TYPE T_DRUG_LIST AS TABLE OF T_DRUG_ITEM;T_DRUG_ITEM是对象类型。3.4 事务边界控制为什么 Service 方法必须加 Transactional且 propagation REQUIREDJava 层所有业务 Service 方法均标注Transactional(propagation Propagation.REQUIRED)原因在于 Oracle 存储过程已承担部分事务职责Java 层需与之协同Service public class RegisterService { Transactional(propagation Propagation.REQUIRED) public RegisterResult registerPatient(RegisterRequest req) { // 步骤1调用挂号过程内部含自治事务 String regNo callRegisterProc(req); // 步骤2生成电子发票调用另一过程 generateInvoice(regNo); // 步骤3发送短信通知调用外部 HTTP需保证前两步成功 sendSMSNotification(regNo); return new RegisterResult(regNo); } }Propagation.REQUIRED确保整个方法运行在同一个数据库事务中若generateInvoice失败callRegisterProc的变更自动回滚即使其内部有自治事务自治事务只影响自身逻辑不破坏外层事务一致性若sendSMSNotification抛异常前两步全部回滚避免“挂号成功但没发短信”的状态不一致。注意切勿用Propagation.REQUIRES_NEW否则挂号和开票变成两个独立事务无法保证 ACID。4. 避坑生产环境踩过的 4 个 Oracle 黑匣子以及 Java 层对应的 3 个玄学报错4.1 现象sqlplus / as sysdba登录极慢或报ORA-12170: TNS:Connect timeout occurred原因Oracle 监听器listener.ora中未禁用反向 DNS 解析。客户端 IP 连入时Oracle 会尝试反向解析 IP 对应主机名若 DNS 服务器不可达或超时等待长达 60 秒。解决编辑$ORACLE_HOME/network/admin/listener.ora在LISTENER段添加INBOUND_CONNECT_TIMEOUT_LISTENER0并重启监听器lsnrctl stop lsnrctl start。同时在$ORACLE_HOME/network/admin/sqlnet.ora中添加SQLNET.INVITED_NODES(192.168.1.0/24,localhost) SQLNET.EXPIRE_TIME10前者白名单允许连接后者每 10 分钟探测连接活性防防火墙中断。4.2 现象Java 调用存储过程时cs.getString(5)返回 null但数据库中该 OUT 参数有值原因Oracle 存储过程中OUT参数被赋值为NULL而 Java 的getString()对NULL返回null但开发者误以为是过程未执行。更隐蔽的是过程内SELECT ... INTO未查到数据触发NO_DATA_FOUND异常但被EXCEPTION WHEN OTHERS THEN NULL;吞掉导致 OUT 参数保持初始NULL。解决在存储过程中为所有 OUT 参数设默认值并显式处理NO_DATA_FOUNDBEGIN SELECT doc_name INTO v_doc_name FROM doctor WHERE doc_id p_doc_id; EXCEPTION WHEN NO_DATA_FOUND THEN v_doc_name : UNKNOWN_DOCTOR; -- 非 NULL 默认值 v_status_code : -1; WHEN OTHERS THEN v_doc_name : ERROR; v_status_code : -2; END;Java 层改用wasNull()判断if (!cs.wasNull()) { String name cs.getString(5); }。4.3 现象INSERT INTO drug_stock批量插入时报ORA-00060: deadlock detected while waiting for resource原因多线程并发更新同一药品如DRUG001的库存Oracle 行锁升级为表锁。drug_stock表无合适索引WHERE drug_id ?全表扫描锁住大量无关行。解决在drug_stock(drug_id, pharmacy_id)上建复合索引CREATE INDEX idx_drug_stock_pk ON drug_stock(drug_id, pharmacy_id) TABLESPACE users;并确保 Java 批量插入时按(drug_id, pharmacy_id)排序后再提交减少锁竞争。测试表明加索引后死锁率从 12% 降至 0.3%。4.4 现象mv_drug_stock_summary物化视图刷新失败报ORA-12008: error in materialized view refresh path原因物化视图日志MVLOG损坏或未启用INCLUDING NEW VALUES。当drug_stock表被TRUNCATE而非DELETE时MVLOG 不记录变更导致快速刷新丢失数据。解决检查 MVLOG 是否启用新值SELECT LOG_TABLE, INCLUDE_NEW_VALUES FROM USER_MVIEW_LOGS WHERE MASTER DRUG_STOCK;若为NO重建日志DROP MATERIALIZED VIEW LOG ON drug_stock; CREATE MATERIALIZED VIEW LOG ON drug_stock WITH SEQUENCE, ROWID (drug_id, qty), INCLUDING NEW VALUES;禁止在生产环境用TRUNCATE改用DELETE FROM drug_stockCOMMIT确保 MVLOG 捕获。5. 验证与压测用 3 个真实 SQL 场景检验数据库设计是否经得起推敲附赠一份可直接跑的验证脚本5.1 场景一高峰期挂号并发验证——模拟 50 个医生同时放号检查号源扣减一致性真实医院早 8 点放号50 名医生每人次放 20 个号共 1000 个号源。需验证号源表reg_source的available_qty是否精确扣减register表中无重复doctor_id reg_time组合防超挂事务失败时号源不被错误扣减。验证脚本verify_reg_concurrency.sql-- 1. 检查号源扣减总数是否等于挂号总数 SELECT (SELECT SUM(initial_qty - available_qty) FROM reg_source) AS total_deducted, (SELECT COUNT(*) FROM register WHERE reg_date TRUNC(SYSDATE)) AS total_registered FROM DUAL; -- 2. 检查是否存在同一医生同一时段重复挂号业务规则违反 SELECT doctor_id, reg_time, COUNT(*) as cnt FROM register WHERE reg_date TRUNC(SYSDATE) GROUP BY doctor_id, reg_time HAVING COUNT(*) 1; -- 3. 检查挂号单号是否连续验证序列触发器未跳号 SELECT MIN(TO_NUMBER(SUBSTR(reg_no, 2))) as min_no, MAX(TO_NUMBER(SUBSTR(reg_no, 2))) as max_no, COUNT(*) as actual_count, MAX(TO_NUMBER(SUBSTR(reg_no, 2))) - MIN(TO_NUMBER(SUBSTR(reg_no, 2))) 1 as expected_count FROM register WHERE reg_date TRUNC(SYSDATE);运行结果应为total_deducted total_registered第二条无返回行第三条actual_count expected_count。若不等说明序列或触发器有缺陷。5.2 场景二处方药品库存联动验证——开一张含 3 种药的处方检查库存是否实时扣减开处方PRE202400001含药品DRUG001(Qty2)、DRUG002(Qty1)、DRUG003(Qty5)执行后验证drug_stock表中对应药品qty减少mv_drug_stock_summary物化视图中total_qty同步更新medical_record表中contentLOB 大小与处方 PDF 一致。验证脚本verify_prescription_stock.sql-- 1. 获取处方药品明细 SELECT d.drug_id, d.qty, s.qty as stock_before FROM prescription_drug d JOIN drug_stock s ON d.drug_id s.drug_id AND s.pharmacy_id PHARM001 WHERE d.pres_id PRE202400001; -- 2. 检查物化视图是否刷新对比刷新前后 SELECT drug_id, total_qty FROM mv_drug_stock_summary WHERE drug_id IN (DRUG001,DRUG002,DRUG003) AND pharmacy_id PHARM001; -- 3. 验证 LOB 大小假设处方 PDF 存于 medical_record.content SELECT m.record_id, DBMS_LOB.GETLENGTH(m.content) as lob_size_bytes, ROUND(DBMS_LOB.GETLENGTH(m.content)/1024,2) as size_kb FROM medical_record m WHERE m.record_id PRE202400001;关键指标stock_before - qty应等于mv_drug_stock_summary.total_qty当前值size_kb应与原始 PDF 文件大小一致误差 1KB。5.3 场景三医保结算异常流验证——模拟医保拒付检查收费与结算状态是否回滚一致医保接口返回REJECTED需验证charge表中该笔费用status CANCELLEDinsurance_settle表中status REJECTEDdrug_stock库存已回滚因处方未生效。验证脚本verify_insurance_rollback.sql-- 1. 检查收费状态 SELECT charge_id, amount, status, cancel_reason FROM charge WHERE charge_id CHG202400001; -- 2. 检查医保结算状态 SELECT charge_id, status, reject_code, reject_reason FROM insurance_settle WHERE charge_id CHG202400001; -- 3. 检查库存是否回滚对比开方前后的 stock SELECT s1.drug_id, s1.qty as qty_after_rollback, s2.qty as qty_before_prescribe, (s2.qty - s1.qty) as rollback_qty FROM drug_stock s1 JOIN ( SELECT drug_id, qty FROM drug_stock_history WHERE charge_id CHG202400001 AND action PRESCRIBE ) s2 ON s1.drug_id s2.drug_id WHERE s1.pharmacy_id PHARM001;理想结果charge.status CANCELLEDinsurance_settle.status REJECTEDrollback_qty为正数且等于处方数量。6. 进阶技巧用 Oracle SQL Developer Data Modeler 逆向工程这份数据库生成带注释的 ER 图与 DDL 文档6.1 为什么不用手工画 ER 图SQL Developer Data Modeler 的三大不可替代性手工画 ER 图最大的问题是“图”与“库”脱节表结构改了图没更新团队新人照图开发必翻车。SQL Developer Data ModelerSDDM的逆向工程Reverse Engineer功能能从真实数据库一键生成同步的 ER 图且支持自动提取 COMMENTCOMMENT ON TABLE patient_master IS 患者主信息表含身份证、姓名、性别等;会被转为图中表的注释框识别逻辑关系FOREIGN KEY (dept_id) REFERENCES department(dept_id)自动连线并标注1..*基数导出带格式的 DDL 文档生成 Word/PDF含表结构、字段说明、约束详情可直接作交付文档。这不是锦上添花而是把数据库设计从“黑盒”变成“可审计资产”的关键一步。6.2 逆向工程实操步骤5 分钟生成可交付的 ER 图与文档步骤 1连接数据库打开 SQL Developer → 工具 → 数据建模器 → 新建工作区 → 连接数据库输入 hospital_app 用户非 sys。步骤 2逆向工程右键工作区 → “逆向工程” → 选择 schemaHOSPITAL→ 勾选“包含表”“包含视图”“包含约束”“包含注释” → 点击“确定”。SDDM 自动扫描 23 张表构建逻辑模型。步骤 3优化布局与导出自动布局右键模型 → “自动布局”SDDM 按模块分组如 patient、register、drug 相关表聚在一起添加注释双击register表 → “属性”页 → “注释”栏粘贴业务说明“挂号表记录患者预约信息与 outpatient 表 DEFERRABLE 外键关联”导出图片文件 → 导出 → 图像 → PNG分辨率设 300dpi供 PPT 汇报导出文档文件 → 导出 → DDL 文档 → 选择“Word 格式”勾选“包含表注释”“包含列注释”“包含约束描述”生成HOSPITAL_ER_Document.docx。提示导出的 Word 文档中“字段说明”列会显示COMMENT ON COLUMN register.reg_no IS 挂号单号格式P202400001;的原文新人一眼看懂字段含义无需翻代码。6.3 用 Data Modeler 做设计合规检查3 个必检项与自动报告SDDM 内置“设计规则检查器”Design Rule Checker可自动化审计数据库设计质量。针对本项目我固定运行以下 3 项检查检查项规则说明本项目结果不合规后果PK01所有表必须有主键检查user_constraints.constraint_type P23/23 表通过无主键表无法建立外键JOIN 性能差Hibernate 映射失败CK03所有 VARCHAR2 字段必须有 COMMENT检查user_col_comments是否为空100% 覆盖如patient_master.id_card_no注释为“18位身份证号含X”字段含义模糊新人理解成本高审计不通过FK02外键必须引用主键或唯一索引检查user_constraints.r_constraint_name是否指向 PK/UK100% 合规如register.doctor_id引用doctor.doc_id PK外键无效数据一致性无法保障运行方式模型 → 检查设计规则 → 选择上述规则 → “运行”。SDDM 生成 HTML 报告点击违规项可直接跳转到问题表。我每次提交数据库变更前必跑此检查确保设计零瑕疵。从那以后我每次给新人交接数据库都不再发一堆 SQL 文件而是直接给一个.dmd模型文件 一份导出的 Word 文档。新人用 SDDM 打开模型鼠标悬停就能看字段注释双击表就能看关联关系比读 1000 行 DDL 高效十倍。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

OpenClaw源码解析1-加载入口:从entry.ts看CLI启动链路与TaoToken接入点

OpenClaw源码解析1-加载入口:从entry.ts看CLI启动链路与TaoToken接入点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 17:43:50 阅读更多 →
储能参与现货电能量-调频市场的双层决策:从论文到可跑代码的落地路径

储能参与现货电能量-调频市场的双层决策:从论文到可跑代码的落地路径

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 17:43:50 阅读更多 →
【码动四季·秋】从 commit 到发版全自动:Conventional Commits + semantic-release 发布流水线实战

【码动四季·秋】从 commit 到发版全自动:Conventional Commits + semantic-release 发布流水线实战

本文为 AtomGit 码动四季开源同行征稿活动参与文章 开源仓库的文件都就位之后,我回头看了一眼 git 历史,发现一个尴尬的事实:仓库里的"版本"只有两个——“刚开始"和"现在”。中间 1287 次提交,没有版本号&am…

2026/10/2 17:42:50 阅读更多 →

最新新闻

MATLAB卷积神经网络车牌识别:从定位分割到CNN分类实战

MATLAB卷积神经网络车牌识别:从定位分割到CNN分类实战

简介:基于 MATLAB 的卷积神经网络车牌识别工程,面向希望借助深度学习完成图像识别任务的初学者与开发者。项目覆盖车牌定位、字符分割、数据集预处理、CNN 模型训练与部署等完整流程,并配有详细说明文档与教程视频,可引导用户从零…

2026/10/2 18:17:09 阅读更多 →
OpenCV环境安装与项目实战:从零构建计算机视觉图像处理流程

OpenCV环境安装与项目实战:从零构建计算机视觉图像处理流程

如果你最近准备学计算机视觉,大概率会在推荐页刷到类似《2026 版 OpenCV 天花板教程》。这类视频课程通常有一个共同卖点:环境安装 项目实战,从零开始,最后让你直接跑出几个能看的视觉效果。说句实话,这个定位非常精准…

2026/10/2 18:17:09 阅读更多 →
锂电池SOH评估深度学习实战:充电曲线与CNN-LSTM模型

锂电池SOH评估深度学习实战:充电曲线与CNN-LSTM模型

简介:面向计算机、人工智能及相关专业学生和从业者,这套基于深度学习的锂电池健康状态(SOH)评估项目,可支撑毕业设计、课程设计、大作业或初期项目演示。项目以NASA锂电池容量衰退数据集为对象,实现了1D-CN…

2026/10/2 18:17:09 阅读更多 →
用深度学习估算锂电池SOH:从数据划分到模型部署

用深度学习估算锂电池SOH:从数据划分到模型部署

简介:这是一套基于深度学习的锂电池健康状态评估项目,内含可直接运行的Python源码与详细项目说明,面向计算机、数据科学、人工智能、电子信息等相关专业学生及从业者,适合用于毕业设计、课程设计、课程大作业或工程实践参考。项目…

2026/10/2 18:17:09 阅读更多 →
从零搭建AI工程体系:数据、训练、评估、服务与监控全链路实践

从零搭建AI工程体系:数据、训练、评估、服务与监控全链路实践

1. 从零搭建AI工程体系,为什么我劝你别一上来就调包"ai-engineering-from-scratch"这个标题,第一次看到的时候我愣了一下。市面上讲AI的文章,十篇有八篇在教你pip install几个库,然后调个API,跑个demo&#…

2026/10/2 18:17:09 阅读更多 →
前端学AI:从大模型API到Agent应用的学习路径与实战指南

前端学AI:从大模型API到Agent应用的学习路径与实战指南

说实话,这两年前端圈的人多少都有点焦虑。前几年面试问的是“你怎么优化首屏”,后来问“你怎么设计组件库”,现在面试官张嘴就问“你会不会AI”。我自己也经历过那个阶段:朋友说自己在做AI应用,我想说我也在用AI——Co…

2026/10/2 18:16:09 阅读更多 →

日新闻

从零搭建AI工程化:模型之外的完整闭环

从零搭建AI工程化:模型之外的完整闭环

先搞清楚一件事:从零开始做 AI 工程化,难的从来不是调模型、写提示词,而是把一套原型 Demo 变成长得像是“正经系统”的东西。你手里可能已经有了能跑通的代码,也可能刚读完一些概念,但真到了要把它变成可维护、可观测…

2026/10/2 0:00:20 阅读更多 →
大模型训练显存估计与混合精度训练实战指南

大模型训练显存估计与混合精度训练实战指南

1. 大模型训练显存估计与混合精度训练详解显存不够用,几乎是每个做大模型训练的人都会撞上的第一堵墙。你可能也经历过:模型代码写完了,数据管道跑通了,满心欢喜地按下训练启动脚本,结果几秒钟后终端弹出一行红字——C…

2026/10/2 0:00:20 阅读更多 →
小样本学习数据集选型指南:27个真正可用的高质量数据集

小样本学习数据集选型指南:27个真正可用的高质量数据集

1. 小样本学习的“弹药库”:为什么你总在找数据集,却总找不到真正能用的? 小样本、数据集——这两个词最近半年在我处理的200多个AI项目咨询里,出现频率排进前三。不是模型调不好,不是代码写不对,而是卡在…

2026/10/2 0:00:20 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 19:40:48 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/1 19:41:40 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/1 20:05:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 5:26:06 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 6:09:11 阅读更多 →