首页 理论 架构 工程 文档 白皮书 著作 研究 案例 下载 博客 关于 开始使用 →

第218章 RelationRepository

第218章 RelationRepository

218.1 RelationRepository定义

在前面的 ICAI 工程体系中,ObjectRepository 负责对象持久化,StateRepository 负责状态持久化。

对象与对象之间还存在大量关系:

Object A
   ↓
Relation
   ↓
Object B

因此需要建立独立的 RelationRepository。

RelationRepository 是 Relation Domain Object 与持久化系统之间的边界,负责关系事实的保存、查询和更新。

其核心模型为:

RR=(R,M,Q,U,P,T)RR=(R,M,Q,U,P,T)

其中:

  • RR:Relation,关系领域对象;
  • MM:Mapping,关系映射;
  • QQ:Query,关系查询;
  • UU:Update,关系更新;
  • PP:Persistence,关系持久化;
  • TT:Time,操作时间。

因此:

RelationRepository=RelationSave+RelationQuery+RelationUpdate\boxed{ RelationRepository = RelationSave + RelationQuery + RelationUpdate }

其基本结构:

Relation Domain Object
        ↓
RelationRepository
        ↓
RelationMapper
        ↓
PDO
        ↓
MySQL

读取:

MySQL
   ↓
PDO
   ↓
RelationRepository
   ↓
RelationMapper
   ↓
Relation Domain Object

218.2 Relation领域对象

前面的 RelationEngine 已经定义:

R=(ID,O1,T,O2,C,S,Tm)R=(ID,O_1,T,O_2,C,S,T_m)

其中:

  • IDID:Relation ID;
  • O1O_1:Source Object,关系源对象;
  • TT:Relation Type,关系类型;
  • O2O_2:Target Object,关系目标对象;
  • CC:Condition,关系成立条件;
  • SS:State,关系当前状态;
  • TmT_m:Relation Time,关系时间。

例如:

Object O-001
      │
      │ supports
      ↓
Object O-002

对应:

R=(O1,supports,O2,C,S,T)R=(O_1,supports,O_2,C,S,T)

关系本身是独立的 Domain Object。

因此:

Relation≠Object\boxed{ Relation \neq Object }

同时:

Relation≠Relation TableRelation \neq Relation\ Table

数据库只是关系的持久化表示。


218.3 RelationRepository与RelationEngine

这是本章最重要的边界。

RelationEngine 负责:

关系计算
关系类型判断
关系方向判断
关系条件判断
关系匹配
关系更新候选计算
关系验证

RelationRepository 负责:

关系保存
关系查询
关系读取
关系更新

因此:

RelationEngine=Relation CalculationRelationEngine=Relation\ Calculation

而:

RelationRepository=Relation PersistenceRelationRepository=Relation\ Persistence

正确流程:

Object O1
Object O2
Condition
Rule
     ↓
RelationEngine
     ↓
Relation Candidate
     ↓
Validation
     ↓
Verification
     ↓
UpdateEngine
     ↓
RelationRepository
     ↓
MySQL

不能让 Repository 自己判断:

O1 是否 supports O2?

这是 RelationEngine 的职责。


218.4 关系保存

关系保存是把已经确认的 Relation 持久化。

基本流程:

Relation
   ↓
Validate
   ↓
Map
   ↓
Check Existing
   ↓
Insert
   ↓
ReadBack
   ↓
Verify

公式:

Save(R)→Validate→Map→Persist→VerifySave(R) \rightarrow Validate \rightarrow Map \rightarrow Persist \rightarrow Verify


218.5 关系保存条件

一个 Relation 在保存之前至少需要确认:

ValidRelation=Source∧Target∧Type∧Condition∧Rule∧EvidenceValidRelation = Source \land Target \land Type \land Condition \land Rule \land Evidence

其中:

  • Source:源对象存在;
  • Target:目标对象存在;
  • Type:关系类型合法;
  • Condition:关系条件合法;
  • Rule:关系规则允许;
  • Evidence:存在关系成立依据。

注意:

RelationExists≠RelationValidRelationExists \neq RelationValid

数据库中存在一条关系记录,并不意味着该关系在认知意义上一定有效。


218.6 关系方向

