外观
聚合根与关系
控制库的 41 张表围绕三个聚合根[1]组织。掌握这三个根,即可判定删除一行会连带删除哪些数据、哪些表属于独立事实。
三个聚合根
Node是节点的聚合根。 一行nodes持有该节点的身份字段(node_id主键、asn、router_id、loopback、前缀)、base_template(DesiredState 中不来自子表的部分)与current_generation(已发布的最新世代号)。它的子表(agent_tokens、peerings、wg_interfaces、bgp_sessions、generations)全部cascade="all, delete-orphan",删节点连带删子行。Peering是网络对等关系的聚合根。 一条 peering 对应 0..1 条WgInterface与 0..N 条BgpSession(均cascade="all, delete-orphan")。local_node_id指本端节点(CASCADE),remote_node_id可空、指向另一个受管节点(SET NULL)——materializer 据此现取现填对端 WG 公钥并区分内外部互联。DnsGroup是共享模型,节点通过Node.dns_group_id订阅。DNS 不按节点保存;多个节点指向同一组即拿到同一份配置,也就是 anycast。组被删时Node.dns_group_id置 NULL(节点停跑 DNS,不连带删节点)。
聚合根之外的表分两类:
- 观测与存档以
node_id挂在Node上,全部CASCADE——删除节点即清空其全部观测数据。 - 独立事实不设外键,删除节点后仍然留存。最典型的是
flap_alerts:其node_id有意不设外键,因为告警属于历史事实,不应随节点删除而级联消失。
关系一览
→ 表示外键指向,括号内为 ondelete:
nodes (聚合根)
├─ agent_tokens.node_id → nodes.node_id (CASCADE)
├─ enrollment_tokens.node_id → nodes.node_id (SET NULL)
├─ generations.node_id → nodes.node_id (CASCADE) UNIQUE(node_id, generation)
├─ node_wireguard_keys.node_id → nodes.node_id (CASCADE) (PK)
├─ peerings.local_node_id → nodes.node_id (CASCADE) UNIQUE(local_node_id, name)
├─ peerings.remote_node_id → nodes.node_id (SET NULL)
├─ wg_interfaces.node_id → nodes.node_id (CASCADE) UNIQUE(node_id, name)
│ └─ wg_interfaces.peering_id → peerings.id (SET NULL)
├─ bgp_sessions.node_id → nodes.node_id (CASCADE) UNIQUE(node_id, name)
│ └─ bgp_sessions.peering_id → peerings.id (SET NULL)
├─ node_status.node_id → nodes.node_id (CASCADE) (PK)
├─ node_status_events.node_id → nodes.node_id (CASCADE)
├─ node_metrics_rollup.node_id → nodes.node_id (CASCADE) (PK 复合)
├─ node_metrics_last.node_id → nodes.node_id (CASCADE) (PK)
├─ node_routing.node_id → nodes.node_id (CASCADE) (PK)
├─ node_route_entries.node_id → nodes.node_id (CASCADE)
├─ node_route_prefix_hashes.node_id → nodes.node_id (CASCADE) (PK)
├─ node_routing_events.node_id → nodes.node_id (CASCADE)
├─ node_traffic_rollup.node_id → nodes.node_id (CASCADE) (PK 复合)
├─ node_traffic_last_sample.node_id → nodes.node_id (CASCADE) (PK)
├─ node_iface_traffic_rollup.node_id→ nodes.node_id (CASCADE) (PK 复合)
├─ node_iface_traffic_last.node_id → nodes.node_id (CASCADE) (PK 复合)
├─ bgp_flap_state.node_id → nodes.node_id (CASCADE) (PK 复合)
├─ bgp_flap_transitions.node_id → nodes.node_id (CASCADE)
├─ node_prefix_flaps.node_id → nodes.node_id (CASCADE) (PK 复合)
├─ node_prefix_flap_meta.node_id → nodes.node_id (CASCADE) (PK)
├─ node_prefix_flap_paths.node_id → nodes.node_id (CASCADE) (PK 复合)
├─ prefix_flap_rate_rollup.node_id → nodes.node_id (CASCADE) (PK 复合)
├─ autopeering_node_policies.node_id→ nodes.node_id (CASCADE) (PK)
├─ peering_requests.node_id → nodes.node_id (CASCADE)
│ └─ peering_requests.peering_id → peerings.id (SET NULL)
├─ autopeer_route_rollup.node_id → nodes.node_id (CASCADE) (PK 复合)
└─ nodes.dns_group_id → dns_groups.id (SET NULL)
dns_groups (共享聚合根)
└─ dns_group_zones.dns_group_id → dns_groups.id (CASCADE) UNIQUE(dns_group_id, zone)
└─ dns_records.dns_group_zone_id→ dns_group_zones.id (CASCADE)
admin_users
└─ admin_sessions.user_id → admin_users.id (CASCADE)
独立表(无外键,删节点不连带)
port_pools 全 fleet 统一的端口段位
portal_login_transactions 登录事务(主路径已迁 L4)
portal_sessions 门户会话
flap_alerts node_id 有意不设外键:告警是历史事实
flap_activity_rollup fleet 级 60s 活跃度时间线,无节点维度
admin_audit_log 审计注意:SQLite(dev / CI)默认关闭外键,不开启则上述所有 ondelete 子句均不生效。引擎装配中每个新连接都会执行 PRAGMA foreign_keys=ON,见全局约定。
聚合根(aggregate root):领域驱动设计中的概念,指一组相关对象的唯一外部入口。外部只能通过聚合根访问和修改其内部对象,聚合根的生命周期决定内部对象的生命周期——在本库中体现为
cascade="all, delete-orphan"与外键的ON DELETE CASCADE。 ↩︎