From 9747196757aefda9414fa4477fbee263d22f6836 Mon Sep 17 00:00:00 2001 From: Yu Sun Date: Sat, 9 Jul 2022 14:30:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=A8=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 100 +++++++++++++++++++++++++++++++++++++++++++++- imgs/sql_body.png | Bin 0 -> 14866 bytes imgs/sql_head.png | Bin 0 -> 16403 bytes 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 imgs/sql_body.png create mode 100644 imgs/sql_head.png diff --git a/README.md b/README.md index d57beaf..b4f39d3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,59 @@ # EdgeManager(SCADA系统) +- [EdgeManager(SCADA系统)](#edgemanagerscada系统) + - [API](#api) + - [class `EDataCapture`](#class-edatacapture) + - [开发环境](#开发环境) + - [技术细节](#技术细节) + - [0. `EdgeManager\EDataCapture\EDataCapture -> set_data()`为什么是以`6507524`为大小chunked的?](#0-edgemanageredatacaptureedatacapture---set_data为什么是以6507524为大小chunked的) + +## API + +> API设计最大程度遵循了已有的MES规范。 + +### class `EDataCapture` + +0. HTTP POST: `set_data` + +**请求** + +```json +{ + 'action': 'set_data', + 'param': { + 'working_subclass': , + 'type': 'string' | 'int' | 'float' | 'bool', + 'code': , + // value的类型需与type对应 + 'value': , + 'device_code': [string], + 'batch': [string] + } +} +``` + +**返回** + +操作成功: + +```json +{ + 'action': 'result_set_data', + 'errcode': 0, + 'errmsg': '' +} +``` + +操作失败: + +```json +{ + 'action': 'result_set_data', + 'errcode': 4002, + 'errmsg': 'ROLLBACKed: Bad data received (structure and/or values)' +} +``` + ## 开发环境 拉取代码: @@ -26,4 +80,48 @@ docker exec -it edge_manager bash ```bash php EdgeManager.php --server_name=GPU-server-01 --user=postgres --password=big_dick start -``` \ No newline at end of file +``` + +客户端连接: + +```bash +sudo apt install postgresql-client +# 登入 +psql -h localhost -U postgres +# 显示数据库列表 +\l +``` + +## 技术细节 + +### 0. `EdgeManager\EDataCapture\EDataCapture -> set_data()`为什么是以`6507524`为大小chunked的? + +首先明确一点,根据PostgreSQL的技术架构,条件允许的情况下,**一次性插入多条记录是效率最高的**。 + +这其中,仅插入部分字段的值,比如: + +```sql +INSERT INTO films (code, title, did, date_prod, kind) + VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama'); +``` + +的效率又远远不如插入全部列,但使用特殊变量DEFAULT替代缺少的字段,比如: + +```sql +INSERT INTO films VALUES + ('UA502', 'Bananas', DEFAULT, '1971-07-13', 'Comedy', '82 minutes'); +``` + +PostgreSQL的文档里没有提及这个话题,因为源码里为SQL语句的内存分配[指定了一个最大长度常量`MaxAllocSize`](https://github.com/postgres/postgres/blob/2373fe78dfc9d4aa2348a86fffdf8eb9d757e9d5/src/common/stringinfo.c#L28),其大小为比1GB小1字节。这个值可以在编译前手动修改,所以理论上每个PG运行的实例都可以不一样,如果我们使用的PG并非修改过源码手动编译的,那么SQL语句的最大长度为`1024 ** 3 - 1 = 1073741823` bytes。 + +> 安全起见,下述计算假定working_subclass等字段的最大长度均为我们以往约定的45 bytes。 + +而此处我源码中的SQL语句头长度为131 bytes(注意末尾空格): + +![](imgs/sql_head.png) + +单个语句体的长度为165 bytes: + +![](imgs/sql_body.png) + +所以其最多可以一次性插入`(1073741823 - 131) / 165`条记录,向下取整后即为`6507524`。 diff --git a/imgs/sql_body.png b/imgs/sql_body.png new file mode 100644 index 0000000000000000000000000000000000000000..be8f3cb3d32f1a0162feb3abdf1cbe562055c9e0 GIT binary patch literal 14866 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 Su5-m#swiqauY6_^_TK>c{FVIx literal 0 HcmV?d00001 diff --git a/imgs/sql_head.png b/imgs/sql_head.png new file mode 100644 index 0000000000000000000000000000000000000000..4997b98718ff937b756ac83fe3138b1bfd00945a GIT binary patch literal 16403 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

