我在一个PHP项目中有一个特例,在该项目中我正在使用没有第三范式结构的数据库。该数据库仅包含1个表,其中包含许多列。某些应该在单独的表中的数据被限制在1列中,并以某个符号(在本例中为分号“;”)分隔。
在其他列中,应将钳位数据移至与上述相同的单独表中。这一定很令人困惑,所以让我详细说明一下:
**HugeTable** id | Column1 | Column2 | Column3
123 | 数据1;数据2数据3;数据4数据5;数据6
我需要将上面的数据放在一个单独的表中,如下所示:
**NewTable** id | idHugeTable | Column1 | Column2 | Column3 1 | 123 | Data1 | Data3 | Data5 2 | 123 | Data2 | Data4 | Data6
因此,对于巨大表中的每个固定数据,我需要在新表中新建一行。这个过程将帮助我规范化数据库,以便至少可以使用。现在是一场噩梦。这需要通过PHP或MySQL来完成,最好是PHP,因为通过脚本语言对每个循环的一次性查询而言,循环更容易。
编辑:我在PHP中尝试过的示例代码:
$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);
不需要PHP。您只能使用纯MySQL代码执行此操作。
创建表/插入表
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个分隔的值。
询问
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
结果
row -------- 1 2 3 4 5 6 7 8 9 10 ... ... 90 91 92 93 94 95 96 97 98 99 100
现在我们可以看看在上分开的方法;定界符。我们可以为此使用嵌套的SUBSTRING_INDEX函数
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('Data1;Data2', ';', 1), ';', -1) AS DATA
data -------- Data1
如果我们希望我们可以使用第二个单词,则只能看到第一个单词被返回
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('Data1;Data2', ';', 2), ';', -1) AS DATA
data -------- Data2
现在我们结合数字生成器和SUBSTRING_INDEX来生成数据
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
Column1 Column2 Column3 ------- ------- --------- Data1 Data3 Data5 Data2 Data4 Data6
查询新表
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
SELECT * FROM NewTable