大多数 ICAI Relation 都应该明确方向。

例如:

O1→supports→O2O_1\rightarrow supports\rightarrow O_2

不能自动认为:

O2→supports→O1O_2\rightarrow supports\rightarrow O_1

除非 RelationEngine 中明确规定 inverse relation。

例如:

O1 → contains → O2
O2 → part_of → O1

这两个关系可以互为显式逆关系。

因此 RelationRepository 保存的必须是已经确定方向的关系事实。


218.7 关系唯一性

一个关系通常可以用:

Key=(O1,T,O2)Key=(O_1,T,O_2)

确定。

例如:

1001
supports
2001

形成:

(1001,supports,2001)(1001,supports,2001)

同一个 Key 不应该在不允许多重关系的情况下重复创建。

Repository 可以在保存前检查:

Exists
   ↓
Yes → Update / Reject
No  → Insert

但是是否允许重复关系属于领域规则与数据库约束共同决定的问题。


218.8 关系查询

RelationRepository 的第二项核心能力是查询。

基本模型:

Query(C)→{R1,R2,…,Rn}Query(C)\rightarrow\{R_1,R_2,\ldots,R_n\}

其中 CC 是查询条件。

常见查询:

按照关系ID查询
按照源对象查询
按照目标对象查询
按照关系类型查询
按照状态查询
按照源对象+类型查询
按照类型+目标对象查询

218.9 按关系ID查询

findById(ID)→RfindById(ID)\rightarrow R

PHP:

public function findById($id)
{
    $sql = "
        SELECT *
        FROM object_relations
        WHERE id = :id
        LIMIT 1
    ";

    $stmt = $this->pdo->prepare($sql);

    $stmt->execute(array(
        ':id' => $id
    ));

    $data = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$data) {
        return null;
    }

    return $this->mapper->toDomain($data);
}

Repository 返回的是 Relation Domain Object。


218.10 按源对象查询

对于:

O1→R→O2O_1\rightarrow R\rightarrow O_2

可以查询:

findBySource(O1)→{R1,…,Rn}findBySource(O_1) \rightarrow \{R_1,\ldots,R_n\}

例如:

public function findBySourceObjectId($objectId)
{
    $sql = "
        SELECT *
        FROM object_relations
        WHERE source_object_id = :object_id
        ORDER BY id ASC
    ";

    $stmt = $this->pdo->prepare($sql);

    $stmt->execute(array(
        ':object_id' => $objectId
    ));

    $relations = array();

    while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $relations[] = $this->mapper->toDomain($data);
    }

    return $relations;
}

218.11 按目标对象查询

反向查询:

findByTarget(O2)→{R1,…,Rn}findByTarget(O_2) \rightarrow \{R_1,\ldots,R_n\}

例如:

public function findByTargetObjectId($objectId)
{
    $sql = "
        SELECT *
        FROM object_relations
        WHERE target_object_id = :object_id
        ORDER BY id ASC
    ";

    $stmt = $this->pdo->prepare($sql);

    $stmt->execute(array(
        ':object_id' => $objectId
    ));

    $relations = array();

    while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $relations[] = $this->mapper->toDomain($data);
    }

    return $relations;
}

这样可以分别获取:

Outgoing Relations
Incoming Relations

218.12 按关系类型查询

例如:

supports
uses
depends_on
contains
part_of
belongs_to
conflicts_with
located_in

可以:

findByType(T)→{R}findByType(T)\rightarrow\{R\}

例如:

public function findByType($type)
{
    $sql = "
        SELECT *
        FROM object_relations
        WHERE relation_type = :type
        ORDER BY id ASC
    ";

    $stmt = $this->pdo->prepare($sql);

    $stmt->execute(array(
        ':type' => $type
    ));

    $relations = array();

    while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $relations[] = $this->mapper->toDomain($data);
    }

    return $relations;
}

218.13 按对象和关系类型查询

更常见的是:

Query(O1,T)→{R}Query(O_1,T)\rightarrow\{R\}

例如:

O-001
   ↓
supports
   ↓
所有目标对象

SQL:

