Files
dpb/backend/sql/bre_tables.sql
T
34047007@qq.com b95053c52c init: 初始化 dpb 桃育种系统代码库
前后端 + 后端 FastAPI 全量源码、部署脚本与文档。
2026-08-06 00:17:49 +08:00

1561 lines
88 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================================
-- 桃育种系统 - 一期业务表建表 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[字典: <type>] 标注的字段其取值来自 sys_dict,种子见
-- bre_dict.sql,导入经 DictLabelResolver 翻译、前端经 useDictStore 取 label
-- [字典: <type> 待补] 表示模型标注为字典字段但尚无种子 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 int -- 需冷量(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),
CONSTRAINT bre_germplasm_uuid_key UNIQUE (uuid),
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);
CREATE UNIQUE INDEX IF NOT EXISTS uniq_bre_germplasm_cultivar_name ON bre_germplasm (cultivar_name) WHERE (is_deleted = false);
CREATE INDEX IF NOT EXISTS ix_bre_germplasm_cultivar_name ON bre_germplasm (cultivar_name);
CREATE INDEX IF NOT EXISTS ix_bre_germplasm_is_deleted ON bre_germplasm (is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_germplasm_variety_type ON bre_germplasm (variety_type);
-- ============================================================
-- 模块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 -- 备注,
CONSTRAINT bre_site_site_name_key UNIQUE (site_name),
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);
CREATE INDEX IF NOT EXISTS ix_bre_site_created_id ON bre_site (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_site_created_time ON bre_site (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_site_deleted_id ON bre_site (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_site_id ON bre_site (id);
CREATE INDEX IF NOT EXISTS ix_bre_site_is_deleted ON bre_site (is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_site_updated_id ON bre_site (updated_id);
-- 表: 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 int NOT NULL -- 所属基地,
plot_code varchar(50) NOT NULL -- 区块编号/名称,
row_orientation varchar(20) -- 行向(南北行/东西行) [字典: row_orientation],
row_count int -- 行数,
col_count int -- 每行株数,
grid_note text -- 株行距/网格说明,
area float -- 地块面积(亩),
CONSTRAINT fk_bre_plot_site_id FOREIGN KEY (site_id) REFERENCES bre_site (id),
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_created_deleted ON bre_plot (created_time, is_deleted);
CREATE UNIQUE INDEX IF NOT EXISTS uniq_bre_plot_site_code ON bre_plot (site_id, plot_code) WHERE (is_deleted = false);
CREATE INDEX IF NOT EXISTS ix_bre_plot_created_id ON bre_plot (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_plot_created_time ON bre_plot (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_plot_deleted_id ON bre_plot (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_plot_id ON bre_plot (id);
CREATE INDEX IF NOT EXISTS ix_bre_plot_is_deleted ON bre_plot (is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_plot_site ON bre_plot (site_id);
CREATE INDEX IF NOT EXISTS ix_bre_plot_site_id ON bre_plot (site_id);
CREATE INDEX IF NOT EXISTS ix_bre_plot_updated_id ON bre_plot (updated_id);
-- ============================================================
-- 模块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);
CREATE UNIQUE INDEX IF NOT EXISTS uniq_bre_personnel_name ON bre_personnel (name) WHERE (is_deleted = false);
CREATE INDEX IF NOT EXISTS ix_bre_personnel_created_id ON bre_personnel (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_personnel_created_time ON bre_personnel (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_personnel_deleted_id ON bre_personnel (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_personnel_id ON bre_personnel (id);
CREATE INDEX IF NOT EXISTS ix_bre_personnel_is_deleted ON bre_personnel (is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_personnel_updated_id ON bre_personnel (updated_id);
-- ============================================================
-- 模块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);
CREATE INDEX IF NOT EXISTS ix_bre_target_created_id ON bre_target (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_target_created_time ON bre_target (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_target_deleted_id ON bre_target (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_target_id ON bre_target (id);
CREATE INDEX IF NOT EXISTS ix_bre_target_is_deleted ON bre_target (is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_target_updated_id ON bre_target (updated_id);
-- ============================================================
-- 模块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 int -- 杂交年份,
bre_target_id int NOT NULL -- 育种目标(单选,主数据),
female_parent_id int -- 母本,
male_parent_id int -- 父本,
cross_method varchar(50) -- 杂交方式(人工杂交/自然授粉/回交) [字典: cross_method],
cross_date varchar(20) -- 杂交日期,
seed_count int -- 获种数,
remark text -- 备注,
CONSTRAINT fk_bre_cross_combination_bre_target_id FOREIGN KEY (bre_target_id) REFERENCES bre_target (id),
CONSTRAINT fk_bre_cross_combination_female_parent_id FOREIGN KEY (female_parent_id) REFERENCES bre_germplasm (id),
CONSTRAINT fk_bre_cross_combination_male_parent_id FOREIGN KEY (male_parent_id) REFERENCES bre_germplasm (id),
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_created_deleted ON bre_cross_combination (created_time, is_deleted);
CREATE UNIQUE INDEX IF NOT EXISTS uniq_bre_cross_combination_code ON bre_cross_combination (combination_code) WHERE (is_deleted = false);
CREATE INDEX IF NOT EXISTS ix_bre_cross_combination_bre_target_id ON bre_cross_combination (bre_target_id);
CREATE INDEX IF NOT EXISTS ix_bre_cross_combination_created_id ON bre_cross_combination (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_cross_combination_created_time ON bre_cross_combination (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_cross_combination_deleted_id ON bre_cross_combination (deleted_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_female_parent_id ON bre_cross_combination (female_parent_id);
CREATE INDEX IF NOT EXISTS ix_bre_cross_combination_id ON bre_cross_combination (id);
CREATE INDEX IF NOT EXISTS ix_bre_cross_combination_is_deleted ON bre_cross_combination (is_deleted);
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_male_parent_id ON bre_cross_combination (male_parent_id);
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_updated_id ON bre_cross_combination (updated_id);
-- ============================================================
-- 模块6: 杂交授粉
-- ============================================================
-- 表: bre_pollination (授粉记录)
-- 设计说明: 杂交授粉过程记录,挂靠杂交组合与试验地块。
-- 与其它表关系:
-- * 上游: 引用 cross_combination(combination_id)、plot(plot_id)、personnel(bre_personnel_id 授粉人)
-- * 下游: 无
-- 字典来源字段: 无(本表未设字典字段)
-- 逻辑关系: 删除组合/地块/授粉人 → 级联删除本记录(外键均 CASCADE)
CREATE TABLE IF NOT EXISTS bre_pollination (
combination_id int NOT NULL -- 所属组合,
plot_id int -- 试验地块,
pollination_date varchar(20) -- 授粉日期,
flower_count int -- 花朵数,
effective_count int -- 有效坐果数,
pollinator varchar(100),
remark text -- 备注,
bre_personnel_id int -- 授粉人,
CONSTRAINT fk_bre_pollination_bre_personnel_id FOREIGN KEY (bre_personnel_id) REFERENCES bre_personnel (id),
CONSTRAINT fk_bre_pollination_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
CONSTRAINT fk_bre_pollination_plot_id FOREIGN KEY (plot_id) REFERENCES bre_plot (id),
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_created_deleted ON bre_pollination (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_bre_personnel_id ON bre_pollination (bre_personnel_id);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_combination ON bre_pollination (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_combination_id ON bre_pollination (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_created_id ON bre_pollination (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_created_time ON bre_pollination (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_deleted_id ON bre_pollination (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_id ON bre_pollination (id);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_is_deleted ON bre_pollination (is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_personnel ON bre_pollination (bre_personnel_id);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_plot ON bre_pollination (plot_id);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_plot_id ON bre_pollination (plot_id);
CREATE INDEX IF NOT EXISTS ix_bre_pollination_updated_id ON bre_pollination (updated_id);
-- ============================================================
-- 模块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 int NOT NULL -- 所属组合,
treatment_method varchar(50) -- 处理方式(沙藏/层积/低温冷藏/常温) [字典: seed_treatment_method],
treatment_start varchar(20) -- 处理开始日期,
treatment_end varchar(20) -- 处理结束日期,
germination_rate float -- 发芽率(%),
remark text -- 备注,
bre_personnel_id int -- 种子处理人,
CONSTRAINT fk_bre_seed_treatment_bre_personnel_id FOREIGN KEY (bre_personnel_id) REFERENCES bre_personnel (id),
CONSTRAINT fk_bre_seed_treatment_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
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_created_deleted ON bre_seed_treatment (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_seed_treatment_bre_personnel_id ON bre_seed_treatment (bre_personnel_id);
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_combination_id ON bre_seed_treatment (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_seed_treatment_created_id ON bre_seed_treatment (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_seed_treatment_created_time ON bre_seed_treatment (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_seed_treatment_deleted_id ON bre_seed_treatment (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_seed_treatment_id ON bre_seed_treatment (id);
CREATE INDEX IF NOT EXISTS ix_bre_seed_treatment_is_deleted ON bre_seed_treatment (is_deleted);
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_updated_id ON bre_seed_treatment (updated_id);
-- ============================================================
-- 模块8: 杂种苗培育
-- ============================================================
-- 表: bre_seedling (杂种苗)
-- 设计说明: 播种育苗记录,溯源到杂交组合;可被定植批次引用。
-- 与其它表关系:
-- * 上游: 引用 cross_combination(combination_id)、personnel(bre_personnel_id 育苗人)
-- * 下游: 被 planting(seedling_id) 引用
-- 字典来源字段: 无
-- 逻辑关系: 删除组合/育苗人 → 级联删除本记录;删除育苗 → 级联删除引用它的定植记录
CREATE TABLE IF NOT EXISTS bre_seedling (
combination_id int NOT NULL -- 所属组合,
sowing_date varchar(20) -- 播移日期,
tray_no varchar(100) -- 穴盘号,
nursery varchar(100) -- 苗圃,
seedling_count int -- 出苗数,
remark text -- 备注,
bre_personnel_id int -- 育苗人,
treatment_id int,
batch_no varchar(50),
emergence_date varchar(20),
strong_seedling_date varchar(20),
strong_seedling_count int,
stage varchar(1) DEFAULT '1'::character varying,
CONSTRAINT fk_bre_seedling_bre_personnel_id FOREIGN KEY (bre_personnel_id) REFERENCES bre_personnel (id),
CONSTRAINT fk_bre_seedling_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
CONSTRAINT fk_bre_seedling_treatment_id FOREIGN KEY (treatment_id) REFERENCES bre_seed_treatment (id),
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_created_deleted ON bre_seedling (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_batch_no ON bre_seedling (batch_no);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_bre_personnel_id ON bre_seedling (bre_personnel_id);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_combination ON bre_seedling (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_combination_id ON bre_seedling (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_created_id ON bre_seedling (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_created_time ON bre_seedling (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_deleted_id ON bre_seedling (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_id ON bre_seedling (id);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_is_deleted ON bre_seedling (is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_personnel ON bre_seedling (bre_personnel_id);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_treatment_id ON bre_seedling (treatment_id);
CREATE INDEX IF NOT EXISTS ix_bre_seedling_updated_id ON bre_seedling (updated_id);
-- ============================================================
-- 模块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 int NOT NULL -- 所属组合,
plot_id int -- 试验地块,
planting_date varchar(20) -- 定植日期,
tree_count int -- 定植株数,
row_no int -- 行号,
col_no int -- 列号,
remark text -- 备注,
seedling_id int -- 育苗批次,
bre_personnel_id int -- 定植人,
CONSTRAINT fk_bre_planting_bre_personnel_id FOREIGN KEY (bre_personnel_id) REFERENCES bre_personnel (id),
CONSTRAINT fk_bre_planting_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
CONSTRAINT fk_bre_planting_plot_id FOREIGN KEY (plot_id) REFERENCES bre_plot (id),
CONSTRAINT fk_bre_planting_seedling_id FOREIGN KEY (seedling_id) REFERENCES bre_seedling (id),
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_created_deleted ON bre_planting (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_planting_bre_personnel_id ON bre_planting (bre_personnel_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_combination ON bre_planting (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_combination_id ON bre_planting (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_created_id ON bre_planting (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_created_time ON bre_planting (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_planting_deleted_id ON bre_planting (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_id ON bre_planting (id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_is_deleted ON bre_planting (is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_planting_personnel ON bre_planting (bre_personnel_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_plot ON bre_planting (plot_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_plot_id ON bre_planting (plot_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_seedling ON bre_planting (seedling_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_seedling_id ON bre_planting (seedling_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_updated_id ON bre_planting (updated_id);
-- ============================================================
-- 模块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 int NOT NULL -- 所属组合,
dam_id int -- 母本(种质),
sire_id int -- 父本(种质),
plot_id int -- 试验地块,
tree_no varchar(100) NOT NULL -- 单株编号(全局唯一),
row_no int -- 行号,
col_no int -- 列号,
planted_date varchar(20) -- 定植日期,
status varchar(50) -- 状态(存活/淘汰/入选) [字典: tree_status],
remark text -- 备注,
row_orientation varchar(50),
bre_personnel_id int,
planting_id int,
CONSTRAINT fk_bre_tree_bre_personnel_id FOREIGN KEY (bre_personnel_id) REFERENCES bre_personnel (id),
CONSTRAINT fk_bre_tree_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
CONSTRAINT fk_bre_tree_dam_id FOREIGN KEY (dam_id) REFERENCES bre_germplasm (id),
CONSTRAINT fk_bre_tree_sire_id FOREIGN KEY (sire_id) REFERENCES bre_germplasm (id),
CONSTRAINT fk_bre_tree_planting_id FOREIGN KEY (planting_id) REFERENCES bre_planting (id),
CONSTRAINT fk_bre_tree_plot_id FOREIGN KEY (plot_id) REFERENCES bre_plot (id),
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_created_deleted ON bre_tree (created_time, is_deleted);
CREATE UNIQUE INDEX IF NOT EXISTS uniq_bre_tree_no ON bre_tree (tree_no) WHERE (is_deleted = false);
CREATE INDEX IF NOT EXISTS ix_bre_tree_combination ON bre_tree (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_combination_id ON bre_tree (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_created_id ON bre_tree (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_created_time ON bre_tree (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_tree_deleted_id ON bre_tree (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_id ON bre_tree (id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_is_deleted ON bre_tree (is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_tree_personnel ON bre_tree (bre_personnel_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_planting_id ON bre_tree (planting_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_plot ON bre_tree (plot_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_plot_id ON bre_tree (plot_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_updated_id ON bre_tree (updated_id);
-- ============================================================
-- 模块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 int NOT NULL -- 所属组合,
evaluate_year int -- 评价年份(多年),
evaluate_date varchar(20) -- 评价日期,
remark text -- 备注,
tree_id int NOT NULL -- 关联单株,
bre_personnel_id int -- 评价人,
overall_score float,
CONSTRAINT fk_bre_tree_evaluation_bre_personnel_id FOREIGN KEY (bre_personnel_id) REFERENCES bre_personnel (id),
CONSTRAINT fk_bre_tree_evaluation_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
CONSTRAINT fk_bre_tree_evaluation_tree_id FOREIGN KEY (tree_id) REFERENCES bre_tree (id),
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_created_deleted ON bre_tree_evaluation (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_bre_personnel_id ON bre_tree_evaluation (bre_personnel_id);
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_combination_id ON bre_tree_evaluation (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_created_id ON bre_tree_evaluation (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_created_time ON bre_tree_evaluation (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_deleted_id ON bre_tree_evaluation (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_id ON bre_tree_evaluation (id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_is_deleted ON bre_tree_evaluation (is_deleted);
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_tree ON bre_tree_evaluation (tree_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_tree_id ON bre_tree_evaluation (tree_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_evaluation_updated_id ON bre_tree_evaluation (updated_id);
-- ============================================================
-- 模块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 int NOT NULL -- 所属组合,
photo_type varchar(50) -- 照片类型(全株/果实/枝干) [字典: photo_type],
photo_url varchar(100) -- 照片路径/URL,
capture_date varchar(20) -- 拍摄日期,
remark text -- 备注,
tree_id int -- 关联单株,
evaluation_id int,
category varchar(50),
CONSTRAINT fk_bre_tree_photo_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
CONSTRAINT fk_bre_tree_photo_evaluation_id FOREIGN KEY (evaluation_id) REFERENCES bre_tree_evaluation (id),
CONSTRAINT fk_bre_tree_photo_tree_id FOREIGN KEY (tree_id) REFERENCES bre_tree (id),
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_created_deleted ON bre_tree_photo (created_time, is_deleted);
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_combination_id ON bre_tree_photo (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_photo_created_id ON bre_tree_photo (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_photo_created_time ON bre_tree_photo (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_tree_photo_deleted_id ON bre_tree_photo (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_photo_evaluation ON bre_tree_photo (evaluation_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_photo_id ON bre_tree_photo (id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_photo_is_deleted ON bre_tree_photo (is_deleted);
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_tree_id ON bre_tree_photo (tree_id);
CREATE INDEX IF NOT EXISTS ix_bre_tree_photo_updated_id ON bre_tree_photo (updated_id);
-- ============================================================
-- 模块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 int NOT NULL -- 所属组合,
tree_no varchar(100) NOT NULL,
selection_year int -- 入选年份,
is_selected varchar(50) -- 选育结论(入选/淘汰/待定) [字典: selection_result],
reason text -- 入选理由,
remark text -- 备注,
tree_id int NOT NULL -- 关联单株,
CONSTRAINT fk_bre_selection_result_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
CONSTRAINT fk_bre_selection_result_tree_id FOREIGN KEY (tree_id) REFERENCES bre_tree (id),
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_created_deleted ON bre_selection_result (created_time, is_deleted);
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_combination_id ON bre_selection_result (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_selection_result_created_id ON bre_selection_result (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_selection_result_created_time ON bre_selection_result (created_time);
CREATE INDEX IF NOT EXISTS ix_bre_selection_result_deleted_id ON bre_selection_result (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_selection_result_id ON bre_selection_result (id);
CREATE INDEX IF NOT EXISTS ix_bre_selection_result_is_deleted ON bre_selection_result (is_deleted);
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_tree_id ON bre_selection_result (tree_id);
CREATE INDEX IF NOT EXISTS ix_bre_selection_result_updated_id ON bre_selection_result (updated_id);
-- ============================================================================
-- 规划新增模块(依据 桃育种系统模块扩展需求规格 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 (
trait_code varchar(64) NOT NULL,
trait_name varchar(128) NOT NULL,
category varchar(32),
data_type varchar(16) NOT NULL DEFAULT 'numeric'::character varying,
unit varchar(16),
is_core varchar(1) NOT NULL DEFAULT '1'::character varying,
scale_json text,
valid_min numeric(12,3),
valid_max numeric(12,3),
ontology_uri varchar(255),
remark varchar(512),
CONSTRAINT uq_bre_trait_code UNIQUE (trait_code),
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_trait_uuid UNIQUE (uuid)
);
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);
CREATE INDEX IF NOT EXISTS ix_bre_trait_created_id ON bre_trait (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_trait_deleted_id ON bre_trait (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_trait_updated_id ON bre_trait (updated_id);
-- §3.2 扩展观测(EAV,物候时序 + 非核心性状)
CREATE TABLE IF NOT EXISTS bre_observation (
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),
status int NOT NULL DEFAULT 1,
CONSTRAINT fk_bre_observation_trait_id FOREIGN KEY (trait_id) REFERENCES bre_trait (id),
CONSTRAINT fk_bre_observation_tree_id FOREIGN KEY (tree_id) REFERENCES bre_tree (id),
id bigserial 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_observation_uuid UNIQUE (uuid)
);
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);
CREATE INDEX IF NOT EXISTS ix_bre_observation_created_id ON bre_observation (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_observation_deleted_id ON bre_observation (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_observation_updated_id ON bre_observation (updated_id);
-- §3.3 农事操作
CREATE TABLE IF NOT EXISTS bre_field_operation (
tree_id int,
plot_id int,
op_type varchar(32) NOT NULL,
op_date date,
op_detail text,
operator_id int,
remark varchar(512),
status int NOT NULL DEFAULT 1,
CONSTRAINT fk_bre_field_operation_tree_id FOREIGN KEY (tree_id) REFERENCES bre_tree (id),
id bigserial 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_field_operation_uuid UNIQUE (uuid)
);
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);
CREATE INDEX IF NOT EXISTS ix_bre_field_operation_created_id ON bre_field_operation (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_field_operation_deleted_id ON bre_field_operation (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_field_operation_updated_id ON bre_field_operation (updated_id);
-- §3.4 MET 试验结构:试验 / 研究 / 参试项
CREATE TABLE IF NOT EXISTS bre_trial (
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),
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_trial_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_trial IS 'MET 试验(§3.4';
CREATE INDEX IF NOT EXISTS ix_bre_trial_created_id ON bre_trial (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_trial_deleted_id ON bre_trial (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_trial_updated_id ON bre_trial (updated_id);
CREATE TABLE IF NOT EXISTS bre_trial_study (
trial_id int NOT NULL,
study_name varchar(128) NOT NULL,
site_id int,
year int,
block_count int,
design_type varchar(32),
remark varchar(512),
CONSTRAINT fk_bre_trial_study_site_id FOREIGN KEY (site_id) REFERENCES bre_site (id),
CONSTRAINT fk_bre_trial_study_trial_id FOREIGN KEY (trial_id) REFERENCES bre_trial (id),
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_trial_study_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_trial_study IS 'MET 研究(多年点,block 随机效应来源)';
CREATE INDEX IF NOT EXISTS ix_bre_trial_study_created_id ON bre_trial_study (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_trial_study_deleted_id ON bre_trial_study (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_trial_study_updated_id ON bre_trial_study (updated_id);
CREATE TABLE IF NOT EXISTS bre_trial_study_entry (
trial_study_id int NOT NULL,
entry_number int NOT NULL,
germplasm_id int NOT NULL,
combination_id int,
remark varchar(512),
CONSTRAINT fk_bre_trial_study_entry_germplasm_id FOREIGN KEY (germplasm_id) REFERENCES bre_germplasm (id),
CONSTRAINT fk_bre_trial_study_entry_trial_study_id FOREIGN KEY (trial_study_id) REFERENCES bre_trial_study (id),
CONSTRAINT bre_trial_study_entry_uuid_key UNIQUE (uuid),
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_trial_study_entry_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_trial_study_entry IS '参试项(design matrix 聚合键 entry_number';
CREATE INDEX IF NOT EXISTS ix_bre_trial_study_entry_created_deleted ON bre_trial_study_entry (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_trial_study_entry_created_id ON bre_trial_study_entry (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_trial_study_entry_deleted_id ON bre_trial_study_entry (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_trial_study_entry_updated_id ON bre_trial_study_entry (updated_id);
-- §3.5 分组/标签(family 虚拟 + category 复用)
CREATE TABLE IF NOT EXISTS bre_group (
group_name varchar(128) NOT NULL,
group_type varchar(32),
remark varchar(512),
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_group_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_group IS '分组/标签(§3.5family 虚拟组/category 复用)';
CREATE INDEX IF NOT EXISTS ix_bre_group_created_id ON bre_group (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_group_deleted_id ON bre_group (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_group_updated_id ON bre_group (updated_id);
CREATE TABLE IF NOT EXISTS bre_group_member (
group_id int,
member_type varchar(16),
member_id int,
CONSTRAINT fk_bre_group_member_group_id FOREIGN KEY (group_id) REFERENCES bre_group (id),
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_group_member_uuid UNIQUE (uuid)
);
CREATE INDEX IF NOT EXISTS ix_bre_group_member_created_id ON bre_group_member (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_group_member_deleted_id ON bre_group_member (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_group_member_updated_id ON bre_group_member (updated_id);
-- §3.6 育种报告(v1.7 进一期)
CREATE TABLE IF NOT EXISTS bre_report (
report_name varchar(128) NOT NULL,
report_type varchar(32),
year int,
target_id int,
doc_path varchar(512),
gen_by varchar(64),
remark varchar(512),
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_report_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_report IS '育种报告(§3.6docx/pdf 导出,v1.7 进一期)';
CREATE INDEX IF NOT EXISTS ix_bre_report_created_id ON bre_report (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_report_deleted_id ON bre_report (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_report_updated_id ON bre_report (updated_id);
-- §3.7 分子基因型层(V2.0
CREATE TABLE IF NOT EXISTS bre_marker (
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),
CONSTRAINT uq_bre_marker_name UNIQUE (marker_name),
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_marker_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_marker IS '分子标记(§3.7SSR/SNPpanel/assembly_version 供 GS 同版本)';
CREATE INDEX IF NOT EXISTS ix_bre_marker_created_id ON bre_marker (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_marker_deleted_id ON bre_marker (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_marker_updated_id ON bre_marker (updated_id);
CREATE TABLE IF NOT EXISTS bre_genotyping_dataset (
dataset_name varchar(128) NOT NULL,
platform varchar(32),
panel varchar(32),
purpose varchar(16),
run_date date,
lab varchar(128),
remark varchar(512),
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_genotyping_dataset_uuid UNIQUE (uuid)
);
CREATE INDEX IF NOT EXISTS ix_bre_genotyping_dataset_created_id ON bre_genotyping_dataset (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_genotyping_dataset_deleted_id ON bre_genotyping_dataset (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_genotyping_dataset_updated_id ON bre_genotyping_dataset (updated_id);
CREATE TABLE IF NOT EXISTS bre_genotype_sample (
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),
CONSTRAINT fk_bre_genotype_sample_dataset_id FOREIGN KEY (dataset_id) REFERENCES bre_genotyping_dataset (id),
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_genotype_sample_uuid UNIQUE (uuid)
);
CREATE INDEX IF NOT EXISTS ix_bre_genotype_sample_created_id ON bre_genotype_sample (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_genotype_sample_deleted_id ON bre_genotype_sample (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_genotype_sample_updated_id ON bre_genotype_sample (updated_id);
CREATE TABLE IF NOT EXISTS bre_genotype_call (
sample_id int,
marker_id int,
allele varchar(32),
remark varchar(256),
CONSTRAINT fk_bre_genotype_call_marker_id FOREIGN KEY (marker_id) REFERENCES bre_marker (id),
CONSTRAINT fk_bre_genotype_call_sample_id FOREIGN KEY (sample_id) REFERENCES bre_genotype_sample (id),
CONSTRAINT uq_genotype_call_sample_marker UNIQUE (sample_id, marker_id),
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_genotype_call_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_genotype_call IS '基因型调用(§3.7allele 遵循 VCF/GP 0/1/2 编码)';
CREATE INDEX IF NOT EXISTS ix_bre_genotype_call_created_id ON bre_genotype_call (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_genotype_call_deleted_id ON bre_genotype_call (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_genotype_call_updated_id ON bre_genotype_call (updated_id);
-- §3.8 克隆扩繁(P1,一期)
CREATE TABLE IF NOT EXISTS bre_propagation (
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),
CONSTRAINT fk_bre_propagation_nursery_site_id FOREIGN KEY (nursery_site_id) REFERENCES bre_site (id),
CONSTRAINT fk_bre_propagation_operator_id FOREIGN KEY (operator_id) REFERENCES bre_personnel (id),
CONSTRAINT fk_bre_propagation_produced_germplasm_id FOREIGN KEY (produced_germplasm_id) REFERENCES bre_germplasm (id),
CONSTRAINT fk_bre_propagation_rootstock_id FOREIGN KEY (rootstock_id) REFERENCES bre_germplasm (id),
CONSTRAINT uq_bre_propagation_batch UNIQUE (batch_code),
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_propagation_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_propagation IS '克隆扩繁批次(§3.8;入选株→克隆种质→扩繁→新树闭环)';
CREATE INDEX IF NOT EXISTS ix_bre_propagation_created_id ON bre_propagation (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_propagation_deleted_id ON bre_propagation (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_propagation_updated_id ON bre_propagation (updated_id);
-- §3.9 环境因子(G×E 协变量)
CREATE TABLE IF NOT EXISTS bre_environment_condition (
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),
CONSTRAINT fk_bre_environment_condition_site_id FOREIGN KEY (site_id) REFERENCES bre_site (id),
CONSTRAINT uq_env_site_year UNIQUE (site_id, year),
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_environment_condition_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_environment_condition IS '环境因子(§3.9G×E 协变量,site×year 唯一)';
CREATE INDEX IF NOT EXISTS ix_bre_environment_condition_created_id ON bre_environment_condition (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_environment_condition_deleted_id ON bre_environment_condition (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_environment_condition_updated_id ON bre_environment_condition (updated_id);
-- §3.10 审计切面(通用,Service 写操作落)
CREATE TABLE IF NOT EXISTS bre_audit_log (
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,
CONSTRAINT fk_bre_audit_log_operator_id FOREIGN KEY (operator_id) REFERENCES bre_personnel (id),
id bigserial 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_audit_log_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_audit_log IS '审计日志(§3.10;晋级审批/全程可追溯切面)';
CREATE INDEX IF NOT EXISTS ix_bre_audit_created ON bre_audit_log (created_time);
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_log_created_id ON bre_audit_log (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_audit_log_deleted_id ON bre_audit_log (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_audit_log_updated_id ON bre_audit_log (updated_id);
-- §3.11 选择规则(阈值/指数条件)
CREATE TABLE IF NOT EXISTS bre_selection_rule (
rule_name varchar(128) NOT NULL,
target_id int NOT NULL,
stage varchar(32),
conditions_json text NOT NULL,
logic varchar(8) DEFAULT 'and'::character varying,
action varchar(16),
priority int,
enabled varchar(1) DEFAULT '1'::character varying,
remark varchar(512),
CONSTRAINT fk_bre_selection_rule_target_id FOREIGN KEY (target_id) REFERENCES bre_target (id),
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_rule_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_selection_rule IS '选择规则(§3.11conditions_json 阈值,可引用 trait_code/EBV';
CREATE INDEX IF NOT EXISTS ix_bre_selection_rule_created_id ON bre_selection_rule (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_selection_rule_deleted_id ON bre_selection_rule (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_selection_rule_updated_id ON bre_selection_rule (updated_id);
-- §3.12 育种值:模型元数据 + 值表(值表 V1.1 前移)
CREATE TABLE IF NOT EXISTS bre_prediction (
model_name varchar(128),
trait_id int,
method varchar(32),
accuracy numeric(5,3),
train_n int,
heritability numeric(5,4),
predict_date date,
note varchar(512),
CONSTRAINT fk_bre_prediction_trait_id FOREIGN KEY (trait_id) REFERENCES bre_trait (id),
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_prediction_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_prediction IS '育种值模型/批次元数据(§3.12)';
CREATE INDEX IF NOT EXISTS ix_bre_prediction_created_deleted ON bre_prediction (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_prediction_created_id ON bre_prediction (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_prediction_deleted_id ON bre_prediction (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_prediction_updated_id ON bre_prediction (updated_id);
CREATE TABLE IF NOT EXISTS bre_prediction_value (
prediction_id int NOT NULL,
germplasm_id int,
tree_id int,
trait_id int,
predicted_value numeric(12,4),
reliability numeric(6,4),
rank int,
CONSTRAINT fk_bre_prediction_value_germplasm_id FOREIGN KEY (germplasm_id) REFERENCES bre_germplasm (id),
CONSTRAINT fk_bre_prediction_value_prediction_id FOREIGN KEY (prediction_id) REFERENCES bre_prediction (id),
CONSTRAINT fk_bre_prediction_value_trait_id FOREIGN KEY (trait_id) REFERENCES bre_trait (id),
id bigserial 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_prediction_value_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_prediction_value IS '个体预测值(EBV 持久化,V1.1 建表;趋势图/双轨选择/亲本决策读)';
CREATE INDEX IF NOT EXISTS ix_bre_prediction_value_created_deleted ON bre_prediction_value (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_prediction_value_created_id ON bre_prediction_value (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_prediction_value_deleted_id ON bre_prediction_value (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_prediction_value_updated_id ON bre_prediction_value (updated_id);
-- §3.12 补充:配合力分析结果(GCA/SCA 持久化,一期落地)
CREATE TABLE IF NOT EXISTS bre_combining_ability (
model_name varchar(128),
trait_id int,
method varchar(16),
gca_json jsonb,
sca_json jsonb,
CONSTRAINT fk_bre_combining_ability_trait_id FOREIGN KEY (trait_id) REFERENCES bre_trait (id),
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_combining_ability_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_combining_ability IS '配合力分析结果(§3.12;GCA 按亲本、SCA 按组合,一期落地)';
CREATE INDEX IF NOT EXISTS ix_bre_combining_ability_created_deleted ON bre_combining_ability (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_combining_ability_created_id ON bre_combining_ability (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_combining_ability_deleted_id ON bre_combining_ability (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_combining_ability_updated_id ON bre_combining_ability (updated_id);
-- §5 统计异步任务(R 引擎异步 job 队列)
CREATE TABLE IF NOT EXISTS bre_statistics_job (
job_type varchar(32),
params_json jsonb,
status varchar(16) NOT NULL DEFAULT 'PENDING'::character varying,
result_ref int,
error_msg text,
started_time timestamptz,
finished_time timestamptz,
id bigserial 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_statistics_job_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_statistics_job IS '统计异步任务(R 引擎;ABLUP/COMBINING 提交后异步执行并回写结果)';
CREATE INDEX IF NOT EXISTS ix_bre_statistics_job_created_deleted ON bre_statistics_job (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_statistics_job_created_id ON bre_statistics_job (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_statistics_job_deleted_id ON bre_statistics_job (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_statistics_job_updated_id ON bre_statistics_job (updated_id);
-- §3.13 种子批(选择强度链前段)
CREATE TABLE IF NOT EXISTS bre_seed_lot (
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),
CONSTRAINT fk_bre_seed_lot_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
CONSTRAINT uq_bre_seed_lot_code UNIQUE (lot_code),
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_lot_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_seed_lot IS '种子批(§3.13used_count 派生 remaining,选择强度链源头)';
CREATE INDEX IF NOT EXISTS ix_bre_seed_lot_created_id ON bre_seed_lot (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_seed_lot_deleted_id ON bre_seed_lot (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_seed_lot_updated_id ON bre_seed_lot (updated_id);
-- §3.14 试验处理(裂区/析因 factor×level
CREATE TABLE IF NOT EXISTS bre_treatment (
trial_study_id int NOT NULL,
factor varchar(32) NOT NULL,
level varchar(32) NOT NULL,
description varchar(256),
remark varchar(512),
CONSTRAINT fk_bre_treatment_trial_study_id FOREIGN KEY (trial_study_id) REFERENCES bre_trial_study (id),
CONSTRAINT uq_treatment_factor_level UNIQUE (trial_study_id, factor, level),
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_treatment_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_treatment IS '试验处理(§3.14factor×levelBrAPI Treatment/MIAPPE ExperimentalFactor';
CREATE INDEX IF NOT EXISTS ix_bre_treatment_created_id ON bre_treatment (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_treatment_deleted_id ON bre_treatment (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_treatment_updated_id ON bre_treatment (updated_id);
-- §3.15 定植-处理关联(多对多)
CREATE TABLE IF NOT EXISTS bre_planting_treatment (
planting_id int,
treatment_id int,
remark varchar(512),
CONSTRAINT fk_bre_planting_treatment_planting_id FOREIGN KEY (planting_id) REFERENCES bre_planting (id),
CONSTRAINT fk_bre_planting_treatment_treatment_id FOREIGN KEY (treatment_id) REFERENCES bre_treatment (id),
CONSTRAINT uq_planting_treatment UNIQUE (planting_id, treatment_id),
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_treatment_uuid UNIQUE (uuid)
);
COMMENT ON TABLE bre_planting_treatment IS '定植-处理关联(§3.15;因子效应挂到 block 级批次全部 tree';
CREATE INDEX IF NOT EXISTS ix_bre_planting_treatment_created_id ON bre_planting_treatment (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_treatment_deleted_id ON bre_planting_treatment (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_planting_treatment_updated_id ON bre_planting_treatment (updated_id);
-- §3.x 系谱管理(v1.9 补充;基于杂交组合自链 + 种质系谱串派生,独立维护亲子/世代关系)
CREATE TABLE IF NOT EXISTS bre_pedigree (
combination_id int NOT NULL,
child_code varchar(64) NOT NULL,
generation varchar(16),
remark varchar(512),
CONSTRAINT fk_bre_pedigree_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
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_pedigree_uuid UNIQUE (uuid)
);
CREATE INDEX IF NOT EXISTS ix_bre_pedigree_created_deleted ON bre_pedigree (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_pedigree_created_id ON bre_pedigree (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_pedigree_deleted_id ON bre_pedigree (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_pedigree_updated_id ON bre_pedigree (updated_id);
-- §3.x 育种计划(v1.9 补充;顶层计划,germplasm.breeding_program 后续可升级为指向本表 FK)
CREATE TABLE IF NOT EXISTS bre_plan (
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),
CONSTRAINT uq_bre_plan_code UNIQUE (plan_code),
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_plan_uuid UNIQUE (uuid)
);
CREATE INDEX IF NOT EXISTS ix_bre_plan_created_deleted ON bre_plan (created_time, is_deleted);
CREATE INDEX IF NOT EXISTS ix_bre_plan_created_id ON bre_plan (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_plan_deleted_id ON bre_plan (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_plan_updated_id ON bre_plan (updated_id);
-- =====================================================================
-- 结构对齐补丁(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 $$;
-- ============================================================
-- 模块: 单株鉴定(性状观测明细长表 EAVevaluation_upgrade 新增)
-- ============================================================
-- 表: bre_trait_observation (性状观测明细)
-- 设计说明: 单株鉴定性状值长表(EAV)。
-- 与其它表关系: tree / tree_evaluation / trait / cross_combination 外键。
-- 约束: 同一次鉴定内同一性状仅一条(evaluation_id 非空时)。
CREATE TABLE IF NOT EXISTS bre_trait_observation (
evaluation_id int,
tree_id int,
combination_id int,
trait_id int NOT NULL,
evaluate_year int,
value_numeric float,
value_text varchar(255),
value_date varchar(20),
remark text,
CONSTRAINT fk_bre_trait_observation_combination_id FOREIGN KEY (combination_id) REFERENCES bre_cross_combination (id),
CONSTRAINT fk_bre_trait_observation_evaluation_id FOREIGN KEY (evaluation_id) REFERENCES bre_tree_evaluation (id),
CONSTRAINT fk_bre_trait_observation_trait_id FOREIGN KEY (trait_id) REFERENCES bre_trait (id),
CONSTRAINT fk_bre_trait_observation_tree_id FOREIGN KEY (tree_id) REFERENCES bre_tree (id),
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_trait_observation_uuid UNIQUE (uuid)
);
CREATE INDEX IF NOT EXISTS ix_bre_trait_observation_created_deleted ON bre_trait_observation (created_time, is_deleted);
CREATE UNIQUE INDEX IF NOT EXISTS uq_bre_trait_observation_eval_trait ON bre_trait_observation (evaluation_id, trait_id) WHERE ((evaluation_id IS NOT NULL) AND (is_deleted = false));
CREATE INDEX IF NOT EXISTS ix_bre_trait_observation_combination ON bre_trait_observation (combination_id);
CREATE INDEX IF NOT EXISTS ix_bre_trait_observation_created_id ON bre_trait_observation (created_id);
CREATE INDEX IF NOT EXISTS ix_bre_trait_observation_deleted_id ON bre_trait_observation (deleted_id);
CREATE INDEX IF NOT EXISTS ix_bre_trait_observation_evaluation ON bre_trait_observation (evaluation_id);
CREATE INDEX IF NOT EXISTS ix_bre_trait_observation_trait ON bre_trait_observation (trait_id);
CREATE INDEX IF NOT EXISTS ix_bre_trait_observation_tree ON bre_trait_observation (tree_id);
CREATE INDEX IF NOT EXISTS ix_bre_trait_observation_updated_id ON bre_trait_observation (updated_id);