A*bnD~B?ka0h}#^g zsr#r&g4pQ!fn9Vt%{0_RDzGqez&JmVyY&79!zL1i$a;01`-32Rip`3*+qyIbA<|7Zz&HHu>a9`^` zZk0Vo;|@$)e`e!e`V|V%fO)cP%oyq*v3E8Uq#U&*g(OmT%x z87`!_Cb-QL2OIA+jYjqUvPmi1p4i#=WIHLg9)9#u6^4N;8m8U|100C~whD)jEa1*h z(Nl6_v8xO})0~Yjof}>t&Nf7YHI*KrQ8xe0$001C3s(E_aHRN(czfILGOctDT$?Fv zeK>EJpp{+TfgnnArLE?Rd~5EHjZ&9$e!R9&x7_iaNKTlM!jseQIvXZ1VQv%x*l zT5Hx*TjW>}bhEZGDD#4GQy-YeA9yE9Zo(PmEwye_XChj1IidJl1DBGXm& z$Xo%12{jK3@G6j=rRy5OeRexz_xpunYOR$xM1Fb4cwV1s=qh_VIR#*tGEUht5v%oW zim`CsdKia)t)I3x4GJEQJKOnX8w=r?627w22c0-OqE_SJTrdMpNIpklA%T)>4y>gr zsyH)GDCfw2#21Kq76QSQxh$J5)iI-E>J8uF2uLGu+PWj8NU4x{qOv&{Ry&DofEuo~ zNWvobpAdKZ|8)?7eh*^Ny}EfN>Rr?@aza%oT0u)a>JjuqBFmWa=9NXoY*7QToV-Mp zFJZ;|UavTQEYL!2n$9{te64PZP>a+-wJ}Zy^3513T|D>vP1nO>k^EVNvtsL>Z*Osn zBUtf-CDDU1Y*k<^F6+=P)nt@Kd9ycVDxQ6O7weL|mG$_!2e-nPrd zVe;1N<+{+Q7_efsZ?(D{)`6zqjP##DrgfcyzbCM8+LM#KGgn5H5dU7(Drv=)W{l*& z34)r5J<3Z|NHpGo(r{$XRHq1zaA+HaIx#?m_)8xwUr2EKO~12HbWYIR9Lef?o;`;w zWh`uYm+WbmcvL@Q6XQYO^1S6Gvw3Hr_4gcUF%hR6#}Rg*#b0q6IrIf|3FM zCh;BWbxJs0(>qc_HPM8-xSqDhBJ?Wv`(?l_{2TV??;V9o5nvB#1l1zQjrlxtY~QOeiWXDA)KFtFxz?EWozDpM}7NvD&) za^Q6%-*x_8ab?5V(SpXKZbRZDE|t&m}&7bE|@zToe63#h3i%Md_Ze z#rscgupp^83O)LgtzcyQl3|_Q(^F?#)Rs?hDJsg8@hNt9N+@RN=6?<-Sniw4*Ib_v+Po*`Pn<)@pH z+UV?L$ckciO8)gA^y{P17Z{z@1%;y7wLDw3t}7LkQwrV*-F(4RZa-Jk-yG@>Yea-M z1B&b(jAeyQvqq5yeeIEC*>`>;ME5~;XN%U8tG2-`kh®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