public function findBySourceAndType($objectId, $type)
{
    $sql = "
        SELECT *
        FROM object_relations
        WHERE source_object_id = :object_id
        AND relation_type = :type
        ORDER BY id ASC
    ";

    $stmt = $this->pdo->prepare($sql);

    $stmt->execute(array(
        ':object_id' => $objectId,
        ':type' => $type
    ));

    $relations = array();

    while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $relations[] = $this->mapper->toDomain($data);
    }

    return $relations;
}

这为后续 KnowledgeEngine、SceneEngine、MatchingEngine 提供关系事实读取能力。


218.14 关系双向查询

可以进一步建立:

findBetween(O1,O2)→{R}findBetween(O_1,O_2) \rightarrow \{R\}

用于查询两个对象之间是否已经存在关系。

public function findBetween($sourceId, $targetId)
{
    $sql = "
        SELECT *
        FROM object_relations
        WHERE source_object_id = :source_id
        AND target_object_id = :target_id
        ORDER BY id ASC
    ";

    $stmt = $this->pdo->prepare($sql);

    $stmt->execute(array(
        ':source_id' => $sourceId,
        ':target_id' => $targetId
    ));

    $relations = array();

    while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $relations[] = $this->mapper->toDomain($data);
    }

    return $relations;
}

如果需要查询两个方向,则必须显式执行:

(O1,O2)(O_1,O_2)

和:

(O2,O1)(O_2,O_1)

不能因为关系查询方便就自动认为关系无方向。


218.15 关系更新

关系更新模型:

Rt+ΔR→Rt+1R_t+\Delta R\rightarrow R_{t+1}

例如:

O1 → supports → O2

变为:

O1 → depends_on → O2

或者:

active
↓
inactive

这些都属于关系更新。

但是:

ΔR\Delta R

应该由 RelationEngine / UpdateEngine 计算并确认。

RelationRepository 负责正式持久化。


218.16 关系更新流程

Current Relation
      ↓
RelationEngine
      ↓
Change Candidate
      ↓
Validation
      ↓
Verification
      ↓
UpdateEngine
      ↓
RelationRepository
      ↓
MySQL

公式:

Rt+ΔR→Validate→Update→VerifyR_t+\Delta R \rightarrow Validate \rightarrow Update \rightarrow Verify


218.17 关系状态更新

Relation 本身具有 State。

例如:

created
active
inactive
blocked
expired
deleted

如果关系从:

active→blockedactive\rightarrow blocked

应该经过:

RelationEngine
      ↓
StateEngine
      ↓
UpdateEngine
      ↓
RelationRepository

不能由 Repository 自己判断关系应该变成 blocked。


218.18 关系类型更新

关系类型更新属于更严格的更新。

例如:

supports→depends_onsupports\rightarrow depends\_on

这实际上已经改变了关系语义。

因此不能简单认为:

UPDATE relation_type

就完成了认知层面的更新。

应该:

Old Relation
      ↓
RelationEngine
      ↓
New Relation Candidate
      ↓
Verification
      ↓
UpdateEngine
      ↓
Repository

这样可以确保关系变化具有依据。


218.19 关系对象更新

如果:

O1O_1

或者:

O2O_2

发生变化,也可能影响 Relation。

例如:

O1
 ↓
located_in
 ↓
O2

当 O1 的位置发生变化时,旧关系可能需要重新计算。

流程:

Object Change
     ↓
RelationEngine
     ↓
Affected Relations
     ↓
Recalculate
     ↓
Update Candidate
     ↓
RelationRepository

这里体现:

ObjectChange→RelationRecalculationObjectChange \rightarrow RelationRecalculation

但 RelationRepository 不负责自动推导这种影响。


218.20 关系查询与RelationEngine

Repository 查询到的关系:

O1 → supports → O2

只是数据库中的事实。

RelationEngine 可以进一步判断:

关系是否有效?
关系是否满足当前条件?
关系是否仍然 active?
是否满足当前场景?

因此:

Query(R)≠Evaluate(R)Query(R)\neq Evaluate(R)

更完整:

RelationRepository
      ↓
Load Relation Facts
      ↓
RelationEngine
      ↓
Calculate / Match / Verify

218.21 关系查询与KnowledgeEngine

Relation 是 KnowledgeEngine 的重要输入。

例如:

O1 → supports → O2
O2 → supports → O3

