-- ============================================================ -- 桃育种系统 - 一期业务表建表 SQL(breeding 全量 14 域) -- 依据: 后端 ORM 模型 (backend/app/api/v1/module_bre/**/model.py) -- 对齐 doc/桃育种系统业务功能规划报告.md 第九节(2026-07-28 实际落地) -- 说明: -- 1. bre_germplasm 等表由 create_all 建;本文件为可读 schema 参考。 -- 2. 审计字段(id/uuid/is_deleted/created_time/updated_time/deleted_time/ -- created_id/updated_id/deleted_id)由基类 ModelMixin/UserMixin 提供。 -- 3. 外键统一引用 sys_user(id) ON DELETE SET NULL(审计人); -- 业务外键引用本文件内表,统一 ON DELETE CASCADE(级联删除)。 -- 4. 状态/类别字段以 varchar 存字典存储值(英码 dict_value,如 common/strong/alive), -- 展示中文 dict_label;[字典: ] 标注的字段其取值来自 sys_dict,种子见 -- bre_dict.sql,导入经 DictLabelResolver 翻译、前端经 useDictStore 取 label; -- [字典: 待补] 表示模型标注为字典字段但尚无种子 SQL,取值待定。 -- 5. 育种目标独立成表 bre_target(主数据);杂交组合单选引用其一, -- 以便后期按"组合→目标→目标性状阈值→单株达标判定"统计每组合达标率。 -- 6. 育种单株独立成表 bre_tree(新增实体);tree_evaluation / -- tree_photo / selection_result 经 tree_id 外键关联,删树级联删下游三表。 -- 7. 人员独立成表 bre_personnel(方案B);5 个业务域经 -- bre_personnel_id 外键引用(授粉人/定植人/育苗人/评价人/种子处理人)。 -- 8. 无 status 字段的表,model 中已覆盖 __table_args__ 去掉 status 索引 -- (仅保留 (created_time, is_deleted) 复合索引用于数据权限过滤)。 -- 9. 日期字段以 varchar(20) 存文本日期(如 '2026-07-28'),非 timestamptz。 -- ============================================================ -- ============================================================ -- 模块1: 亲本资源管理 -- ============================================================ -- 表: bre_germplasm (亲本资源) -- 设计说明: 保存育种用种质/品种档案,作为杂交组合的母本与父本来源。 -- 与其它表关系: -- * 上游: 无 -- * 下游: 被 cross_combination(female_parent_id/male_parent_id) 引用; -- 被 bre_germplasm_photo(独立文件) 经 germplasm_id 引用 -- 字典来源字段: variety_type(变种类型), firmness(硬度), maturity_period(成熟期:早/中/晚), -- flowering_period(花期) —— 均 [字典],见 bre_dict.sql -- 逻辑关系: 删除种质 → 级联删除其照片子表;作为母/父本被组合引用时随组合级联删除 CREATE TABLE IF NOT EXISTS bre_germplasm ( cultivar_name varchar(100) NOT NULL, -- 品种/种质名称 variety_type varchar(20), -- 变种类型(普通桃/油桃/蟠桃/油蟠桃/黄肉) [字典: variety_type] origin varchar(200), -- 来源 preservation_site varchar(200), -- 保存地 avg_fruit_weight numeric(8,2), -- 平均果重(g) ssc numeric(4,1), -- 可溶性固形物(%) firmness varchar(20), -- 硬度 [字典: firmness] maturity_period varchar(20), -- 成熟期(早/中/晚) [字典: maturity_period] flowering_period varchar(20), -- 花期 [字典: flowering_period] chilling_requirement integer, -- 需冷量(h) disease_resistance text, -- 抗病性描述 can_be_female boolean NOT NULL DEFAULT false, -- 可作母本 can_be_male boolean NOT NULL DEFAULT false, -- 可作父本 pedigree_note text, -- 系谱备注 photo_path varchar(500), -- 照片地址(图片URL) id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_germplasm_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_germplasm IS '亲本资源表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_germplasm_created_deleted ON bre_germplasm (created_time, is_deleted); -- ============================================================ -- 模块2: 基地/试验地管理 -- ============================================================ -- 表: bre_site (基地/试验地) -- 设计说明: 试验基地/试验站主数据,定植与授粉的地点来源。 -- 与其它表关系: -- * 上游: 无 -- * 下游: 被 bre_plot(site_id) 引用 -- 字典来源字段: eco_type(生态区类型:华北/西北/华东/西南/东北/华南) [字典],见 bre_dict.sql -- 逻辑关系: 删除基地 → 级联删除其下所有地块 CREATE TABLE IF NOT EXISTS bre_site ( site_name varchar(100) NOT NULL, -- 基地/试验地名称 address varchar(255), -- 详细地址 area float, -- 基地面积(亩) longitude float, -- 经度 latitude float, -- 纬度 eco_type varchar(50), -- 生态区类型(华北/西北/华东/...) [字典: eco_type] remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_site_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_site IS '基地/试验地管理表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_site_created_deleted ON bre_site (created_time, is_deleted); -- 表: bre_plot (区块: 基地内区块划分) -- 设计说明: 基地内区块划分,作为单株定植的网格位置。 -- 与其它表关系: -- * 上游: 引用 bre_site(site_id) -- * 下游: 被 pollination(plot_id)/planting(plot_id)/tree(plot_id) 引用 -- 字典来源字段: row_orientation(行向:南北行/东西行) [字典],见 bre_dict.sql -- 逻辑关系: 删除地块 → 级联删除引用该地块的授粉/定植/单株记录 CREATE TABLE IF NOT EXISTS bre_plot ( site_id integer NOT NULL REFERENCES bre_site(id) ON DELETE CASCADE, -- 所属基地 plot_code varchar(50) NOT NULL, -- 区块编号/名称 row_orientation varchar(20), -- 行向(南北行/东西行) [字典: row_orientation] row_count integer, -- 行数 col_count integer, -- 每行株数 grid_note text, -- 株行距/网格说明 area float, -- 地块面积(亩) id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_plot_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_plot IS '基地内区块划分表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_plot_site ON bre_plot (site_id); CREATE INDEX IF NOT EXISTS ix_bre_plot_created_deleted ON bre_plot (created_time, is_deleted); -- ============================================================ -- 模块3: 人员花名册 -- ============================================================ -- 表: bre_personnel (人员花名册,独立人员表/方案B) -- 设计说明: 记录参与育种的人员;被 5 个业务域经 bre_personnel_id 引用, -- 作为"干活的人"(授粉人/定植人/育苗人/评价人/种子处理人)。 -- 与其它表关系: -- * 上游: 无 -- * 下游: 被 pollination/planting/seedling/tree_evaluation/seed_treatment -- 的 bre_personnel_id 引用 -- 字典来源字段: gender(性别:男/女) [字典], role(角色:育种专家/技术员/管理员) [字典],见 bre_dict.sql -- 逻辑关系: 删除人员 → 级联删除各业务记录中该人员引用(外键均 CASCADE) CREATE TABLE IF NOT EXISTS bre_personnel ( name varchar(100) NOT NULL, -- 姓名 gender varchar(50), -- 性别(男/女) [字典: gender] role varchar(50), -- 角色(育种专家/技术员/管理员) [字典: personnel_role] phone varchar(100), -- 联系电话 organization varchar(100), -- 所属单位 join_date varchar(20), -- 入职日期 remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_personnel_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_personnel IS '人员花名册表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_personnel_created_deleted ON bre_personnel (created_time, is_deleted); -- ============================================================ -- 模块4: 育种目标(主数据) -- ============================================================ -- 表: bre_target (育种目标主数据) -- 设计说明: 预置"6大品种系列"(大果型/早熟/黄肉/油桃/蟠桃/加工型)等目标,由育种家维护; -- 杂交组合单选引用其一,作为该组合达标率统计的统一基准。 -- 与其它表关系: -- * 上游: 无 -- * 下游: 被 cross_combination(bre_target_id) 引用 -- 字典来源字段: series(系列/品系) [字典], is_preset(是否预设:1/0) [字典],见 bre_dict.sql -- 逻辑关系: 删除目标 → 级联删除引用它的杂交组合 CREATE TABLE IF NOT EXISTS bre_target ( target_name varchar(100) NOT NULL, -- 目标名称,如"优质大果型" series varchar(100), -- 系列/品系 [字典: series] description text, -- 目标说明/关键性状描述 is_preset varchar(50), -- 是否预设(1/0) [字典: is_preset] remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_target_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_target IS '育种目标主数据表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_target_created_deleted ON bre_target (created_time, is_deleted); -- ============================================================ -- 模块5: 组合选配 -- ============================================================ -- 表: bre_cross_combination (杂交组合) —— 全模块关系枢纽 -- 设计说明: 记录母本/父本/育种目标/杂交方式;下游授粉/种子/育苗/定植/单株 -- 均挂靠本表 combination_id,是整条育种管线的核心枢纽。 -- 与其它表关系: -- * 上游: 引用 bre_target(bre_target_id)、bre_germplasm(female_parent_id/male_parent_id) -- * 下游: 被 pollination/seed_treatment/seedling/planting/tree/tree_evaluation/ -- tree_photo/selection_result 的 combination_id 引用(共 8 张表) -- 字典来源字段: cross_method(杂交方式:人工杂交/自然授粉/回交) [字典],见 bre_dict.sql -- 逻辑关系: 删除组合 → 级联删除其下全部 8 张下游业务表记录 CREATE TABLE IF NOT EXISTS bre_cross_combination ( combination_code varchar(100) NOT NULL, -- 组合编号 YY+3位序号(自动生成) cross_year integer, -- 杂交年份 bre_target_id integer NOT NULL REFERENCES bre_target(id) ON DELETE CASCADE, -- 育种目标(单选,主数据) female_parent_id integer REFERENCES bre_germplasm(id) ON DELETE CASCADE, -- 母本 male_parent_id integer REFERENCES bre_germplasm(id) ON DELETE CASCADE, -- 父本 cross_method varchar(50), -- 杂交方式(人工杂交/自然授粉/回交) [字典: cross_method] cross_date varchar(20), -- 杂交日期 seed_count integer, -- 获种数 remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_cross_combination_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_cross_combination IS '杂交组合选配表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_cross_combination_target ON bre_cross_combination (bre_target_id); CREATE INDEX IF NOT EXISTS ix_bre_cross_combination_female ON bre_cross_combination (female_parent_id); CREATE INDEX IF NOT EXISTS ix_bre_cross_combination_male ON bre_cross_combination (male_parent_id); CREATE INDEX IF NOT EXISTS ix_bre_cross_combination_created_deleted ON bre_cross_combination (created_time, is_deleted); -- ============================================================ -- 模块6: 杂交授粉 -- ============================================================ -- 表: bre_pollination (授粉记录) -- 设计说明: 杂交授粉过程记录,挂靠杂交组合与试验地块。 -- 与其它表关系: -- * 上游: 引用 cross_combination(combination_id)、plot(plot_id)、personnel(bre_personnel_id 授粉人) -- * 下游: 无 -- 字典来源字段: 无(本表未设字典字段) -- 逻辑关系: 删除组合/地块/授粉人 → 级联删除本记录(外键均 CASCADE) CREATE TABLE IF NOT EXISTS bre_pollination ( combination_id integer NOT NULL REFERENCES bre_cross_combination(id) ON DELETE CASCADE, -- 所属组合 plot_id integer REFERENCES bre_plot(id) ON DELETE CASCADE, -- 试验地块 pollination_date varchar(20), -- 授粉日期 flower_count integer, -- 花朵数 effective_count integer, -- 有效坐果数 bre_personnel_id integer REFERENCES bre_personnel(id) ON DELETE CASCADE, -- 授粉人 remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_pollination_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_pollination IS '杂交授粉记录表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_pollination_combination ON bre_pollination (combination_id); CREATE INDEX IF NOT EXISTS ix_bre_pollination_plot ON bre_pollination (plot_id); CREATE INDEX IF NOT EXISTS ix_bre_pollination_personnel ON bre_pollination (bre_personnel_id); CREATE INDEX IF NOT EXISTS ix_bre_pollination_created_deleted ON bre_pollination (created_time, is_deleted); -- ============================================================ -- 模块7: 种子处理 -- ============================================================ -- 表: bre_seed_treatment (种子处理) -- 设计说明: 采果后种子处理(沙藏/胚培等)记录。 -- 与其它表关系: -- * 上游: 引用 cross_combination(combination_id)、personnel(bre_personnel_id 种子处理人) -- * 下游: 无 -- 字典来源字段: treatment_method(处理方式:沙藏/层积/低温冷藏/常温) [字典],见 bre_dict.sql -- 逻辑关系: 删除组合/处理人 → 级联删除本记录(外键均 CASCADE) CREATE TABLE IF NOT EXISTS bre_seed_treatment ( combination_id integer NOT NULL REFERENCES bre_cross_combination(id) ON DELETE CASCADE, -- 所属组合 treatment_method varchar(30), -- 处理方式(沙藏/层积/低温冷藏/常温) [字典: seed_treatment_method] treatment_start varchar(20), -- 处理开始日期 treatment_end varchar(20), -- 处理结束日期 germination_rate float, -- 发芽率(%) bre_personnel_id integer REFERENCES bre_personnel(id) ON DELETE CASCADE, -- 种子处理人 remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_seed_treatment_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_seed_treatment IS '种子处理记录表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_seed_treatment_combination ON bre_seed_treatment (combination_id); CREATE INDEX IF NOT EXISTS ix_bre_seed_treatment_personnel ON bre_seed_treatment (bre_personnel_id); CREATE INDEX IF NOT EXISTS ix_bre_seed_treatment_created_deleted ON bre_seed_treatment (created_time, is_deleted); -- ============================================================ -- 模块8: 杂种苗培育 -- ============================================================ -- 表: bre_seedling (杂种苗) -- 设计说明: 播种育苗记录,溯源到杂交组合;可被定植批次引用。 -- 与其它表关系: -- * 上游: 引用 cross_combination(combination_id)、personnel(bre_personnel_id 育苗人) -- * 下游: 被 planting(seedling_id) 引用 -- 字典来源字段: 无 -- 逻辑关系: 删除组合/育苗人 → 级联删除本记录;删除育苗 → 级联删除引用它的定植记录 CREATE TABLE IF NOT EXISTS bre_seedling ( combination_id integer NOT NULL REFERENCES bre_cross_combination(id) ON DELETE CASCADE, -- 所属组合 sowing_date varchar(20), -- 播移日期 tray_no varchar(100), -- 穴盘号 nursery varchar(100), -- 苗圃 seedling_count integer, -- 出苗数 bre_personnel_id integer REFERENCES bre_personnel(id) ON DELETE CASCADE, -- 育苗人 remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_seedling_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_seedling IS '杂种苗培育记录表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_seedling_combination ON bre_seedling (combination_id); CREATE INDEX IF NOT EXISTS ix_bre_seedling_personnel ON bre_seedling (bre_personnel_id); CREATE INDEX IF NOT EXISTS ix_bre_seedling_created_deleted ON bre_seedling (created_time, is_deleted); -- ============================================================ -- 模块9: 田间定植 -- ============================================================ -- 表: bre_planting (田间定植) -- 设计说明: 田间定植记录,关联组合/地块/育苗批次/定植人; -- 与 bre_tree 无硬外键(1 定植 → N 株,靠 combination_id+plot_id 关联,有意设计)。 -- 与其它表关系: -- * 上游: 引用 cross_combination(combination_id)、plot(plot_id)、 -- personnel(bre_personnel_id 定植人)、seedling(seedling_id 育苗批次) -- * 下游: 无 -- 字典来源字段: 无 -- 逻辑关系: 删除任一上游 → 级联删除本记录;定植批次可经 seedling_id 溯源到育苗批次 CREATE TABLE IF NOT EXISTS bre_planting ( combination_id integer NOT NULL REFERENCES bre_cross_combination(id) ON DELETE CASCADE, -- 所属组合 plot_id integer REFERENCES bre_plot(id) ON DELETE CASCADE, -- 试验地块 planting_date varchar(20), -- 定植日期 tree_count integer, -- 定植株数 row_no integer, -- 行号 col_no integer, -- 列号 bre_personnel_id integer REFERENCES bre_personnel(id) ON DELETE CASCADE, -- 定植人 seedling_id integer REFERENCES bre_seedling(id) ON DELETE CASCADE, -- 育苗批次 remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_planting_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_planting IS '田间定植记录表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_planting_combination ON bre_planting (combination_id); CREATE INDEX IF NOT EXISTS ix_bre_planting_plot ON bre_planting (plot_id); CREATE INDEX IF NOT EXISTS ix_bre_planting_personnel ON bre_planting (bre_personnel_id); CREATE INDEX IF NOT EXISTS ix_bre_planting_seedling ON bre_planting (seedling_id); CREATE INDEX IF NOT EXISTS ix_bre_planting_created_deleted ON bre_planting (created_time, is_deleted); -- ============================================================ -- 模块10: 育种单株(新增实体) -- ============================================================ -- 表: bre_tree (育种单株) -- 设计说明: 独立单株实体(新增),单株编号全局唯一;下游评价/照片/选育均经 -- tree_id 关联本表。修复原"tree_no 自由文本无统一实体"的断点。 -- 与其它表关系: -- * 上游: 引用 cross_combination(combination_id)、plot(plot_id) -- * 下游: 被 tree_evaluation(tree_id)/tree_photo(tree_id)/selection_result(tree_id) 引用 -- 字典来源字段: status(状态:存活/淘汰/入选) [字典],见 bre_dict.sql -- 逻辑关系: 删除单株 → 级联删除下游三表(评价/照片/选育) CREATE TABLE IF NOT EXISTS bre_tree ( combination_id integer NOT NULL REFERENCES bre_cross_combination(id) ON DELETE CASCADE, -- 所属组合 plot_id integer REFERENCES bre_plot(id) ON DELETE CASCADE, -- 试验地块 tree_no varchar(100) NOT NULL, -- 单株编号(全局唯一) row_no integer, -- 行号 col_no integer, -- 列号 planted_date varchar(20), -- 定植日期 status varchar(50), -- 状态(存活/淘汰/入选) [字典: tree_status] remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_tree_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_tree IS '育种单株表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_tree_combination ON bre_tree (combination_id); CREATE INDEX IF NOT EXISTS ix_bre_tree_plot ON bre_tree (plot_id); CREATE INDEX IF NOT EXISTS ix_bre_tree_created_deleted ON bre_tree (created_time, is_deleted); -- ============================================================ -- 模块11: 单株评价(果实性状内联,无独立 fruit_trait 表) -- ============================================================ -- 表: bre_tree_evaluation (单株评价) -- 设计说明: 单株年度评价主表;果实性状(果形/单果重/含糖量等)内联本表, -- 不单独建 breeding_fruit_trait 子表(与原规划不同)。 -- 与其它表关系: -- * 上游: 引用 cross_combination(combination_id)、tree(tree_id)、personnel(bre_personnel_id 评价人) -- * 下游: 无 -- 字典来源字段: growth_vigor(生长势:强/中/弱) [字典: growth_vigor], -- fruit_shape(果形:圆/扁圆/椭圆) [字典: fruit_shape],见 bre_dict.sql -- (fruit_weight/sugar_content 为数值字段,非字典) -- 逻辑关系: 删除组合/单株/评价人 → 级联删除本记录(外键均 CASCADE) CREATE TABLE IF NOT EXISTS bre_tree_evaluation ( combination_id integer NOT NULL REFERENCES bre_cross_combination(id) ON DELETE CASCADE, -- 所属组合 tree_id integer NOT NULL REFERENCES bre_tree(id) ON DELETE CASCADE, -- 关联单株 evaluate_year integer, -- 评价年份(多年) evaluate_date varchar(20), -- 评价日期 growth_vigor varchar(50), -- 生长势(强/中/弱) [字典: growth_vigor] fruit_shape varchar(50), -- 果形(圆/扁圆/椭圆) [字典] fruit_weight float, -- 单果重(g) sugar_content float, -- 含糖量(%) bre_personnel_id integer REFERENCES bre_personnel(id) ON DELETE CASCADE, -- 评价人 remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_tree_evaluation_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_tree_evaluation IS '单株评价表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_combination ON bre_tree_evaluation (combination_id); CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_tree ON bre_tree_evaluation (tree_id); CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_personnel ON bre_tree_evaluation (bre_personnel_id); CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_created_deleted ON bre_tree_evaluation (created_time, is_deleted); -- ============================================================ -- 模块12: 单株照片 -- ============================================================ -- 表: bre_tree_photo (单株照片) -- 设计说明: 单株照片记录,关联组合与单株。 -- 与其它表关系: -- * 上游: 引用 cross_combination(combination_id)、tree(tree_id) -- * 下游: 无 -- 字典来源字段: photo_type(照片类型:全株/果实/枝干) [字典],见 bre_dict.sql -- 逻辑关系: 删除组合/单株 → 级联删除本记录(外键均 CASCADE) CREATE TABLE IF NOT EXISTS bre_tree_photo ( combination_id integer NOT NULL REFERENCES bre_cross_combination(id) ON DELETE CASCADE, -- 所属组合 tree_id integer REFERENCES bre_tree(id) ON DELETE CASCADE, -- 关联单株 photo_type varchar(50), -- 照片类型(全株/果实/枝干) [字典: photo_type] photo_url varchar(100), -- 照片路径/URL capture_date varchar(20), -- 拍摄日期 remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_tree_photo_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_tree_photo IS '单株照片表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_tree_photo_combination ON bre_tree_photo (combination_id); CREATE INDEX IF NOT EXISTS ix_bre_tree_photo_tree ON bre_tree_photo (tree_id); CREATE INDEX IF NOT EXISTS ix_bre_tree_photo_created_deleted ON bre_tree_photo (created_time, is_deleted); -- ============================================================ -- 模块13: 选育结果(评价筛选) -- ============================================================ -- 表: bre_selection_result (选育结果) -- 设计说明: 单株选育结论(入选/淘汰/待定),关联组合与单株。 -- 与其它表关系: -- * 上游: 引用 cross_combination(combination_id)、tree(tree_id) -- * 下游: 无 -- 字典来源字段: is_selected(选育结论:入选/淘汰/待定) [字典],见 bre_dict.sql -- 逻辑关系: 删除组合/单株 → 级联删除本记录(外键均 CASCADE) CREATE TABLE IF NOT EXISTS bre_selection_result ( combination_id integer NOT NULL REFERENCES bre_cross_combination(id) ON DELETE CASCADE, -- 所属组合 tree_id integer NOT NULL REFERENCES bre_tree(id) ON DELETE CASCADE, -- 关联单株 selection_year integer, -- 入选年份 is_selected varchar(50), -- 选育结论(入选/淘汰/待定) [字典: selection_result] reason text, -- 入选理由 remark text, -- 备注 id serial PRIMARY KEY, uuid varchar(64) NOT NULL UNIQUE, is_deleted boolean NOT NULL DEFAULT false, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz NOT NULL DEFAULT now(), deleted_time timestamptz, created_id integer REFERENCES sys_user(id) ON DELETE SET NULL, updated_id integer REFERENCES sys_user(id) ON DELETE SET NULL, deleted_id integer REFERENCES sys_user(id) ON DELETE SET NULL, CONSTRAINT uq_bre_selection_result_uuid UNIQUE (uuid) ); COMMENT ON TABLE bre_selection_result IS '选育结果表(桃育种)'; CREATE INDEX IF NOT EXISTS ix_bre_selection_result_combination ON bre_selection_result (combination_id); CREATE INDEX IF NOT EXISTS ix_bre_selection_result_tree ON bre_selection_result (tree_id); CREATE INDEX IF NOT EXISTS ix_bre_selection_result_created_deleted ON bre_selection_result (created_time, is_deleted); -- ============================================================================ -- 规划新增模块(依据 桃育种系统模块扩展需求规格 v1.9 §3,2026-07-29 刷新) -- 说明:以下表尚未实装 model,待生成器落地后由 create_all / 迁移脚本建表。 -- 风格与上方 14 域一致:snake_case 表名 + 审计字段 + 外键 + (created_time, is_deleted) 索引。 -- ============================================================================ -- §3.1 性状字典(核心性状 is_core=true 固定列,扩展性状 EAV) CREATE TABLE IF NOT EXISTS bre_trait ( id serial NOT NULL, trait_code varchar(64) NOT NULL, trait_name varchar(128) NOT NULL, category varchar(32), data_type varchar(16) NOT NULL DEFAULT 'numeric', unit varchar(16), is_core varchar(1) NOT NULL DEFAULT '1', scale_json text, valid_min numeric(12,3), valid_max numeric(12,3), ontology_uri varchar(255), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_trait PRIMARY KEY (id), CONSTRAINT uq_bre_trait_code UNIQUE (trait_code) ); COMMENT ON TABLE bre_trait IS '性状字典(§3.1);核心性状固定列承载表型,is_core=false 走 observation EAV'; CREATE INDEX IF NOT EXISTS ix_bre_trait_created_deleted ON bre_trait (created_time, is_deleted); -- §3.2 扩展观测(EAV,物候时序 + 非核心性状) CREATE TABLE IF NOT EXISTS bre_observation ( id bigserial NOT NULL, tree_id int, plot_id int, trait_id int, obs_date date, obs_year int, obs_value text, obs_type varchar(32), trial_study_id int, operator_id int, remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, status int NOT NULL DEFAULT 1, CONSTRAINT pk_bre_observation PRIMARY KEY (id), CONSTRAINT fk_observation_tree FOREIGN KEY (tree_id) REFERENCES bre_tree (id), CONSTRAINT fk_observation_trait FOREIGN KEY (trait_id) REFERENCES bre_trait (id) ); COMMENT ON TABLE bre_observation IS '扩展观测 EAV(§3.2);与 tree_evaluation 经统一性状值视图归一'; CREATE INDEX IF NOT EXISTS ix_bre_observation_created_deleted ON bre_observation (created_time, is_deleted); -- §3.3 农事操作 CREATE TABLE IF NOT EXISTS bre_field_operation ( id bigserial NOT NULL, tree_id int, plot_id int, op_type varchar(32) NOT NULL, op_date date, op_detail text, operator_id int, remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, status int NOT NULL DEFAULT 1, CONSTRAINT pk_bre_field_operation PRIMARY KEY (id), CONSTRAINT fk_field_op_tree FOREIGN KEY (tree_id) REFERENCES bre_tree (id) ); COMMENT ON TABLE bre_field_operation IS '农事操作(§3.3)'; CREATE INDEX IF NOT EXISTS ix_bre_field_operation_created_deleted ON bre_field_operation (created_time, is_deleted); -- §3.4 MET 试验结构:试验 / 研究 / 参试项 CREATE TABLE IF NOT EXISTS bre_trial ( id serial NOT NULL, trial_name varchar(128) NOT NULL, trial_type varchar(32), design_type varchar(32), start_year int, end_year int, objective varchar(512), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_trial PRIMARY KEY (id) ); CREATE TABLE IF NOT EXISTS bre_trial_study ( id serial NOT NULL, trial_id int, study_name varchar(128) NOT NULL, site_id int, year int, block_count int, design_type varchar(32), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_trial_study PRIMARY KEY (id), CONSTRAINT fk_trial_study_trial FOREIGN KEY (trial_id) REFERENCES bre_trial (id), CONSTRAINT fk_trial_study_site FOREIGN KEY (site_id) REFERENCES bre_site (id) ); CREATE TABLE IF NOT EXISTS bre_trial_study_entry ( id serial NOT NULL, trial_study_id int, entry_number int, germplasm_id int, combination_id int, remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_study_entry PRIMARY KEY (id), CONSTRAINT fk_study_entry_study FOREIGN KEY (trial_study_id) REFERENCES bre_trial_study (id), CONSTRAINT fk_study_entry_germplasm FOREIGN KEY (germplasm_id) REFERENCES bre_germplasm (id) ); COMMENT ON TABLE bre_trial IS 'MET 试验(§3.4)'; COMMENT ON TABLE bre_trial_study IS 'MET 研究(多年点,block 随机效应来源)'; COMMENT ON TABLE bre_trial_study_entry IS '参试项(design matrix 聚合键 entry_number)'; -- §3.5 分组/标签(family 虚拟 + category 复用) CREATE TABLE IF NOT EXISTS bre_group ( id serial NOT NULL, group_name varchar(128) NOT NULL, group_type varchar(32), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_group PRIMARY KEY (id) ); CREATE TABLE IF NOT EXISTS bre_group_member ( id serial NOT NULL, group_id int, member_type varchar(16), member_id int, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_group_member PRIMARY KEY (id), CONSTRAINT fk_group_member_group FOREIGN KEY (group_id) REFERENCES bre_group (id) ); COMMENT ON TABLE bre_group IS '分组/标签(§3.5;family 虚拟组/category 复用)'; -- §3.6 育种报告(v1.7 进一期) CREATE TABLE IF NOT EXISTS bre_report ( id serial NOT NULL, report_name varchar(128) NOT NULL, report_type varchar(32), year int, target_id int, doc_path varchar(512), gen_by int, remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_report PRIMARY KEY (id) ); COMMENT ON TABLE bre_report IS '育种报告(§3.6,docx/pdf 导出,v1.7 进一期)'; -- §3.7 分子基因型层(V2.0) CREATE TABLE IF NOT EXISTS bre_marker ( id serial NOT NULL, marker_name varchar(64) NOT NULL, chromosome varchar(16), position int, marker_type varchar(16), panel varchar(32), assembly_version varchar(32), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_marker PRIMARY KEY (id), CONSTRAINT uq_bre_marker_name UNIQUE (marker_name) ); CREATE TABLE IF NOT EXISTS bre_genotyping_dataset ( id serial NOT NULL, dataset_name varchar(128) NOT NULL, platform varchar(32), panel varchar(32), purpose varchar(16), run_date date, lab varchar(128), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_genotyping_dataset PRIMARY KEY (id) ); CREATE TABLE IF NOT EXISTS bre_genotype_sample ( id serial NOT NULL, dataset_id int, source_type varchar(16), source_id int, sample_type varchar(16), sample_date date, method varchar(64), lab varchar(128), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_genotype_sample PRIMARY KEY (id), CONSTRAINT fk_genotype_sample_dataset FOREIGN KEY (dataset_id) REFERENCES bre_genotyping_dataset (id) ); CREATE TABLE IF NOT EXISTS bre_genotype_call ( id serial NOT NULL, sample_id int, marker_id int, allele varchar(32), remark varchar(256), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_genotype_call PRIMARY KEY (id), CONSTRAINT fk_genotype_call_sample FOREIGN KEY (sample_id) REFERENCES bre_genotype_sample (id), CONSTRAINT fk_genotype_call_marker FOREIGN KEY (marker_id) REFERENCES bre_marker (id), CONSTRAINT uq_genotype_call_sample_marker UNIQUE (sample_id, marker_id) ); COMMENT ON TABLE bre_marker IS '分子标记(§3.7;SSR/SNP,panel/assembly_version 供 GS 同版本)'; COMMENT ON TABLE bre_genotype_call IS '基因型调用(§3.7;allele 遵循 VCF/GP 0/1/2 编码)'; -- §3.8 克隆扩繁(P1,一期) CREATE TABLE IF NOT EXISTS bre_propagation ( id serial NOT NULL, batch_code varchar(64) NOT NULL, scion_source_type varchar(16), scion_source_id int, produced_germplasm_id int, rootstock_id int, method varchar(16), graft_date date, nursery_site_id int, operator_id int, scion_count int, grafted_count int, survival_count int, destination varchar(32), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_propagation PRIMARY KEY (id), CONSTRAINT uq_bre_propagation_batch UNIQUE (batch_code), CONSTRAINT fk_propagation_germplasm FOREIGN KEY (produced_germplasm_id) REFERENCES bre_germplasm (id), CONSTRAINT fk_propagation_rootstock FOREIGN KEY (rootstock_id) REFERENCES bre_germplasm (id), CONSTRAINT fk_propagation_site FOREIGN KEY (nursery_site_id) REFERENCES bre_site (id), CONSTRAINT fk_propagation_operator FOREIGN KEY (operator_id) REFERENCES bre_personnel (id) ); COMMENT ON TABLE bre_propagation IS '克隆扩繁批次(§3.8;入选株→克隆种质→扩繁→新树闭环)'; -- §3.9 环境因子(G×E 协变量) CREATE TABLE IF NOT EXISTS bre_environment_condition ( id serial NOT NULL, site_id int, year int, chilling_hours numeric(8,1), growing_degree_days numeric(8,1), rainfall_mm numeric(8,1), temp_avg numeric(6,1), soil_moisture numeric(6,1), source varchar(32), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_environment_condition PRIMARY KEY (id), CONSTRAINT fk_env_site FOREIGN KEY (site_id) REFERENCES bre_site (id), CONSTRAINT uq_env_site_year UNIQUE (site_id, year) ); COMMENT ON TABLE bre_environment_condition IS '环境因子(§3.9;G×E 协变量,site×year 唯一)'; -- §3.10 审计切面(通用,Service 写操作落) CREATE TABLE IF NOT EXISTS bre_audit_log ( id bigserial NOT NULL, entity_type varchar(32), entity_id int, action varchar(32), field_name varchar(64), old_value varchar(512), new_value varchar(512), operator_id int, created_time timestamptz NOT NULL DEFAULT now(), CONSTRAINT pk_bre_audit_log PRIMARY KEY (id), CONSTRAINT fk_audit_operator FOREIGN KEY (operator_id) REFERENCES bre_personnel (id) ); COMMENT ON TABLE bre_audit_log IS '审计日志(§3.10;晋级审批/全程可追溯切面)'; CREATE INDEX IF NOT EXISTS ix_bre_audit_entity ON bre_audit_log (entity_type, entity_id); CREATE INDEX IF NOT EXISTS ix_bre_audit_created ON bre_audit_log (created_time); -- §3.11 选择规则(阈值/指数条件) CREATE TABLE IF NOT EXISTS bre_selection_rule ( id serial NOT NULL, rule_name varchar(128) NOT NULL, target_id int, stage varchar(32), conditions_json text NOT NULL, logic varchar(8) DEFAULT 'and', action varchar(16), priority int, enabled varchar(1) DEFAULT '1', remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_selection_rule PRIMARY KEY (id), CONSTRAINT fk_selection_rule_target FOREIGN KEY (target_id) REFERENCES bre_target (id) ); COMMENT ON TABLE bre_selection_rule IS '选择规则(§3.11;conditions_json 阈值,可引用 trait_code/EBV)'; -- §3.12 育种值:模型元数据 + 值表(值表 V1.1 前移) CREATE TABLE IF NOT EXISTS bre_prediction ( id serial NOT NULL, model_name varchar(128), trait_id int, method varchar(32), accuracy numeric(5,3), train_n int, predict_date date, note varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_prediction PRIMARY KEY (id), CONSTRAINT fk_prediction_trait FOREIGN KEY (trait_id) REFERENCES bre_trait (id) ); CREATE TABLE IF NOT EXISTS bre_prediction_value ( id bigserial NOT NULL, prediction_id int, germplasm_id int, tree_id int, trait_id int, predicted_value numeric(12,4), reliability numeric(6,4), rank int, created_time timestamptz NOT NULL DEFAULT now(), CONSTRAINT pk_bre_prediction_value PRIMARY KEY (id), CONSTRAINT fk_prediction_value_prediction FOREIGN KEY (prediction_id) REFERENCES bre_prediction (id), CONSTRAINT fk_prediction_value_germplasm FOREIGN KEY (germplasm_id) REFERENCES bre_germplasm (id), CONSTRAINT fk_prediction_value_trait FOREIGN KEY (trait_id) REFERENCES bre_trait (id) ); COMMENT ON TABLE bre_prediction IS '育种值模型/批次元数据(§3.12)'; COMMENT ON TABLE bre_prediction_value IS '个体预测值(EBV 持久化,V1.1 建表;趋势图/双轨选择/亲本决策读)'; -- §3.12 补充:配合力分析结果(GCA/SCA 持久化,一期落地) CREATE TABLE IF NOT EXISTS bre_combining_ability ( id serial NOT NULL, model_name varchar(128), trait_id int, method varchar(16), gca_json jsonb, sca_json jsonb, created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_combining_ability PRIMARY KEY (id), CONSTRAINT fk_combining_trait FOREIGN KEY (trait_id) REFERENCES bre_trait (id) ); COMMENT ON TABLE bre_combining_ability IS '配合力分析结果(§3.12;GCA 按亲本、SCA 按组合,一期落地)'; -- §5 统计异步任务(R 引擎异步 job 队列) CREATE TABLE IF NOT EXISTS bre_statistics_job ( id bigserial NOT NULL, job_type varchar(32), params_json jsonb, status varchar(16) NOT NULL DEFAULT 'PENDING', result_ref int, error_msg text, started_time timestamptz, finished_time timestamptz, created_time timestamptz NOT NULL DEFAULT now(), created_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_statistics_job PRIMARY KEY (id) ); COMMENT ON TABLE bre_statistics_job IS '统计异步任务(R 引擎;ABLUP/COMBINING 提交后异步执行并回写结果)'; -- §3.13 种子批(选择强度链前段) CREATE TABLE IF NOT EXISTS bre_seed_lot ( id serial NOT NULL, combination_id int, lot_code varchar(64) NOT NULL, harvest_year int, seed_count int, used_count int DEFAULT 0, germination_rate numeric(5,2), storage_type varchar(16), storage_location varchar(128), test_date date, remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_seed_lot PRIMARY KEY (id), CONSTRAINT uq_bre_seed_lot_code UNIQUE (lot_code), CONSTRAINT fk_seed_lot_combination FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id) ); COMMENT ON TABLE bre_seed_lot IS '种子批(§3.13;used_count 派生 remaining,选择强度链源头)'; -- §3.14 试验处理(裂区/析因 factor×level) CREATE TABLE IF NOT EXISTS bre_treatment ( id serial NOT NULL, trial_study_id int, factor varchar(32) NOT NULL, level varchar(32) NOT NULL, description varchar(256), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_treatment PRIMARY KEY (id), CONSTRAINT fk_treatment_study FOREIGN KEY (trial_study_id) REFERENCES bre_trial_study (id), CONSTRAINT uq_treatment_factor_level UNIQUE (trial_study_id, factor, level) ); COMMENT ON TABLE bre_treatment IS '试验处理(§3.14;factor×level,BrAPI Treatment/MIAPPE ExperimentalFactor)'; -- §3.15 定植-处理关联(多对多) CREATE TABLE IF NOT EXISTS bre_planting_treatment ( id serial NOT NULL, planting_id int, treatment_id int, remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_planting_treatment PRIMARY KEY (id), CONSTRAINT fk_planting_treatment_planting FOREIGN KEY (planting_id) REFERENCES bre_planting (id), CONSTRAINT fk_planting_treatment_treatment FOREIGN KEY (treatment_id) REFERENCES bre_treatment (id), CONSTRAINT uq_planting_treatment UNIQUE (planting_id, treatment_id) ); COMMENT ON TABLE bre_planting_treatment IS '定植-处理关联(§3.15;因子效应挂到 block 级批次全部 tree)'; -- §3.x 系谱管理(v1.9 补充;基于杂交组合自链 + 种质系谱串派生,独立维护亲子/世代关系) CREATE TABLE IF NOT EXISTS bre_pedigree ( id serial NOT NULL, combination_id int, child_code varchar(64), generation varchar(16), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_pedigree PRIMARY KEY (id), CONSTRAINT fk_pedigree_combination FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id) ); CREATE INDEX IF NOT EXISTS ix_bre_pedigree_created_deleted ON bre_pedigree (created_time, is_deleted); -- §3.x 育种计划(v1.9 补充;顶层计划,germplasm.breeding_program 后续可升级为指向本表 FK) CREATE TABLE IF NOT EXISTS bre_plan ( id serial NOT NULL, plan_code varchar(64) NOT NULL, plan_name varchar(128) NOT NULL, objective varchar(512), start_year int, end_year int, leader varchar(64), remark varchar(512), created_time timestamptz NOT NULL DEFAULT now(), updated_time timestamptz, created_by int, updated_by int, is_deleted int NOT NULL DEFAULT 0, CONSTRAINT pk_bre_plan PRIMARY KEY (id), CONSTRAINT uq_bre_plan_code UNIQUE (plan_code) ); CREATE INDEX IF NOT EXISTS ix_bre_plan_created_deleted ON bre_plan (created_time, is_deleted); -- ===================================================================== -- 结构对齐补丁(V1.9 表 -> ModelMixin 基类契约) -- 幂等,可重复执行:补齐 uuid / deleted_time,并将 is_deleted integer 改为 boolean。 -- 背景:v1.9 规格建表时遗漏 uuid/deleted_time 且 is_deleted 用 int, -- 而 _gen_specs 生成器产出的 model 继承 ModelMixin(要求这 3 列)。 -- ===================================================================== CREATE EXTENSION IF NOT EXISTS pgcrypto; DO $$ DECLARE t text; BEGIN FOREACH t IN ARRAY ARRAY[ 'bre_trait','bre_selection_rule','bre_trial', 'bre_trial_study','bre_treatment','bre_group', 'bre_pedigree','bre_plan' ] LOOP -- uuid(唯一) IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = t AND column_name = 'uuid' ) THEN EXECUTE format('ALTER TABLE %I ADD COLUMN uuid varchar(64) NOT NULL DEFAULT gen_random_uuid()', t); EXECUTE format('CREATE UNIQUE INDEX IF NOT EXISTS uq_%I_uuid ON %I(uuid)', t, t); END IF; -- deleted_time(软删除时间,可空) IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = t AND column_name = 'deleted_time' ) THEN EXECUTE format('ALTER TABLE %I ADD COLUMN deleted_time timestamptz', t); END IF; -- is_deleted: integer -> boolean IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = t AND column_name = 'is_deleted' AND data_type = 'integer' ) THEN EXECUTE format('ALTER TABLE %I ALTER COLUMN is_deleted DROP DEFAULT', t); EXECUTE format('ALTER TABLE %I ALTER COLUMN is_deleted TYPE boolean USING (is_deleted = 1)', t); EXECUTE format('ALTER TABLE %I ALTER COLUMN is_deleted SET DEFAULT false', t); END IF; END LOOP; END $$;