【问题标题】:XML Parsing and query on MySQL select queryMySQL 选择查询上的 XML 解析和查询
【发布时间】:2021-04-05 00:34:17
【问题描述】:

我有一张表,其中有超过 20 亿行,我的搜索始终基于索引字段。

没有什么需要尝试的新方法是获取存储在 longtext 和 varchar(4000) 列中的 xml 字符串字段 这两个列都存储xml文件,一个是大xml文件,一个是小xmls文件。

我需要查询 xml 文件中的节点或字段。

例如,我需要获取第一个 xml 文件(DS 列第 6 列)中存在的 statusCode 和第二个 xml 文件(SY 列最后一列)中存在的 providerT

搜索总是基于索引列 CT_ID 然后基于 DS SY 列。

所以我正在搜索类似的查询

select * from AD_TABLE where CT_ID ='6ththeurtyiru' and DS.statusCode='COMPLETED' AND SY.providerT='noOfNRe';

我知道我的查询是错误的,但是如果我有 json 这可以工作,但我们在 MySql 中是否有任何这样的 xml?

我做了一些搜索,但查询看起来非常难以理解,特别是解析查询。

请有人帮我解决这个问题。

ID,VERSION,AN_TYPE,EN_TYPE,CT_ID,DS,OT_TYPE,DATE_TIME,GP_ID,OT_NAME,OT_ID,UR_NAME,UR_ID,PT_ID,NS,SY

6uyuitygjh82mcrzz,0,SD_CASE,MYCHECK,6ththeurtyiru
,<?xml version="1.0" encoding="UTF-8" standalone="yes"?><sCPayload><cId>suerywe7r-21cf-4c7e-8071-suerywe7r</cId><statusCode>COMPLETED</statusCode><sngState>INPROGRESS</sngState><noOfNRe>1</noOfNRe><noOfRRR>0</noOfRRR><noOfER>0</noOfER><noOfARR>1</noOfARR><providerT>WATCHLIST</providerT></sCPayload>,CASE,9/16/2020 9:45,bd7c9519-d726-4672-8599-83d21927bec5,,5f53b903-21cf-4c7e-8071-suerywe7r,System User,USER_SYSTEM,,,<?xml version="1.0" encoding="UTF-8" standalone="yes"?><screenCES><providerT>MYWATCH</providerT><noOfNRe>1</noOfNRe></screenCES>,

【问题讨论】:

  • 您使用的是哪个版本以及 MySQL 或 MariaDB ?
  • @BerndBuffen Mysql 我甚至可以使用 Maria DB
  • 我喜欢 MariaDB,但不是必须的,只是虚拟字段的语法有点不同

标签: mysql sql


【解决方案1】:

在MySQL8.0中,可以使用ExtractValue

对于 MariaDB (10.5),文档为:ExtractValue

mysql> set @xml='<sCPayload><cId>suerywe7r-21cf-4c7e-8071-suerywe7r</cId><statusCode>COMPLETED</statusCode><sngState>INPROGRESS</sngState><noOfNRe>1</noOfNRe><noOfRRR>0</noOfRRR><noOfER>0</noOfER><noOfARR>1</noOfARR><providerT>WATCHLIST</providerT></sCPayload>';
Query OK, 0 rows affected (0.00 sec)

mysql> select ExtractValue(@xml,'//statusCode');
+-----------------------------------+
| ExtractValue(@xml,'//statusCode') |
+-----------------------------------+
| COMPLETED                         |
+-----------------------------------+
1 row in set (0.00 sec)

mysql>

【讨论】:

  • set @xml 将为全表完成?我们如何为每一行设置这个?
  • 要对表中的每一行执行此操作,您必须执行类似 select ID,VERSION, ExtractValue(DS,'//statusCode') statusCode,ExtractValue(DS,'//sngState') sngState,ExtractValue(DS,'//providerT') providerT; 的操作
  • 所以这是选择但我必须首先运行set@xml 我将如何做到这一点?以上将适用于每一列,但仍适用于一行?
  • 不,set @xml = .... 只会创建一个变量,请参阅:dev.mysql.com/doc/refman/8.0/en/set-variable.html
  • 对不起,如果我感到困惑,但我们设置的值仅适用于一行..我确实设置了这个,当我查询其他行时,我得到 null 作为结果
【解决方案2】:

您还可以将提取的结果放在永久虚拟字段中。所以你可以建立一个索引或组合索引来获得一个快速的结果,而不是一个 FULL TABLE SCAN。 如果您更改 XML,此字段将自动更新

将此字段添加到您的表格中

ALTER TABLE yourTable

    ADD COLUMN
    `statusCode` varchar(16) AS (ExtractValue(DS,'//statusCode')) PERSISTENT;

【讨论】:

  • 但是这个Alter表和MySql Aurora普通的alter一样吗,因为那是非常广泛的操作。另外,如果我在这种情况下首先根据索引进行选择,那么该归档还需要索引吗?最后一个 statusCode 仅用于示例,我可以将它用于任何字段吗?
  • 另外我在 xml 中有超过 10o 个节点,所以这是否意味着我需要创建 100 个持久列?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-24
  • 2016-01-16
  • 2011-09-18
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
相关资源
最近更新 更多