KnowledgeEngine 可以根据明确规则进行推导。

例如:

supports(O1,O2)∧supports(O2,O3)→supports(O1,O3)supports(O_1,O_2) \land supports(O_2,O_3) \rightarrow supports(O_1,O_3)

但只有在规则明确允许传递推导时才能成立。

因此:

RelationRepository
      ↓
Relation Facts
      ↓
KnowledgeEngine
      ↓
Knowledge Calculation

RelationRepository 本身不能进行传递推理。


218.22 关系查询与SceneEngine

SceneEngine 需要:

Objects
States
Relations
Environment
Time

因此:

Scene=F(O,S,R,Env,T)Scene = F(O,S,R,Env,T)

其中 RR 就来自 RelationRepository 加载的关系事实。

完整过程:

ObjectRepository
      ↓
StateRepository
      ↓
RelationRepository
      ↓
SceneEngine
      ↓
Scene

这使 RelationRepository 成为场景计算的数据基础之一。


218.23 RelationMapper

关系映射:

Relation↔PersistenceDataRelation \leftrightarrow PersistenceData

例如:

<?php

class RelationMapper
{
    public function toPersistence($relation)
    {
        return array(
            'id' => $relation->getId(),
            'source_object_id' => $relation->getSourceObjectId(),
            'relation_type' => $relation->getType(),
            'target_object_id' => $relation->getTargetObjectId(),
            'condition' => $relation->getCondition(),
            'state' => $relation->getState(),
            'relation_time' => $relation->getTime()
        );
    }

    public function toDomain($data)
    {
        $relation = new Relation();

        $relation->setId($data['id']);
        $relation->setSourceObjectId(
            $data['source_object_id']
        );
        $relation->setType(
            $data['relation_type']
        );
        $relation->setTargetObjectId(
            $data['target_object_id']
        );
        $relation->setCondition(
            $data['condition']
        );
        $relation->setState(
            $data['state']
        );
        $relation->setTime(
            $data['relation_time']
        );

        return $relation;
    }
}

Mapper 不负责判断关系是否合法。


218.24 RelationRepository PHP接口

兼容 PHP 5.6 / PHP 7:

<?php

interface RelationRepositoryInterface
{
    public function findById($id);

    public function findBySourceObjectId($objectId);

    public function findByTargetObjectId($objectId);

    public function findByType($type);

    public function findBySourceAndType($objectId, $type);

    public function findBetween($sourceId, $targetId);

    public function save($relation);

    public function update($relation);

    public function exists($sourceId, $type, $targetId);
}

该接口把关系查询能力标准化。


218.25 RelationRepository基本实现

<?php

class MySQLRelationRepository implements RelationRepositoryInterface
{
    protected $pdo;
    protected $mapper;

    public function __construct(PDO $pdo, RelationMapper $mapper)
    {
        $this->pdo = $pdo;
        $this->mapper = $mapper;
    }

