首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用PHP循环或MySQL重构坏数据库

使用PHP循环或MySQL重构坏数据库
EN

Stack Overflow用户
提问于 2017-10-23 21:30:16
回答 1查看 238关注 0票数 0

我有一个PHP项目的特殊情况,在这个项目中,我正在处理一个没有第三范式结构的数据库。该数据库仅包含1个表,其中包含多个列。一些本应在单独的表中的数据被夹在1列中,并由某个符号(在本例中为分号";")分隔。

还有其他列,在这些列中,钳制的数据应该移动到前面提到的同一个分离的表中。这一定很让人困惑,所以让我来详细说明:

代码语言:javascript
复制
**HugeTable**
id |  Column1      |  Column2     |  Column3

123 |数据1;数据2数据3;数据4数据5;数据6

我需要将上面的数据放在一个单独的表中,如下所示:

代码语言:javascript
复制
**NewTable**
id   |  idHugeTable  |  Column1  |  Column2  |  Column3
 1   |  123          |  Data1    |  Data3    |  Data5
 2   |  123          |  Data2    |  Data4    |  Data6

因此,对于大表中的每个被钳制的数据,我需要在新表中创建一个新行。这个过程将帮助我规范化数据库,使其至少是可行的。现在这是一场噩梦。这需要通过PHP或MySQL来完成,最好是PHP,因为循环更容易通过脚本语言在每个循环中执行一次查询。

编辑:我在PHP中尝试过的示例代码:

代码语言:javascript
复制
$delimiter = ";";
$query = "SELECT * FROM HugeTable";

$result = mysqli_query($connection_var, $query);

while ($row = mysqli_fetch_assoc()){
    $column1_data = explode($delimiter, $row['Column1']);
    $column2_data = explode($delimiter, $row['Column2']);
    $column3_data = explode($delimiter, $row['Column3']);

    foreach ($column1_data as $key => $value){
        //skip if empty value
        if ($value == ""){
            continue;
        }
        else{
            $query_ins = "INSERT INTO NewTable (idHugeTable, Column1, Column2, Column3) VALUES (".$row['id'].", ".$column1_data[$key].", ".$column2_data[$key].", ".$column3_data[$key].");";
            mysqli_query($connection_var, $query_ins);
        }//end if
    }//end foreach
}//end while

mysqli_close($connection_var);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-23 22:41:34

不需要PHP。您只能使用纯MySQL代码来完成此任务。

创建表格/插入表格

代码语言:javascript
复制
CREATE TABLE HugeTable
    (`Column1` VARCHAR(11), `Column2` VARCHAR(11), `Column3` VARCHAR(11))
;

INSERT INTO HugeTable
    (`Column1`, `Column2`, `Column3`)
VALUES
    ('Data1;Data2', 'Data3;Data4', 'Data5;Data6')
; 

CREATE TABLE NewTable
   (`Column1` VARCHAR(11), `Column2` VARCHAR(11), `Column3` VARCHAR(11))
;

首先,我们需要MySQL来生成数字。此MySQL代码生成1到100。因此,最终的查询将支持多达100个分隔值。

查询

代码语言:javascript
复制
SELECT 
 @row := @row + 1 AS ROW
FROM (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) row1
CROSS JOIN (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) row2
CROSS JOIN (
  SELECT @row := 0 
) init_user_params 

结果

代码语言:javascript
复制
  row  
--------
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
     ...
     ...
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
     100

现在我们可以看一下在;分隔符上分隔的方法。为此,我们可以使用嵌套的SUBSTRING_INDEX函数

查询

代码语言:javascript
复制
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('Data1;Data2', ';', 1), ';', -1) AS DATA

结果

代码语言:javascript
复制
data    
--------
Data1   

您可以看到,如果我们想要使用第二个单词,则只返回第一个单词

查询

代码语言:javascript
复制
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('Data1;Data2', ';', 2), ';', -1) AS DATA

结果

代码语言:javascript
复制
data    
--------
Data2  

现在,我们结合使用数字生成器和SUBSTRING_INDEX来生成数据

查询

代码语言:javascript
复制
SELECT 
  DISTINCT
   SUBSTRING_INDEX(SUBSTRING_INDEX(Column1, ';', rows.row), ';', -1) Column1
 , SUBSTRING_INDEX(SUBSTRING_INDEX(Column2, ';', rows.row), ';', -1) Column2
 , SUBSTRING_INDEX(SUBSTRING_INDEX(Column3, ';', rows.row), ';', -1) Column3
FROM (
  SELECT 
   @row := @row + 1 AS ROW
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) row1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) row2  
  CROSS JOIN (
    SELECT @row := 0 
  ) init_user_params
)
 ROWS
CROSS JOIN 
 HugeTable 

结果

代码语言:javascript
复制
Column1  Column2  Column3  
-------  -------  ---------
Data1    Data3    Data5    
Data2    Data4    Data6    

Query NewTable

代码语言:javascript
复制
INSERT INTO 
  NewTable
SELECT 
  DISTINCT
   SUBSTRING_INDEX(SUBSTRING_INDEX(Column1, ';', rows.row), ';', -1) Column1
 , SUBSTRING_INDEX(SUBSTRING_INDEX(Column2, ';', rows.row), ';', -1) Column2
 , SUBSTRING_INDEX(SUBSTRING_INDEX(Column3, ';', rows.row), ';', -1) Column3
FROM (
  SELECT 
   @row := @row + 1 AS ROW
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) row1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) row2  
  CROSS JOIN (
    SELECT @row := 0 
  ) init_user_params
)
 ROWS
CROSS JOIN 
 HugeTable 

查询

代码语言:javascript
复制
SELECT * FROM NewTable

结果

代码语言:javascript
复制
Column1  Column2  Column3  
-------  -------  ---------
Data1    Data3    Data5    
Data2    Data4    Data6   
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46890617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档