3、配方数据存储:配方文件格式(CSV/XML)、配方数据库配置、配方存储路径管理

配方数据存哪儿、怎么存,这事儿看着简单,但坑不少。我见过太多项目,配方文件乱放,格式不统一,最后换条产线就得改半天程序。今天咱们就把这事儿捋清楚。

3.1 配方文件格式:CSV vs XML

配方文件说白了就是个数据载体。选什么格式,直接影响你后续的维护成本。我个人习惯,小项目用CSV,大项目用XML。

3.1.1 CSV格式——简单粗暴

CSV的好处就是轻量,Excel直接打开就能改。适合配方参数少、结构固定的场景。

// 一个典型的CSV配方文件
RecipeID, RecipeName, TempSet, PressureSet, TimeSet
R001, 标准工艺A, 120.5, 2.3, 45.0
R002, 标准工艺B, 135.0, 2.8, 50.0
R003, 高温工艺, 180.0, 3.5, 60.0

嗯,这里要注意:CSV没有层级结构。如果你的配方有嵌套参数(比如一个工步下面有多个子参数),CSV就有点吃力了。我在一个食品包装项目里遇到过,配方参数多达80多个,用CSV维护到后期,Excel文件打开都卡。

警告:CSV文件不要用中文做列名!不同系统的编码兼容性会让你崩溃。我吃过这个亏,后来统一用英文+下划线命名。

3.1.2 XML格式——结构化王者

XML虽然看着啰嗦,但它的结构化能力是CSV比不了的。特别是配方参数有层级关系时,XML的优势就出来了。

<?xml version="1.0" encoding="UTF-8"?>
<RecipeCollection>
    <Recipe ID="R001">
        <Name>标准工艺A</Name>
        <Parameters>
            <Temperature Unit="C">120.5</Temperature>
            <Pressure Unit="bar">2.3</Pressure>
            <Time Unit="s">45.0</Time>
        </Parameters>
        <Steps>
            <Step ID="1">
                <Action>加热</Action>
                <Target>120.0</Target>
            </Step>
            <Step ID="2">
                <Action>保温</Action>
                <Duration>30.0</Duration>
            </Step>
        </Steps>
    </Recipe>
</RecipeCollection>

你看,XML可以清晰地表达“配方→参数→工步”这样的层级关系。而且它支持属性(比如Unit="C"),这是CSV做不到的。

我的建议:如果配方参数超过30个,或者有嵌套结构,直接上XML。别犹豫,后期改起来省心得多。

3.2 配方数据库配置

文件存配方是小打小闹。真正工业级应用,配方数据必须进数据库。为什么?因为数据库能解决并发访问、版本控制、权限管理这些头疼问题。

3.2.1 数据库表结构设计

我一般设计三张表:配方主表、配方参数表、配方版本表。

表名 字段 说明
RecipeMaster RecipeID, RecipeName, ProductType, Status, CreateTime 配方主信息,一个配方一条记录
RecipeParams ParamID, RecipeID, ParamName, ParamValue, Unit, SeqNo 配方参数,一对多关系
RecipeVersion VersionID, RecipeID, VersionNo, ChangeLog, UpdateTime, Operator 版本追踪,每次修改都记录

为什么要单独搞个版本表?有一次我在化工项目里,操作员误改了配方参数,导致整批产品报废。从那以后,我所有项目都强制加版本控制。每次修改都留痕,谁改的、改了什么、什么时候改的,一查便知。

3.2.2 Intouch连接数据库

Intouch通过ODBC连接数据库,配置起来其实不复杂。关键步骤就三步:

  1. 配置ODBC数据源——在Windows的ODBC管理器中创建系统DSN
  2. 创建SQL访问模板——在Intouch的SQL Access Manager中定义绑定列表
  3. 编写脚本——用QuickScript执行SQL语句
// Intouch中读取配方的示例脚本
SQLConnect( ConnectionID, "DSN=RecipeDB;UID=sa;PWD=123456" );
SQLSelect( ConnectionID, "SELECT * FROM RecipeParams WHERE RecipeID = 'R001' ORDER BY SeqNo" );

// 绑定结果到内存表
SQLFirst( ConnectionID );
WHILE SQLSucceed( ConnectionID ) DO
    ParamName = SQLResult( ConnectionID, "ParamName" );
    ParamValue = SQLResult( ConnectionID, "ParamValue" );
    // 写入到Intouch标记名
    RecipeParam[ ParamName ] = ParamValue;
    SQLNext( ConnectionID );
ENDWHILE;

SQLDisconnect( ConnectionID );
核心要点:数据库连接字符串不要硬编码在脚本里。我习惯把连接参数写到Ini文件或注册表中,换数据库时改个配置就行,不用动代码。

3.3 配方存储路径管理

路径管理这事儿,看着不起眼,但出问题就是大麻烦。你想想看,如果配方文件存在C盘,系统重装全没了,那是什么感受?

3.3.1 路径规划原则

  • 不要用绝对路径——用相对路径或环境变量。比如 %RECIPE_PATH%\Standard
  • 分层存储——按产品类型、日期、班次分层建文件夹
  • 备份机制——配方文件每天自动备份到另一个盘符

我曾经在一个制药项目里,客户要求配方文件必须保留3年。我们设计了一套路径规则:D:\RecipeData\[ProductType]\[Year]\[Month]\[Day]\[RecipeName].xml。这样查找历史配方非常方便。

3.3.2 Intouch中的路径配置

在Intouch中,我通常用脚本动态拼接路径:

// 动态生成配方文件路径
sProductType = "TypeA";
sDate = DateString( CurrentTime, "%Y%m%d" );
sFilePath = "D:\\RecipeData\\" + sProductType + "\\" + sDate + "\\";

// 检查目录是否存在,不存在则创建
IF FileExist( sFilePath ) == 0 THEN
    CreateDirectory( sFilePath );
ENDIF;

// 完整文件路径
sFullPath = sFilePath + "Recipe_" + sRecipeID + ".xml";
注意:路径中不要包含特殊字符(空格、中文、&符号等)。我在一个项目中用了中文路径,结果Intouch的FileExist函数死活不认,排查了半天才发现是编码问题。

3.4 知识体系总览

下面这张图,把配方数据存储的核心逻辑串起来了。你对照着看,心里就有谱了。

配方数据存储核心架构 配方数据来源 文件存储 数据库存储 CSV格式 XML格式 SQL Server Oracle/MySQL 存储路径管理:分层结构 + 备份机制 + 权限控制 Intouch配方管理界面

这张图把配方数据存储的脉络理清了。从数据来源开始,到文件存储和数据库存储两条路,再到具体的格式和路径管理,最后落到Intouch界面上。你照着这个架构去设计,基本不会出大问题。

个人经验:别想着一步到位。先跑通文件存储,再迁移到数据库。我见过太多人一上来就搞数据库,结果连基本的读写都没调通,项目就延期了。

专注资料整理