    public function findById($id)
    {
        $sql = "
            SELECT *
            FROM object_relations
            WHERE id = :id
            LIMIT 1
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':id' => $id
        ));

        $data = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$data) {
            return null;
        }

        return $this->mapper->toDomain($data);
    }

    public function findBySourceObjectId($objectId)
    {
        $sql = "
            SELECT *
            FROM object_relations
            WHERE source_object_id = :object_id
            ORDER BY id ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':object_id' => $objectId
        ));

        return $this->mapRows($stmt);
    }

    public function findByTargetObjectId($objectId)
    {
        $sql = "
            SELECT *
            FROM object_relations
            WHERE target_object_id = :object_id
            ORDER BY id ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':object_id' => $objectId
        ));

        return $this->mapRows($stmt);
    }

    public function findByType($type)
    {
        $sql = "
            SELECT *
            FROM object_relations
            WHERE relation_type = :type
            ORDER BY id ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':type' => $type
        ));

        return $this->mapRows($stmt);
    }

    public function findBySourceAndType($objectId, $type)
    {
        $sql = "
            SELECT *
            FROM object_relations
            WHERE source_object_id = :object_id
            AND relation_type = :type
            ORDER BY id ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':object_id' => $objectId,
            ':type' => $type
        ));

        return $this->mapRows($stmt);
    }

    public function findBetween($sourceId, $targetId)
    {
        $sql = "
            SELECT *
            FROM object_relations
            WHERE source_object_id = :source_id
            AND target_object_id = :target_id
            ORDER BY id ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':source_id' => $sourceId,
            ':target_id' => $targetId
        ));

        return $this->mapRows($stmt);
    }

    public function exists($sourceId, $type, $targetId)
    {
        $sql = "
            SELECT COUNT(*) AS total
            FROM object_relations
            WHERE source_object_id = :source_id
            AND relation_type = :type
            AND target_object_id = :target_id
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':source_id' => $sourceId,
            ':type' => $type,
            ':target_id' => $targetId
        ));

        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        return ((int)$row['total'] > 0);
    }

    public function save($relation)
    {
        $data = $this->mapper->toPersistence($relation);

        if ($this->exists(
            $data['source_object_id'],
            $data['relation_type'],
            $data['target_object_id']
        )) {
            return false;
        }

        $sql = "
            INSERT INTO object_relations
            (
                id,
                source_object_id,
                relation_type,
                target_object_id,
                condition,
                state,
                relation_time
            )
            VALUES
            (
                :id,
                :source_object_id,
                :relation_type,
                :target_object_id,
                :condition,
                :state,
                :relation_time
            )
        ";

        $stmt = $this->pdo->prepare($sql);

        return $stmt->execute(array(
            ':id' => $data['id'],
            ':source_object_id' => $data['source_object_id'],
            ':relation_type' => $data['relation_type'],
            ':target_object_id' => $data['target_object_id'],
            ':condition' => $data['condition'],
            ':state' => $data['state'],
            ':relation_time' => $data['relation_time']
        ));
    }

    public function update($relation)
    {
        $data = $this->mapper->toPersistence($relation);

        $sql = "
            UPDATE object_relations
            SET
                source_object_id = :source_object_id,
                relation_type = :relation_type,
                target_object_id = :target_object_id,
                condition = :condition,
                state = :state,
                relation_time = :relation_time
            WHERE id = :id
        ";

        $stmt = $this->pdo->prepare($sql);

        return $stmt->execute(array(
            ':id' => $data['id'],
            ':source_object_id' => $data['source_object_id'],
            ':relation_type' => $data['relation_type'],
            ':target_object_id' => $data['target_object_id'],
            ':condition' => $data['condition'],
            ':state' => $data['state'],
            ':relation_time' => $data['relation_time']
        ));
    }

    protected function mapRows($stmt)
    {
        $relations = array();

        while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $relations[] = $this->mapper->toDomain($data);
        }

        return $relations;
    }
}

上述代码是 Repository 的结构性实现示例。表名、字段名以及唯一约束必须根据实际工程数据库进行适配,不能未经检查就视为现有项目的可直接运行版本。


218.26 关系保存事务

关系保存通常涉及:

Source Object
Target Object
Relation

因此保存前应该确保源对象和目标对象存在。

流程:

ValidateSource∧ValidateTarget∧ValidateRelationValidateSource \land ValidateTarget \land ValidateRelation

然后:

Begin
 ↓
Check Source
 ↓
Check Target
 ↓
Check Duplicate
 ↓
Insert Relation
 ↓
Verify
 ↓
Commit

如果关系同时需要维护逆关系:

O1 → contains → O2
O2 → part_of → O1

那么两个关系的保存也应该由事务统一协调。


218.27 关系更新事务

关系更新:

Rt+ΔR→Rt+1R_t+\Delta R\rightarrow R_{t+1}

如果更新包含:

Type
Condition
State
Target

就必须保证更新过程的一致性。

流程:

Begin
   ↓
Load Current Relation
   ↓
Validate Change
   ↓
Update
   ↓
ReadBack
   ↓
Verify
   ↓
Commit

218.28 关系更新与唯一性冲突

例如当前:

O1 → supports → O2

准备更新为:

O1 → uses → O2

如果:

O1 → uses → O2

已经存在,那么更新可能违反唯一关系规则。

因此:

ValidUpdate=ValidChange∧NoDuplicate∧RuleValidUpdate = ValidChange \land NoDuplicate \land Rule

如果冲突:

Update
   ↓
