第233章 ICAI数据库关系
233.1 数据库关系的提出
ICAI(Individual Cognitive AI,个体认知人工智能)并不是由一组相互孤立的数据表组成。
前面的章节已经建立了个体、对象、属性、状态、关系、场景、知识、需求、目标、能力、方法、决策、行为、动作、执行、结果、反馈、记忆、经验、学习、风险、冲突、异常、诊断、保护与修复等数据结构。
如果这些数据只分别存储在不同的数据表中,而没有明确的数据关系,那么数据库只能保存“数据”,不能形成完整的认知对象结构。
因此,ICAI数据库关系(ICAI Database Relationship)是指:
通过主键、外键、关系表以及领域关系对象,将不同认知数据对象按照身份、从属、关联、引用和个体归属建立可验证的数据连接。
ICAI数据库关系的核心不是“表与表连接”本身,而是:
数据对象身份 → 数据对象关系 → 个体归属 → 认知过程关联 → 历史追踪
因此,本章建立以下基本结构:
Individual → Object → Attribute / State / Relation → Knowledge / Goal / Capability / Method → Decision → Behavior → Action → Execution → Result → Feedback → Memory / Experience → Learning → Risk / Conflict / Abnormality → Diagnosis / Protection / Repair
数据库关系必须能够支撑这条完整链路。
233.2 主键
主键(Primary Key,PK)是数据库表中用于唯一识别一条持久化记录的字段。
例如:
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY
对于:
individuals
objects
states
relations
knowledge
goals
capabilities
methods
decisions
behaviors
actions
executions
results
feedbacks
memories
experiences
learning_records
risks
conflicts
abnormalities
diagnoses
protections
repairs
每张核心表都应该具有自己的数据库主键。
但是必须继续保持前面章节确定的一个重要原则:
Domain ID ≠ Database Primary Key
例如:
individual_code = IND-0001
database id = 15
其中:
IND-0001
是ICAIDomain层面的业务身份标识,而:
15
是MySQL持久化记录的主键。
二者不能混为一谈。
233.2.1 主键的三个作用
主键至少承担三个工程作用。
第一,唯一识别
例如:
individuals.id = 15
只能指向一条数据库记录。
第二,建立引用基础
其他表可以通过外键引用该记录。
例如:
objects.individual_id
可以引用:
individuals.id
第三,支持数据生命周期管理
Repository可以利用主键进行:
Load
Update
Delete
Exists
因此主键属于数据库持久化层的基础身份机制,而不是认知计算机制。
233.3 ICAI领域编码与数据库主键
ICAI不应仅依赖数据库自增ID。
推荐同时存在:
id
individual_code
object_code
goal_code
method_code
behavior_code
action_code
result_code
memory_code
experience_code
risk_code
diagnosis_code
repair_code
例如:
individuals
id = 15
individual_code = IND-0001
objects
id = 81
object_code = OBJ-0018
goals
id = 102
goal_code = GOAL-0012
这样形成两层身份:
Domain Identity
↓
individual_code / object_code / goal_code
↓
Persistence Identity
↓
MySQL id
这样可以避免认知对象身份与数据库存储身份耦合。
233.4 外键
外键(Foreign Key,FK)是数据库中用于表达两个持久化记录之间引用关系的字段。
例如:
objects.individual_id
引用:
individuals.id
可以表达:
Individual
↓
Object
即某个对象属于某个个体。
233.4.1 外键的基本结构
例如:
CREATE TABLE objects (
id BIGINT NOT NULL AUTO_INCREMENT,
object_code VARCHAR(100) NOT NULL,
individual_id BIGINT NULL,
object_type VARCHAR(100) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_object_code (object_code),
KEY idx_object_individual (individual_id)
);
如果数据库层需要强制约束,也可以进一步建立:
CONSTRAINT fk_object_individual
FOREIGN KEY (individual_id)
REFERENCES individuals(id)
但是ICAI工程中是否使用物理Foreign Key,需要结合数据删除策略、历史数据保留策略以及Repository设计决定。
尤其是:
History、Memory、Experience、Learning、Diagnosis、Repair
这些数据通常具有长期追踪价值,因此不能因为某个当前对象被删除,就简单级联删除全部历史认知数据。
233.5 外键与ICAI认知关系的区别
必须区分:
数据库外键关系
与:
ICAI领域关系
数据库外键回答:
“这条记录引用哪一条数据库记录?”
ICAI领域关系回答:
“这个认知对象与另一个认知对象是什么关系?”
例如:
objects.individual_id → individuals.id
表达数据库层面的个体归属。
而:
Object A
related_to
Object B
则属于ICAI领域关系。
因此:
Foreign Key ≠ Domain Relation
外键是持久化引用机制。
领域关系是认知对象之间的语义关系。
233.6 一对一关系
一对一关系(One-to-One,1:1)表示一个对象最多对应另一个对象的一条记录。
例如某些ICAI配置数据可以采用:
Individual
↓
IndividualProfile
一个Individual对应一个Profile。
数据库可以设计为:
CREATE TABLE individual_profiles (
id BIGINT NOT NULL AUTO_INCREMENT,
individual_id BIGINT NOT NULL,
profile_data TEXT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_profile_individual (individual_id),
KEY idx_profile_individual (individual_id)
);
这里:
individual_id
既可以作为外键引用:
individuals.id
又通过:
UNIQUE
保证一个Individual最多拥有一条Profile。
因此:
Individual 1
↓
Profile 1
形成一对一关系。
233.7 一对多关系
一对多关系(One-to-Many,1:N)是ICAI数据库最常见的关系。
例如:
Individual
↓
Objects
一个个体可以拥有多个对象。
即:
Individual 1
├── Object 1
├── Object 2
├── Object 3
└── Object N
数据库结构:
objects.individual_id
↓
individuals.id
233.7.1 个体与状态
一个对象在运行过程中可以产生多个状态记录:
Object
├── State 1
├── State 2
├── State 3
└── State N
因此:
objects 1 → N states
但是需要注意:
Current State ≠ State History
当前状态应该表达对象现在的状态。
状态历史则表达过去发生过哪些状态变化。
因此可以形成:
Object
├── Current State
└── State History
233.7.2 个体与记忆
一个Individual可以具有多个Memory:
Individual
├── Memory A
├── Memory B
├── Memory C
└── Memory N
因此:
individuals 1 → N memories
对应:
memories.individual_id
引用:
individuals.id
233.7.3 个体与经验
同样,一个Individual可以形成多个Experience:
Individual
├── Experience A
├── Experience B
└── Experience N
因此:
individuals 1 → N experiences
233.8 多对多关系
多对多关系(Many-to-Many,N:M)表示:
A → 多个B
B → 多个A
不能直接通过单个外键完整表达。
ICAI中最典型的是:
Memory ↔ Memory
以及:
Experience ↔ Experience
或者:
Goal ↔ Capability
例如:
Goal A
├── Capability 1
├── Capability 2
└── Capability 3
Goal B
├── Capability 2
├── Capability 3
└── Capability 4
此时:
Goal ↔ Capability
就是多对多关系。
233.9 多对多关系表
ICAI应该使用独立关系表保存多对多关系。
例如:
CREATE TABLE goal_capability_relations (
id BIGINT NOT NULL AUTO_INCREMENT,
goal_code VARCHAR(100) NOT NULL,
capability_code VARCHAR(100) NOT NULL,
relation_type VARCHAR(100) NOT NULL,
condition_data TEXT NULL,
relation_state VARCHAR(50) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_goal_capability (
goal_code,
capability_code,
relation_type
),
KEY idx_goal_relation (goal_code),
KEY idx_capability_relation (capability_code)
);
关系表本身也是一个领域数据对象。
它不仅保存:
A belongs to B
还可以保存:
Relation Type
Condition
State
Time
Evidence
Weight
因此ICAI中的关系不是简单的数据库连接,而是具有属性的认知关系。
233.10 ICAI关系对象
前面的关系模型定义为:
R=(ID,O1,T,O2,C,S,Tm)R=(ID,O_1,T,O_2,C,S,T_m)
其中:
- IDID:关系身份
- O1O_1:关系起点对象
- TT:关系类型
- O2O_2:关系终点对象
- CC:关系成立条件
- SS:关系状态
- TmT_m:关系建立或更新时间
因此:
Relation
=
Object1
+
RelationType
+
Object2
+
Condition
+
State
+
Time
这比单纯的:
object1_id
object2_id
更加完整。
233.11 个体关系
个体关系(Individual Relationship)是ICAI数据库关系体系的核心。
它表示:
一个Individual与其他认知对象、其他Individual以及这些对象之间关系网络的结构化连接。
个体关系不是简单的:
individual_id
而是:
Individual
↓
Object
↓
Relation
↓
Object
因此可以建立:
Individual
├── Objects
├── States
├── Goals
├── Capabilities
├── Methods
├── Behaviors
├── Memories
├── Experiences
├── Knowledge
├── Risks
├── Conflicts
├── Abnormalities
├── Diagnoses
└── Repairs
这些对象进一步通过Relation形成网络。
233.12 Individual作为关系中心
ICAI不是把所有数据表简单地连接在一起,而是以Individual作为认知主体。
基本关系:
Individual
↓
Object
↓
State
↓
Behavior
↓
Result
↓
Feedback
↓
Memory
↓
Experience
↓
Learning
同时:
Individual
↓
Need
↓
Goal
↓
Capability
↓
Method
↓
Decision
↓
Behavior
维护链:
Individual
↓
Risk / Conflict / Abnormality
↓
Diagnosis
↓
Protection / Repair
↓
Verification
最终形成:
Individual
↓
Cognitive Objects
↓
Relations
↓
Cognitive Process
↓
History
↓
Memory / Experience
↓
Learning
↓
Update
233.13 个体关系表
如果需要专门保存Individual之间的关系,可以建立:
CREATE TABLE individual_relations (
id BIGINT NOT NULL AUTO_INCREMENT,
relation_code VARCHAR(100) NOT NULL,
individual1_id BIGINT NOT NULL,
relation_type VARCHAR(100) NOT NULL,
individual2_id BIGINT NOT NULL,
condition_data TEXT NULL,
relation_state VARCHAR(50) NOT NULL,
evidence_data TEXT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_individual_relation (relation_code),
KEY idx_individual1 (individual1_id),
KEY idx_individual2 (individual2_id),
KEY idx_relation_type (relation_type),
KEY idx_relation_state (relation_state)
);
例如:
Individual A
↓
supervises
↓
Individual B
或者:
Individual A
↓
collaborates_with
↓
Individual B
关系本身可以继续拥有:
Condition
State
Evidence
Time
因此:
Individual A
↓
Relation
↓
Individual B
不是简单的“好友列表”式数据,而是一个正式的领域关系对象。
233.14 对象关系
ICAI不仅需要Individual之间的关系,也需要Object之间的关系。
例如:
Object A
↓
contains
↓
Object B
或者:
Object A
↓
depends_on
↓
Object B
可以使用:
CREATE TABLE object_relations (
id BIGINT NOT NULL AUTO_INCREMENT,
relation_code VARCHAR(100) NOT NULL,
object1_code VARCHAR(100) NOT NULL,
relation_type VARCHAR(100) NOT NULL,
object2_code VARCHAR(100) NOT NULL,
condition_data TEXT NULL,
relation_state VARCHAR(50) NOT NULL,
evidence_data TEXT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_object_relation (relation_code),
KEY idx_object1 (object1_code),
KEY idx_object2 (object2_code),
KEY idx_relation_type (relation_type),
KEY idx_relation_state (relation_state)
);
这样:
Object
↕
Relation
↕
Object
成为ICAI对象关系网络的基础。
233.15 认知对象之间的关系
ICAI数据库关系不能只设计:
Individual → Object
还必须支持不同认知对象之间的关联。
例如:
Need → Goal
Goal → Capability
Goal → Method
Capability → Method
Method → Decision
Decision → Behavior
Behavior → Action
Action → Execution
Execution → Result
Result → Feedback
Feedback → Memory
Memory → Experience
Experience → Learning
Learning → Knowledge
Risk → Protection
Conflict → Diagnosis
Abnormality → Diagnosis
Diagnosis → Repair
Repair → Verification
这些关系共同构成ICAI认知数据库。
233.16 外键关系与关系表的组合
ICAI数据库不应该强行使用一种关系机制解决全部问题。
应该根据关系性质选择。
个体归属
采用外键:
objects.individual_id
当前对象引用
采用外键或领域编码:
state.object_id
多对象领域关系
采用关系表:
object_relations
个体之间关系
采用:
individual_relations
多对多关系
采用专用关系表:
goal_capability_relations
历史关系
采用历史表:
history_records
因此形成:
Foreign Key
+
Relation Table
+
Domain Code
+
History
↓
Complete ICAI Data Relationship
233.17 数据关系与时间
ICAI关系不是永远不变的。
例如:
Object A
↓
depends_on
↓
Object B
可能在:
T1
成立。
到了:
T2
关系可能解除。
因此关系需要具有:
created_at
updated_at
如果需要完整历史,还可以保存:
relation_history
形成:
Relation Created
↓
Relation Active
↓
Relation Updated
↓
Relation Inactive
↓
Relation Archived
这与ICAI的状态和历史体系保持一致。
233.18 数据关系与状态
关系本身也具有状态。
例如:
active
inactive
blocked
pending
verified
invalid
archived
因此:
Relation
=
Object1
+
Type
+
Object2
+
Condition
+
State
+
Time
关系不是数据库中静态存在的“线”,而是一个具有生命周期的数据对象。
233.19 数据关系与证据
对于知识、经验、诊断、风险等认知数据,仅仅存在关系并不足以证明关系正确。
因此可以增加:
evidence_data
例如:
Abnormality
↓
Diagnosis
Diagnosis需要说明:
Evidence
↓
Cause
↓
Diagnosis
同样:
Risk
↓
Protection
Protection也应该能够追溯其风险依据。
因此:
Relation
+
Evidence
+
Condition
+
Time
才能形成可追踪的ICAI关系。
233.20 数据库关系与Repository
Repository负责数据库关系的读取和保存,但不负责决定认知关系。
例如:
ObjectRepository
负责:
Load Object
Save Object
Update Object
Query Object
而:
RelationRepository
负责:
Load Relation
Save Relation
Update Relation
Delete Relation
Query Relation
但:
RelationEngine
负责计算:
两个对象是否满足关系条件
关系类型是什么
关系是否有效
关系状态如何变化
因此必须保持:
Engine
↓
Calculation
Repository
↓
Persistence
即:
Repository不负责认知计算。
233.21 数据库关系与Service
Service负责协调多个Repository和Engine。
例如:
RelationService
↓
RelationEngine
↓
RelationRepository
↓
MySQL
一个典型过程:
读取对象
↓
读取条件
↓
RelationEngine计算
↓
生成Relation
↓
RelationService验证
↓
RelationRepository保存
这与前面的ICAIServices架构保持一致。
233.22 PHP对象映射
ICAI可以在PHP中将数据库关系映射为Domain Object。
例如:
class Relation
{
protected $id;
protected $object1;
protected $relationType;
protected $object2;
protected $condition;
protected $state;
protected $time;
public function __construct($data = array())
{
$this->id = isset($data['id']) ? $data['id'] : null;
$this->object1 = isset($data['object1']) ? $data['object1'] : null;
$this->relationType = isset($data['relation_type']) ? $data['relation_type'] : null;
$this->object2 = isset($data['object2']) ? $data['object2'] : null;
$this->condition = isset($data['condition']) ? $data['condition'] : null;
$this->state = isset($data['state']) ? $data['state'] : null;
$this->time = isset($data['time']) ? $data['time'] : null;
}
}
数据库记录:
relation_code
object1_code
relation_type
object2_code
condition_data
relation_state
created_at
updated_at
通过Mapper转换为:
Relation Object
形成:
MySQL Row
↓
Mapper
↓
Relation Domain Object
↓
RelationEngine
233.23 ICAI数据库关系总图
ICAI数据库关系可以统一表示为:
Individual
│
┌────────────────┼────────────────┐
↓ ↓ ↓
Objects Goals Knowledge
│ │
┌─────┼─────┐ ↓
↓ ↓ ↓ Capabilities
Attributes States Relations │
↓
Methods
│
↓
Decisions
│
↓
Behaviors
│
↓
Actions
│
↓
Executions
│
↓
Results
│
↓
Feedback
│
┌──────────────┴──────────────┐
↓ ↓
Memories Experiences
│ │
└──────────────┬──────────────┘
↓
Learning
│
↓
Update
│
↓
Knowledge / Capability / Method
维护关系:
Individual
↓
Risk / Conflict / Abnormality
↓
Diagnosis / Protection
↓
Repair
↓
Verification
↓
History
233.24 ICAI数据库关系的六种基础关系
因此,本章所建立的数据库关系可以统一为六类。
第一类:主键关系
Record → Unique Identity
由Primary Key实现。
第二类:外键关系
Record A → Record B
由Foreign Key实现。
第三类:一对一关系
A 1 → 1 B
通过外键 + UNIQUE约束实现。
第四类:一对多关系
A 1 → N B
通常通过B表中的Foreign Key实现。
第五类:多对多关系
A N ↔ M B
通过独立Relation Table实现。
第六类:个体关系
Individual
↓
Cognitive Objects
↓
Relations
↓
Cognitive Processes
这是ICAI数据库区别于普通业务数据库的重要部分。
233.25 ICAI关系完整原则
ICAI数据库关系必须遵循以下原则。
第一,身份唯一。
每一个持久化记录必须具有明确的Primary Key。
第二,领域身份独立。
Domain ID不能简单等同于Database ID。
第三,归属明确。
属于某个Individual的数据必须能够追溯其Individual。
第四,关系显式。
重要认知关系不能仅依赖程序代码中的隐含逻辑。
第五,多对多独立。
多对多关系必须使用明确的Relation Table。
第六,关系可验证。
重要认知关系应该能够保存Condition、Evidence、State和Time。
第七,历史可追溯。
关系变化不能直接覆盖过去事实而失去历史。
第八,Repository不负责认知。
Repository负责持久化,Engine负责计算,Service负责协调。
233.26 本章总结
ICAI数据库不是简单的“数据表集合”,而是一个由身份、引用、归属、关系、状态、时间和历史共同构成的认知数据结构。
主键解决:
我是谁?
外键解决:
我引用谁?
一对一解决:
一个对象对应一个对象
一对多解决:
一个对象对应多个对象
多对多解决:
多个对象之间的复杂关联
个体关系解决:
这些对象为什么属于同一个认知主体,
以及它们之间如何形成完整关系网络。
最终形成:
Primary Key
↓
Identity
↓
Foreign Key
↓
Ownership / Reference
↓
1:1 / 1:N / N:M
↓
Domain Relation
↓
Individual Relation
↓
Cognitive Data Network
↓
ICAI Cognitive System
因此,ICAI数据库关系的最终目标不是单纯让SQL能够执行JOIN,而是让Individual、Object、State、Knowledge、Goal、Capability、Method、Decision、Behavior、Memory、Experience、Learning、Risk、Conflict、Abnormality、Diagnosis、Protection、Repair等认知对象能够形成明确、可查询、可追踪、可验证的关系网络。
这一关系网络最终成为ICAI运行时认知计算的数据基础。
第233章补充 ICAI关系表的完整数据库约束
233.27 关系表约束的提出
ICAI中的Relation(关系)不是简单保存两个对象编号的连接表。
前面定义:
R=(ID,O1,T,O2,C,S,Tm)R=(ID,O_1,T,O_2,C,S,T_m)
其中:
- IDID:关系唯一身份
- O1O_1:关系起点
- TT:关系类型
- O2O_2:关系终点
- CC:关系成立条件
- SS:关系状态
- TmT_m:关系时间
因此数据库必须保证:
Relation
↓
身份合法
↓
对象合法
↓
关系类型合法
↓
关系组合唯一
↓
关系状态合法
↓
时间合法
↓
关系可追踪
数据库约束(Database Constraint)就是对这些条件进行持久化层面的强制限制。
233.28 关系表约束的八个层次
ICAI关系表建议建立八类约束:
1. 主键约束
2. 非空约束
3. 唯一约束
4. 外键约束
5. 自引用约束
6. 状态约束
7. 时间约束
8. 业务关系约束
其中:
Primary Key
↓
Identity Constraint
Foreign Key
↓
Reference Constraint
UNIQUE
↓
Duplicate Constraint
CHECK
↓
Value Constraint
Index
↓
Query Constraint
233.29 主键约束
所有正式关系表都必须具有自己的数据库主键。
例如:
PRIMARY KEY (id)
完整定义:
id BIGINT NOT NULL AUTO_INCREMENT
因此:
Relation Row 1 → id=1
Relation Row 2 → id=2
Relation Row 3 → id=3
每一条关系记录具有唯一数据库身份。
但是:
id ≠ relation_code
其中:
id
是数据库Persistence Identity。
而:
relation_code
是ICAI Domain Identity。
233.30 关系编码唯一约束
关系必须具有Domain层唯一编码。
例如:
relation_code VARCHAR(100) NOT NULL
并建立:
UNIQUE KEY uk_relation_code (relation_code)
因此:
REL-0001
REL-0002
REL-0003
不能重复。
完整结构:
CREATE TABLE object_relations (
id BIGINT NOT NULL AUTO_INCREMENT,
relation_code VARCHAR(100) NOT NULL,
...
PRIMARY KEY (id),
UNIQUE KEY uk_relation_code (relation_code)
);
233.31 外键约束
如果关系表直接使用数据库ID引用对象,则应该建立Foreign Key。
例如:
object1_id BIGINT NOT NULL,
object2_id BIGINT NOT NULL
对应:
CONSTRAINT fk_relation_object1
FOREIGN KEY (object1_id)
REFERENCES objects(id),
CONSTRAINT fk_relation_object2
FOREIGN KEY (object2_id)
REFERENCES objects(id)
形成:
objects
↑
│
object1_id
│
object_relations
│
object2_id
│
↓
objects
这能够防止关系指向不存在的数据库对象。
233.32 为什么需要两个外键
关系天然具有两个端点:
R=(O1,T,O2)R=(O_1,T,O_2)
因此:
object1_id
表示关系起点。
object2_id
表示关系终点。
不能只保存:
object_id
否则无法确定关系另一端是谁。
因此:
O1 → Relation → O2
必须至少能够识别:
O1
O2
233.33 一对多关系约束
一对多关系通常不需要建立独立关系表。
例如:
Individual 1
↓
N
Objects
直接在:
objects
中保存:
individual_id BIGINT NOT NULL
并建立:
CONSTRAINT fk_object_individual
FOREIGN KEY (individual_id)
REFERENCES individuals(id)
同时建立:
KEY idx_object_individual (individual_id)
因此:
individuals.id
↑
│
objects.individual_id
实现:
Individual 1 → N Objects
233.34 一对一关系约束
一对一关系除了Foreign Key,还必须使用UNIQUE。
例如:
CREATE TABLE individual_profiles (
id BIGINT NOT NULL AUTO_INCREMENT,
individual_id BIGINT NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_profile_individual (individual_id),
CONSTRAINT fk_profile_individual
FOREIGN KEY (individual_id)
REFERENCES individuals(id)
);
其中:
FOREIGN KEY
保证Individual存在。
而:
UNIQUE
保证同一个Individual只能有一个Profile。
因此:
Individual 1 → Profile 1
而不会变成:
Individual 1 → Profile 1
→ Profile 2
→ Profile 3
233.35 多对多关系约束
多对多关系必须通过关系表实现。
例如:
Goal N ↔ M Capability
关系表:
CREATE TABLE goal_capability_relations (
id BIGINT NOT NULL AUTO_INCREMENT,
goal_code VARCHAR(100) NOT NULL,
capability_code VARCHAR(100) NOT NULL,
relation_type VARCHAR(100) NOT NULL,
condition_data TEXT NULL,
relation_state VARCHAR(50) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id)
);
但是仅有Primary Key不够。
必须增加:
UNIQUE KEY uk_goal_capability_relation (
goal_code,
capability_code,
relation_type
)
这样:
Goal A
↓
requires
↓
Capability B
只能存在一条有效的同类型关系。
233.36 为什么唯一约束必须包含关系类型
不能简单写:
UNIQUE (goal_code, capability_code)
因为两个对象之间可能存在不同关系。
例如:
Goal A
├── requires → Capability B
└── depends_on → Capability B
这是两个不同的Domain Relation。
因此唯一性应该定义为:
Unique=(O1,O2,T)Unique=(O_1,O_2,T)
即:
Object1
+
RelationType
+
Object2
共同决定关系身份。
233.37 自引用关系约束
某些关系允许:
Object A → Object A
例如某些递归结构、层级关系或自我引用模型。
但是大多数普通关系不允许:
Object A
↓
Object A
例如:
depends_on
contains
parent_of
通常不应该允许自己依赖自己、自己包含自己。
因此,如果数据库版本支持合适的CHECK约束,可以定义:
CHECK (object1_id <> object2_id)
即:
object1_id ≠ object2_id
但是否允许自引用,必须由具体Relation Type决定。
因此不能把:
O1 ≠ O2
作为所有关系的绝对规则。
正确原则是:
Relation Type
↓
Self Relation Allowed?
↓
Yes / No
233.38 关系方向约束
ICAI必须明确关系是否具有方向。
例如:
A depends_on B
不能简单等同于:
B depends_on A
因此:
A → depends_on → B
和:
B → depends_on → A
是两个不同关系。
对于有向关系,唯一约束应该是:
UNIQUE (
object1_id,
relation_type,
object2_id
)
233.39 对称关系约束
有些关系是对称关系,例如:
A collaborates_with B
理论上:
B collaborates_with A
可能表示同一个关系。
这种关系不能只依赖普通:
UNIQUE (object1_id, relation_type, object2_id)
因为数据库可能允许:
A → collaborates_with → B
B → collaborates_with → A
形成两条重复关系。
因此,对称关系需要在Domain层进行规范化。
例如规定:
min(O1,O2) → Relation → max(O1,O2)
然后保存。
即:
Object1 Code < Object2 Code
时:
Object1 = O1
Object2 = O2
否则交换。
这样:
A ↔ B
只保存一次。
233.40 关系状态约束
关系状态不能任意填写。
建议统一:
pending
active
inactive
blocked
verified
invalid
archived
例如:
relation_state VARCHAR(50) NOT NULL
如果MySQL版本和部署策略允许,可以增加CHECK:
CHECK (
relation_state IN (
'pending',
'active',
'inactive',
'blocked',
'verified',
'invalid',
'archived'
)
)
但在兼容PHP 5.6 / MySQL 5.7环境时,不应把系统正确性完全依赖于CHECK,因为不同MySQL版本对CHECK约束的实际执行能力存在差异。
因此更可靠的结构是:
Database
↓
NOT NULL / UNIQUE / FK
↓
Repository Validation
↓
Domain Validation
233.41 时间约束
关系至少应该保存:
created_at
updated_at
如果需要表达关系实际生效时间,还应该增加:
effective_at
expired_at
例如:
effective_at DATETIME NULL,
expired_at DATETIME NULL
形成:
created_at
↓
effective_at
↓
active
↓
expired_at
数据库关系的时间必须与关系状态保持一致。
例如:
expired_at < effective_at
就是非法时间关系。
因此Domain层应验证:
Texpired≥TeffectiveT_{expired}\geq T_{effective}
233.42 关系时间与历史时间
必须区分:
created_at
和:
effective_at
以及:
updated_at
三者含义不同。
例如:
T1
Relation发生
T2
Relation被系统检测
T3
Relation被写入数据库
T4
Relation被修改
可能存在:
effective_at = T1
detected_at = T2
created_at = T3
updated_at = T4
因此:
Database Creation Time
≠
Domain Relation Time
这对ICAI历史和经验分析非常重要。
233.43 条件约束
关系不是无条件成立的。
前面的Relation模型已经定义:
R=(ID,O1,T,O2,C,S,Tm)R=(ID,O_1,T,O_2,C,S,T_m)
其中:
C=ConditionC=Condition
因此关系表可以保存:
condition_data TEXT NULL
但必须注意:
condition_data
不能被数据库当作“关系已经成立”的证明。
正确流程:
Condition
↓
RelationEngine
↓
Condition Evaluation
↓
Relation State
↓
Repository Save
数据库负责保存结果。
Engine负责计算关系是否满足条件。
233.44 证据约束
对于需要认知依据的关系,应支持:
evidence_data TEXT NULL
例如:
Knowledge → supports → Goal
或者:
Abnormality → causes → Diagnosis
这些关系需要能够追溯:
Evidence
↓
Relation
因此:
Relation
+
Evidence
+
Time
构成可追踪关系。
233.45 删除约束
ICAI不能简单使用:
ON DELETE CASCADE
删除全部认知数据。
例如:
Individual
↓
Memory
↓
Experience
↓
Learning
↓
History
如果删除Individual时级联删除所有数据,将破坏历史认知链。
因此建议:
Current Data
↓
可根据业务规则删除或停用
Historical Data
↓
原则上保留
对于核心认知关系,优先:
inactive
archived
invalid
而不是物理DELETE。
233.46 外键删除策略
推荐根据数据性质分别处理。
当前业务关系
可以:
RESTRICT
防止被引用对象被意外删除。
历史关系
尽量:
RESTRICT
或者不建立物理Foreign Key,而通过Repository和Domain ID保持逻辑引用。
临时关系
如果明确属于临时数据,可以根据业务需要:
CASCADE
但必须经过明确设计,不能默认使用。
ICAI原则:
历史数据的可追溯性优先于级联删除的方便性。
233.47 NULL约束
关系中的核心身份字段不能允许NULL。
例如:
relation_code VARCHAR(100) NOT NULL
object1_id BIGINT NOT NULL
relation_type VARCHAR(100) NOT NULL
object2_id BIGINT NOT NULL
relation_state VARCHAR(50) NOT NULL
created_at DATETIME NOT NULL
updated_at DATETIME NOT NULL
而:
condition_data
evidence_data
effective_at
expired_at
可以根据领域要求允许NULL。
原则:
必须存在的数据 → NOT NULL
可选数据 → NULL
不能为了“方便插入”而把所有字段设置为NULL。
233.48 索引约束
关系表必须考虑查询方向。
至少需要:
KEY idx_relation_object1 (object1_id),
KEY idx_relation_object2 (object2_id),
KEY idx_relation_type (relation_type),
KEY idx_relation_state (relation_state)
因为ICAICognitive Engine经常执行:
查询某对象发出的所有关系
以及:
查询某对象接收的所有关系
即:
Object → Outgoing Relations
Object → Incoming Relations
因此:
object1_id
object2_id
都必须具有查询能力。
233.49 推荐的object_relations完整结构
综合以上约束,可以将对象关系表设计为:
CREATE TABLE object_relations (
id BIGINT NOT NULL AUTO_INCREMENT,
relation_code VARCHAR(100) NOT NULL,
object1_id BIGINT NOT NULL,
relation_type VARCHAR(100) NOT NULL,
object2_id BIGINT NOT NULL,
condition_data TEXT NULL,
relation_state VARCHAR(50) NOT NULL,
evidence_data TEXT NULL,
effective_at DATETIME NULL,
expired_at DATETIME NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_relation_code (
relation_code
),
UNIQUE KEY uk_object_relation (
object1_id,
relation_type,
object2_id
),
KEY idx_relation_object1 (
object1_id
),
KEY idx_relation_object2 (
object2_id
),
KEY idx_relation_type (
relation_type
),
KEY idx_relation_state (
relation_state
),
KEY idx_relation_effective (
effective_at
),
CONSTRAINT fk_relation_object1
FOREIGN KEY (object1_id)
REFERENCES objects(id),
CONSTRAINT fk_relation_object2
FOREIGN KEY (object2_id)
REFERENCES objects(id)
);
这张表已经能够表达:
Object1
↓
Relation Type
↓
Object2
并同时保存:
Condition
State
Evidence
Effective Time
Expiration Time
Creation Time
Update Time
233.50 个体关系表完整约束
对于:
Individual ↔ Individual
可以建立:
CREATE TABLE individual_relations (
id BIGINT NOT NULL AUTO_INCREMENT,
relation_code VARCHAR(100) NOT NULL,
individual1_id BIGINT NOT NULL,
relation_type VARCHAR(100) NOT NULL,
individual2_id BIGINT NOT NULL,
condition_data TEXT NULL,
relation_state VARCHAR(50) NOT NULL,
evidence_data TEXT NULL,
effective_at DATETIME NULL,
expired_at DATETIME NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_individual_relation_code (
relation_code
),
UNIQUE KEY uk_individual_relation (
individual1_id,
relation_type,
individual2_id
),
KEY idx_individual_relation_1 (
individual1_id
),
KEY idx_individual_relation_2 (
individual2_id
),
KEY idx_individual_relation_type (
relation_type
),
KEY idx_individual_relation_state (
relation_state
),
CONSTRAINT fk_individual_relation_1
FOREIGN KEY (individual1_id)
REFERENCES individuals(id),
CONSTRAINT fk_individual_relation_2
FOREIGN KEY (individual2_id)
REFERENCES individuals(id)
);
这样:
Individual A
↓
Relation
↓
Individual B
具有完整的数据库引用约束。
233.51 关系表不能解决的约束
数据库约束不能解决所有ICAI关系问题。
例如数据库可以验证:
Object1存在
Object2存在
Relation Code唯一
Relation字段不为空
但数据库不能单独判断:
Object1和Object2是否真的满足depends_on条件?
也不能单独判断:
Diagnosis是否真的由Abnormality支持?
这些属于认知计算。
因此必须划分:
Database Constraint
↓
保证数据结构合法
Domain Validation
↓
保证领域对象合法
RelationEngine
↓
保证关系计算合法
RelationService
↓
保证关系流程合法
233.52 四层关系合法性
ICAI关系最终应该经过四层验证。
第一层:数据库结构合法
PK
FK
UNIQUE
NOT NULL
INDEX
第二层:Domain合法
Object1 Valid
Object2 Valid
RelationType Valid
Condition Valid
State Valid
第三层:认知计算合法
RelationEngine
↓
Evaluate
↓
Relation Result
第四层:生命周期合法
Created
↓
Pending
↓
Active
↓
Verified
↓
Inactive / Archived
最终:
RelationValid=DatabaseValid∧DomainValid∧CognitiveValid∧LifecycleValidRelationValid = DatabaseValid \land DomainValid \land CognitiveValid \land LifecycleValid
233.53 最终关系约束模型
ICAI数据库关系可以最终统一为:
Relation
│
┌──────────────┼──────────────┐
↓ ↓ ↓
Identity Reference Semantics
│ │ │
PK/FK FK RelationType
│ │ │
└──────────────┼──────────────┘
↓
Uniqueness
↓
State
↓
Time
↓
Evidence
↓
Domain Validation
↓
RelationEngine
↓
RelationService
↓
Repository
↓
MySQL
233.54 本章补充总结
完整的ICAI关系表不能只定义:
object1
object2
relation_type
而应该至少解决:
谁?
↓
Primary Key
引用谁?
↓
Foreign Key
是什么关系?
↓
Relation Type
能否重复?
↓
UNIQUE
是否存在?
↓
NOT NULL / FK
是否有效?
↓
State
什么时候成立?
↓
Time
为什么成立?
↓
Evidence
是否满足认知条件?
↓
RelationEngine
是否可以进入系统?
↓
Domain Validation
因此,ICAI关系数据库的完整约束模型为:
RC=PK+FK+U+NN+CK+ST+TM+EV+IDXRC= PK+FK+U+NN+CK+ST+TM+EV+IDX
其中:
- PKPK:Primary Key,主键约束
- FKFK:Foreign Key,外键约束
- UU:Unique,唯一约束
- NNNN:Not Null,非空约束
- CKCK:Check / Domain Check,值和领域约束
- STST:State Constraint,状态约束
- TMTM:Time Constraint,时间约束
- EVEV:Evidence Constraint,证据约束
- IDXIDX:Index,索引约束
最终形成:
ICAI Relation
↓
Identity
↓
Reference
↓
Uniqueness
↓
Validity
↓
State
↓
Time
↓
Evidence
↓
Cognitive Validation
↓
Persistent Relation
这意味着数据库负责阻止非法数据结构进入持久化层,而RelationEngine、Domain Object和Service负责判断关系是否符合ICAI认知语义。两者不能互相替代。
这里实际上需要把第233章进一步收紧:统一对象关系的标识字段,否则 object1_code / object2_code / individual_id / relation_code 混用,会导致后续 Repository、Engine 和数据库关系越来越不一致。
建议统一成下面这套规则。
1. 先统一四种“身份”
| 类型 | 字段 | 含义 |
|---|---|---|
| 数据库身份 | id |
MySQL记录主键 |
| 领域对象身份 | object_code |
对象自身的业务唯一标识 |
| 关系身份 | relation_code |
一条关系自身的业务唯一标识 |
| 个体身份 | individual_code |
Individual自身的业务唯一标识 |
核心原则:
id
↓
Database Identity
object_code
↓
Domain Object Identity
relation_code
↓
Domain Relation Identity
individual_code
↓
Individual Identity
2. 不建议再使用 object1_code / object2_code
这两个字段虽然直观,但会把“对象关系”限制成只能表达 Object ↔ Object。
ICAI后面实际上需要:
Individual → Object
Object → State
Goal → Capability
Capability → Method
Abnormality → Diagnosis
Diagnosis → Repair
因此更统一的设计应该是:
source_type
source_code
relation_type
target_type
target_code
即:
Relation
=
Source
+
RelationType
+
Target
例如:
source_type = object
source_code = OBJ-001
relation_type = depends_on
target_type = object
target_code = OBJ-002
也可以:
source_type = abnormality
source_code = ABN-001
relation_type = diagnosed_by
target_type = diagnosis
target_code = DIA-001
这样一个 relations 表就可以承担统一的对象关系。
3. 建议把第233章的关系模型改成
R=(ID,S,T,D,C,St,Tm,E)R=(ID,S,T,D,C,S_t,T_m,E)
其中:
- IDID:关系数据库主键
- SS:Source,关系源对象
- TT:Relation Type,关系类型
- DD:Destination,关系目标对象
- CC:Condition,关系成立条件
- StS_t:Relation State,关系状态
- TmT_m:Relation Time,关系时间
- EE:Evidence,关系证据
其中 Source 和 Destination 都采用:
O=(Type,Code)O=(Type,Code)
因此:
Source = (source_type, source_code)
Target = (target_type, target_code)
最终:
Relation
↓
source_type
source_code
relation_type
target_type
target_code
condition_data
relation_state
evidence_data
created_at
updated_at
4. 推荐统一数据库表
CREATE TABLE relations (
id BIGINT NOT NULL AUTO_INCREMENT,
relation_code VARCHAR(100) NOT NULL,
source_type VARCHAR(100) NOT NULL,
source_code VARCHAR(100) NOT NULL,
relation_type VARCHAR(100) NOT NULL,
target_type VARCHAR(100) NOT NULL,
target_code VARCHAR(100) NOT NULL,
condition_data TEXT NULL,
relation_state VARCHAR(50) NOT NULL,
evidence_data TEXT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_relation_code (relation_code),
KEY idx_relation_source (
source_type,
source_code
),
KEY idx_relation_target (
target_type,
target_code
),
KEY idx_relation_type (
relation_type
),
KEY idx_relation_state (
relation_state
)
);
这样以后不再分别维护:
object_relations
individual_relations
goal_relations
knowledge_relations
memory_relations
experience_relations
作为唯一关系机制,而是可以统一为:
relations
特殊关系如果需要额外字段,再建立专用关系表。
5. 这样第233章的核心关系统一为
Individual
↓
individual_code
Object
↓
object_code
Relation
↓
relation_code
├── source_type
├── source_code
├── relation_type
├── target_type
├── target_code
├── condition
├── state
├── evidence
└── time
形成:
Source
↓
source_type + source_code
↓
relation_type
↓
target_type + target_code
↓
Target
这比现在第233章中的 object1_code / object2_code 更适合作为 ICAI统一对象关系标识标准。
尤其重要的一点是:
id永远是数据库身份;xxx_code是领域身份;关系两端统一使用type + code,不要让不同关系表自行发明不同的标识字段。
如果按这个方向继续,下一步第234章就可以直接建立 “ICAI统一关系表设计与关系类型编码”,把 relation_type、正向/反向关系、对称关系、传递关系、父子关系、依赖关系和关系唯一性规则一次统一。