举杯邀月

一次mysql表拆分字段的填坑记录,将一个字段的内容按规则拆分到另一个表里

摘要:公司原来有一个“大牛”做了一个站点,将详情页的描述信息直接写到了一个字段了,前台调取通过正则匹配的方法展示不同的标题。现在站点改版,要讲这一个字段的内容拆分出来放到关联表里。

公司原来有一个“大牛”做了一个站点,将详情页的描述信息直接写到了一个字段了,前台调取通过正则匹配的方法展示不同的标题。现在站点改版,要讲这一个字段的内容拆分出来放到关联表里。

要知道 mysql 数据分表也算是优化查询的一种,如果是渲染页面,按前台的分布进行数据的分表,比如正常的页面分为首页、列表、详情页。那么数据怎么分表呢?

首先根据页面,首页、列表展示的基本是标题、缩略图、分类、时间的等内容,但是详情页要展示详情的富文本内容,那么就可以把标题、缩略图、分类、时间的等字段放到一个表,将详情内容放到一个单独的表,要知道详情的字段值一般都是 text 类型,如果全放一个表里,数据量大了之后会影响查询性能。

而这次遇到的问题就是全放到了一张表了,那么可能要说了,直接写sql查询进行更新拆分出来不就可以了么,按正常的是没有问题,但是数据的详情不止一种类型:

详情的展示分为:详情、优势、流程等几大块。分表应该是:

id 详情 优势 流程 ……
1 详情内容 优势内容 流程内容 ……
2 详情内容 优势内容 流程内容 ……

但现在的情况是:

id 内容 ……
1 详情内容、优势内容、 流程内容 ……
1 详情内容、优势内容、 流程内容 ……

而且经过观察,他的标题标签还有不一样的,有的是 h2 标签,有的是 p 套的 span 标签,详情的描述本身就是富文本类型,所以只能通过正则匹配去拆分。

//过滤内容
$content = str_replace(array("\r\n", "\r", "\n"), "", $content);
//匹配内容与标题
$contRes = preg_split("/\/", $content);
preg_match_all("/\(.*?)<\/h2\>/", $content, $titleRes);
if(count($contRes) && isset($titleRes[0])){
    // 将内容为空的值去除
    foreach ($contRes as $k => $v){
        if(empty($v) || $v=='
'
) unset($contRes[$k]); } $contRes = array_values($contRes); $title = []; foreach ($titleRes[0] as $v){ preg_match("/\(.*?)\<\/font\>/", $v, $resT); if(empty($resT)){ preg_match("/\.*?\.*?\(.*?)\<\/span\>\<\/span\>/", $v, $resT); }elseif(strstr($resT[1], 'font')){ preg_match("/\(.*?)\<\/font\>\<\/font\>/", $v, $resT); } if(empty($resT)){ preg_match("/\(.*?)\<\/span\>/", $v, $resT); } if(isset($resT[1]) && (empty($resT[1]) || strstr($resT[1], 'span'))){ preg_match("/\\\(.*?)\<\/span\>/", $v, $resT); } // 判断匹配结果并保存 if(isset($resT[1])){ $title[] = $resT[1]; } } if(count($title) != count($contRes)){ //匹配异常,标题与内容对应不上 $msg = '长度不一致'; }else{ //保存数据 结果类型 // $title = ['详情', '优势', ……] // $contRes = ['详情内容', '优势内容', ……] }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

其实这只是一小部分,由于内容的格式太过于“丰富”,然后就判断标签写了各种正则进行匹配,最终将一万三千条数据匹配分离出来了刚不到一万条,剩下的因为内容太乱只能人工去分派了。

不过这一天的正则没有白写,结果虽然不是百分百,但是也不可忽略,如果人工去拆分这一万条数据……

这个事情也收获了很多的东西,首先是技术上的,写了这一天的正则,对正则也是有了更加深入的理解,然后也用到了一个原来没有用过的php方法 preg_split,这个方法是用正则匹配然后切割字符串,跟 explode 方法类似,只是一个是使用字符串一个是使用正则。

另外,也悟到了另一个点,就是在做项目的时候,mysql、站点模块配置等一定要提前规划好,哪怕是要花费点时间,不然项目一但上线,再想去改结构,是很费劲的一件事。

作者:举杯邀月

出处: http://www.hug-code.cn/archives/5fc711a3ca9fe.html

2020-08-03 标签: phpmysql