Duplicate Check
   ↓
Conflict

Repository 应返回失败或冲突状态,而不是强制覆盖。


218.29 关系历史

虽然本章重点是保存、查询、更新,但 Relation 的变化也具有历史意义。

例如:

supports
 ↓
inactive
 ↓
deleted

如果直接覆盖关系记录:

state = deleted

就无法知道关系什么时候曾经 active。

因此对于需要追踪的关系,可以建立:

relation_history

保存:

RH=(R,Sb,Sa,C,T)RH=(R,S_b,S_a,C,T)

其中:

  • RR:关系;
  • SbS_b:变化前状态;
  • SaS_a:变化后状态;
  • CC:变化原因;
  • TT:变化时间。

这样形成:

Relation+RelationHistoryRelation + RelationHistory

与 StateRepository 的设计原则一致。


218.30 RelationRepository与Memory、Experience

关系历史可以成为认知系统后续数据来源。

例如:

O1 → supports → O2

经过多次实际运行以后:

该关系在某类场景中经常成立

可能进入:

Memory

进一步形成:

Experience

因此:

RelationHistory→Memory→ExperienceRelationHistory \rightarrow Memory \rightarrow Experience

但是:

RelationRepository≠MemoryEngineRelationRepository \neq MemoryEngine RelationRepository≠ExperienceEngineRelationRepository \neq ExperienceEngine


218.31 RelationRepository与KnowledgeEngine

Relation 是 KnowledgeEngine 的基础事实之一。

例如:

supports(O1,O2)supports(O_1,O_2)

可以作为知识事实:

K=(S,P,O,C,St)K=(S,P,O,C,S_t)

其中:

  • Subject = O1;
  • Predicate = supports;
  • Object = O2。

因此:

RelationRepository
       ↓
Relation Fact
       ↓
KnowledgeEngine
       ↓
Knowledge Calculation

但必须保持:

RelationFact≠InferredKnowledgeRelationFact \neq InferredKnowledge

Repository 保存事实。

KnowledgeEngine 负责计算。


218.32 RelationRepository与SceneEngine

SceneEngine 的输入之一就是 Relation。

Sc=F(O,S,R,C,Env,T)Sc=F(O,S,R,C,Env,T)

因此:

ObjectRepository
        ↓
StateRepository
        ↓
RelationRepository
        ↓
SceneEngine

SceneEngine 根据这些事实计算当前场景。

因此 RelationRepository 是 SceneEngine 的持久化事实来源之一。


218.33 RelationRepository与MatchingEngine

MatchingEngine 可以查询关系事实:

Candidate Object
       ↓
RelationRepository
       ↓
Existing Relations
       ↓
MatchingEngine

例如要求:

O1 必须 supports O2

Repository 负责找到关系。

MatchingEngine 负责判断:

Match(R,C)Match(R,C)

所以:

QueryRelation≠MatchRelationQueryRelation \neq MatchRelation


218.34 关系更新的最小更新原则

如果只是:

state:
active → blocked

则:

ΔR=ΔS\Delta R=\Delta S

只更新关系状态。

如果只是 Condition 改变:

ΔR=ΔC\Delta R=\Delta C

只更新 Condition。

不能因为 Relation 的一个字段改变,就删除关系重新创建整个关系结构。

因此:

Rt+ΔR→Rt+1\boxed{ R_t+\Delta R\rightarrow R_{t+1} }

遵循最小更新原则。


218.35 RelationRepository完整工程关系

最终形成:

Controller
     ↓
RelationService
     ↓
RelationEngine
     ↓
UpdateEngine
     ↓
RelationRepository
     ↓
MySQL

关系读取:

RelationService
      ↓
RelationRepository
      ↓
Relation Domain Objects

关系计算:

Objects
States
Conditions
Rules
      ↓
RelationEngine
      ↓
Relation Candidate
      ↓
Verification

然后:

UpdateEngine
      ↓
RelationRepository
      ↓
MySQL

218.36 RelationRepository核心公式

关系保存:

Save(R)→Validate→Map→Persist→Verify\boxed{ Save(R) \rightarrow Validate \rightarrow Map \rightarrow Persist \rightarrow Verify }

关系查询:

Query(C)→PersistenceData→Relation\boxed{ Query(C) \rightarrow PersistenceData \rightarrow Relation }

关系更新:

Rt+ΔR→Validate→Update→Verify\boxed{ R_t+\Delta R \rightarrow Validate \rightarrow Update \rightarrow Verify }

关系存在性:

Exists(O1,T,O2)\boxed{ Exists(O_1,T,O_2) }

关系有效性:

ValidRelation=Source∧Target∧Type∧Condition∧Rule∧Evidence\boxed{ ValidRelation = Source \land Target \land Type \land Condition \land Rule \land Evidence }

这里尤其需要注意:

Exists≠ValidExists\neq Valid

数据库里存在关系记录,只说明持久化层存在该记录,并不能自动证明当前认知环境中该关系仍然有效。


218.37 本章核心原则

原则一:Relation是独立Domain Object

Relation≠ObjectRelation\neq Object

原则二:RelationRepository不负责关系计算

RelationRepository≠RelationEngineRelationRepository\neq RelationEngine

原则三:查询不等于关系推导

Query(R)≠Infer(R)Query(R)\neq Infer(R)

原则四:关系方向必须明确

O1→T→O2O_1\rightarrow T\rightarrow O_2

不自动等于:

O2→T→O1O_2\rightarrow T\rightarrow O_1

原则五:关系存在不等于关系有效

Exists(R)≠Valid(R)Exists(R)\neq Valid(R)

原则六:关系更新遵守最小更新原则

Rt+ΔR→Rt+1R_t+\Delta R\rightarrow R_{t+1}

原则七:关系保存需要源对象和目标对象

ValidSource∧ValidTargetValidSource\land ValidTarget

原则八:关系变化应该能够追溯

RelationChange→RelationHistoryRelationChange \rightarrow RelationHistory

原则九:Repository不负责知识推理

RelationRepository≠KnowledgeEngineRelationRepository\neq KnowledgeEngine

原则十:Repository不负责场景计算

RelationRepository≠SceneEngineRelationRepository\neq SceneEngine


218.38 本章总结

RelationRepository 是 ICAI 关系持久化体系的核心组件。

它把 Relation Domain Object 与 MySQL 隔离:

Relation↔RelationRepository↔MySQL\boxed{ Relation \leftrightarrow RelationRepository \leftrightarrow MySQL }

其核心职责为:

Save+Query+Update\boxed{ Save + Query + Update }

关系保存:

Relation→Validate→Persist→VerifyRelation \rightarrow Validate \rightarrow Persist \rightarrow Verify

关系查询:

QueryCondition→MySQL→RelationQueryCondition \rightarrow MySQL \rightarrow Relation

关系更新:

Rt+ΔR→Validate→Update→VerifyR_t+\Delta R \rightarrow Validate \rightarrow Update \rightarrow Verify

完整工程路径:

Object
Object
   ↓
RelationEngine
   ↓
Relation Candidate
   ↓
Verification
   ↓
UpdateEngine
   ↓
RelationRepository
   ↓
MySQL

读取以后:

MySQL
   ↓
RelationRepository
   ↓
Relation
   ↓
KnowledgeEngine
SceneEngine
MatchingEngine
CognitiveEngine

因此可以最终确定:

RelationEngine=关系计算\boxed{ RelationEngine=关系计算 } UpdateEngine=关系更新应用\boxed{ UpdateEngine=关系更新应用 } RelationRepository=关系持久化\boxed{ RelationRepository=关系持久化 } MySQL=关系数据存储\boxed{ MySQL=关系数据存储 }

由此形成:

Object→RelationEngine→UpdateEngine→RelationRepository→MySQL\boxed{ Object \rightarrow RelationEngine \rightarrow UpdateEngine \rightarrow RelationRepository \rightarrow MySQL }

以及:

RelationRepository→Relation→SceneEngine/KnowledgeEngine/MatchingEngine\boxed{ RelationRepository \rightarrow Relation \rightarrow SceneEngine/KnowledgeEngine/MatchingEngine }

RelationRepository 由此成为 ICAI 对象关系事实从运行时进入持久化、再从持久化重新进入认知计算体系 的核心数据边界。

Leave a Reply

Your email address will not be published. Required fields are marked *