배열 array 분리방법 문의드립니다.

배열 array 분리방법 문의드립니다.

QA

배열 array 분리방법 문의드립니다.

본문

현재 아래와같이 array를 DB에 저장하려고하는데 {n}_test, {n}_date, {n}_date, {n}_desexing는 다른 테이블에 따로 저장하려고하는데 어떻게 하면 좋을지 조언 구해봅니다.. ㅜㅜ

 

* 초록색은 초록색 테이블에, 주황색은 주황색끼리 저장

* _test, _date, _gender, _desexing은 0~n 이 생성될 수 있습니다.

 

Array
(
    [w] => u
    [url] => %2Fbbs%2Fregister_form.php
    [mb_tel] => *** 개인정보보호를 위한 휴대폰번호 노출방지 ***
    [mb_email] => test@test
    [agree] => on
    [agree2] => on
    [0_test] => 이름1
    [0_date] => 2025-02-04
    [0_gender] => male
    [1_test] => 이름2
    [1_date] => 2025-02-05

    [0_gender] => female
    [2_test] => 이름3
    [2_date] => 2025-02-26
    [2_gender] => male
    [2_desexing] => on
)

이 질문에 댓글 쓰기 :

답변 4

다음 코드가 도움이 될지 모르겠습니다.

 


<?php
function array_group_by($arr, $fn) {
    $rv = array();
 
    if (is_callable($fn) == false) {
        return $rv;
    }
 
    array_walk($arr, function ($v, $k) use (&$rv, $fn) {
        $k_new = $fn($v, $k);
        if (isset($rv[$k_new]) == false) {
            $rv[$k_new] = array();
        }
        $rv[$k_new][$k] = $v;
    });
 
    return $rv;
}
 
$data = array(
    'w' => 'u',
    'url' => '%2Fbbs%2Fregister_form.php',
    'mb_tel' => '*** 개인정보보호를 위한 휴대폰번호 노출방지 ***',
    'mb_email' => 'test@test',
    'agree' => 'on',
    'agree2' => 'on',
    '0_test' => '이름1',
    '0_date' => '2025-02-04',
    '0_gender' => 'male',
    '1_test' => '이름2',
    '1_date' => '2025-02-05',
    '0_gender' => 'female',
    '2_test' => '이름3',
    '2_date' => '2025-02-26',
    '2_gender' => 'male',
    '2_desexing' => 'on',
);
 
$data_00 = array_group_by($data, function ($v, $k) {
    if (preg_match('/^\d+_/', $k) === 1) {
        return 'group_b';
    } else {
        return 'group_a';
    }
});
 
$data_01 = array_group_by($data, function ($v, $k) {
    $check = preg_match('/^(\d+)_/', $k, $tmp);
    if ($check === 1) {
        return 'group_' . $tmp[1];
    } else {
        return 'group_a';
    }
});

print_r($data);
/*
Array
(
    [w] => u
    [url] => %2Fbbs%2Fregister_form.php
    [mb_tel] => *** 개인정보보호를 위한 휴대폰번호 노출방지 ***
    [mb_email] => test@test
    [agree] => on
    [agree2] => on
    [0_test] => 이름1
    [0_date] => 2025-02-04
    [0_gender] => female
    [1_test] => 이름2
    [1_date] => 2025-02-05
    [2_test] => 이름3
    [2_date] => 2025-02-26
    [2_gender] => male
    [2_desexing] => on
)
*/

print_r($data_00);
/*
Array
(
    [group_a] => Array
        (
            [w] => u
            [url] => %2Fbbs%2Fregister_form.php
            [mb_tel] => *** 개인정보보호를 위한 휴대폰번호 노출방지 ***
            [mb_email] => test@test
            [agree] => on
            [agree2] => on
        )
    [group_b] => Array
        (
            [0_test] => 이름1
            [0_date] => 2025-02-04
            [0_gender] => female
            [1_test] => 이름2
            [1_date] => 2025-02-05
            [2_test] => 이름3
            [2_date] => 2025-02-26
            [2_gender] => male
            [2_desexing] => on
        )
)
*/
 
print_r($data_01);
/*
Array
(
    [group_a] => Array
        (
            [w] => u
            [url] => %2Fbbs%2Fregister_form.php
            [mb_tel] => *** 개인정보보호를 위한 휴대폰번호 노출방지 ***
            [mb_email] => test@test
            [agree] => on
            [agree2] => on
        )
    [group_0] => Array
        (
            [0_test] => 이름1
            [0_date] => 2025-02-04
            [0_gender] => female
        )
    [group_1] => Array
        (
            [1_test] => 이름2
            [1_date] => 2025-02-05
        )
    [group_2] => Array
        (
            [2_test] => 이름3
            [2_date] => 2025-02-26
            [2_gender] => male
            [2_desexing] => on
        )
)
*/
?>

배열 데이터를 효율적으로 DB에 저장하기 위해,

기본 사용자 정보를 저장하는 user_info 테이블과

개별 데이터를 저장하는 user_details 테이블을 설계하여 1:N 관계를 형성.

user_info 테이블에는 w, url, mb_tel, mb_email, agree, agree2 등의 기본 정보를 저장하고,

user_details 테이블에는 test_name, test_date, gender, desexing 등의 가변 데이터를 저장하며,

각 데이터는 user_info의 id를 참조하여 연결된다. 데이터 저장 시,

먼저 user_info 테이블에 기본 정보를 삽입한 후

생성된 id 값을 활용해 숫자가 포함된 키(0_test, 1_test 등)를 개별 행으로 변환하여

user_details 테이블에 저장하는 방식이 적절해 보임.

*초록색 테이블 → 기본 사용자 정보를 저장하는 테이블

CREATE TABLE user_info (
    id INT PRIMARY KEY AUTO_INCREMENT,
    w VARCHAR(10),
    url TEXT,
    mb_tel VARCHAR(20),
    mb_email VARCHAR(50),
    agree BOOLEAN,
    agree2 BOOLEAN
);

*주황색 테이블 → 개별 데이터를 저장하는 테이블 (user_info와 1:N 관계)

CREATE TABLE user_details (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT,
    test_name VARCHAR(50),
    test_date DATE,
    gender ENUM('male', 'female'),
    desexing BOOLEAN,
    FOREIGN KEY (user_id) REFERENCES user_info(id)
);

*데이터 분리 및 저장 로직 (PHP/Python 등 활용)

  - 숫자가 포함된 키(0_test, 1_test 등)를 추출하여 개별 데이터로 변환

  - user_info 테이블에 먼저 저장하고 id 값을 받아 user_details에 삽입

 

※ 핵심 코드 (PHP + MySQL)

<?php
// 데이터베이스 연결
$conn = new mysqli("localhost", "user", "password", "database");
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// 예제 데이터
$data = [
    "w" => "u",
    "url" => "/bbs/register_form.php",
    "mb_tel" => "공일공-1234-5678",
    "mb_email" => "test골뱅이test.com",
    "agree" => "on",
    "agree2" => "on",
    "0_test" => "이름1",
    "0_date" => "2025-02-04",
    "0_gender" => "male",
    "1_test" => "이름2",
    "1_date" => "2025-02-05",
    "1_gender" => "female",
    "2_test" => "이름3",
    "2_date" => "2025-02-26",
    "2_gender" => "male",
    "2_desexing" => "on"
];

// user_info 테이블에 기본 정보 삽입
$stmt = $conn->prepare("INSERT INTO user_info (w, url, mb_tel, mb_email, agree, agree2) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bind_param("ssssss", $data["w"], $data["url"], $data["mb_tel"], $data["mb_email"], $data["agree"], $data["agree2"]);
$stmt->execute();
$user_id = $stmt->insert_id;
$stmt->close();

// user_details 테이블에 개별 데이터 삽입
foreach ($data as $key => $value) {
    if (preg_match('/^(\d+)_(test|date|gender|desexing)$/', $key, $matches)) {
        $index = $matches[1];
        $column = $matches[2];

        if (!isset($userDetails[$index])) {
            $userDetails[$index] = ["user_id" => $user_id];
        }
        $userDetails[$index][$column] = $value;
    }
}

// 개별 데이터 저장
$stmt = $conn->prepare("INSERT INTO user_details (user_id, test_name, test_date, gender, desexing) VALUES (?, ?, ?, ?, ?)");
foreach ($userDetails as $details) {
    $stmt->bind_param("issss", $details["user_id"], $details["test"], $details["date"], $details["gender"], $details["desexing"]);
    $stmt->execute();
}
$stmt->close();
$conn->close();

w값이 u라는 것은 insert가 아니라 update를 사용해야하는 것 같은데 조건이 없으니

insert 예는 다음처럼...

어떤 필드에 어느 값을 넣을 것인지 설명이 없으니 필드명과 넘어온 변수명이 같다는 가정하에

굳이 배열에 담을 필요는 없을 듯 하군요

배열에 넣으려면 $qry1, $qry2 대신 $arr1[$key] = $value; $arr2[$key] = $value; 

 

  ksort($_POST);
   $qry1 = $deli1 = $qry2 = $deli2 = '';
    foreach( $_POST as $key=>$value){
       if($key=='w') continue;
       if( $key =='url' ||  $key=='mb_tel' || $key=='mb_email' || $key=='agree' || $key=='agree2' ){
           $qry1.=$deli1. "$key='$value'; $deli1=',';
       }else{ $qry2.=$deli2. "$key='$value'; $deli2=','; }
    }
      sql_query("insert into table1 set $qry1");
      sql_query("insert into table2 set $qry2");

 

 


<?php
// 배열 데이터
$data = [
    'w' => 'u',
    'url' => '%2Fbbs%2Fregister_form.php',
    'mb_tel' => '*** 개인정보보호를 위한 휴대폰번호 노출방지 ***',
    'mb_email' => 'test@test',
    'agree' => 'on',
    'agree2' => 'on',
    '0_test' => '이름1',
    '0_date' => '2025-02-04',
    '0_gender' => 'male',
    '1_test' => '이름2',
    '1_date' => '2025-02-05',
    '1_gender' => 'female',
    '2_test' => '이름3',
    '2_date' => '2025-02-26',
    '2_gender' => 'male',
    '2_desexing' => 'on'
];
// 데이터베이스 연결
$pdo = new PDO("mysql:host=G5_MYSQL_HOST;dbname=G5_MYSQL_DB", G5_MYSQL_USER, G5_MYSQL_PASSWORD);
// 1. 메인 테이블에 데이터 저장
$stmt = $pdo->prepare("
    INSERT INTO users (w, url, mb_tel, mb_email, agree, agree2)
    VALUES (:w, :url, :mb_tel, :mb_email, :agree, :agree2)
");
$stmt->execute([
    ':w' => $data['w'],
    ':url' => $data['url'],
    ':mb_tel' => $data['mb_tel'],
    ':mb_email' => $data['mb_email'],
    ':agree' => ($data['agree'] === 'on') ? 1 : 0,
    ':agree2' => ($data['agree2'] === 'on') ? 1 : 0
]);
$userId = $pdo->lastInsertId(); // 삽입된 user_id 가져오기
// 2. 서브 테이블에 데이터 저장
foreach ($data as $key => $value) {
    if (preg_match('/^(\d+)_(test|date|gender|desexing)$/', $key, $matches)) {
        $index = $matches[1];
        $field = $matches[2];
        // user_details 테이블에 데이터 삽입
        $stmt = $pdo->prepare("
            INSERT INTO user_details (user_id, test, date, gender, desexing)
            VALUES (:user_id, :test, :date, :gender, :desexing)
            ON DUPLICATE KEY UPDATE
            test = VALUES(test), date = VALUES(date), gender = VALUES(gender), desexing = VALUES(desexing)
        ");
        $stmt->execute([
            ':user_id' => $userId,
            ':test' => $data["{$index}_test"] ?? null,
            ':date' => $data["{$index}_date"] ?? null,
            ':gender' => $data["{$index}_gender"] ?? null,
            ':desexing' => ($data["{$index}_desexing"] ?? 'off') === 'on' ? 1 : 0
        ]);
    }
}
답변을 작성하시기 전에 로그인 해주세요.
전체 127,958 | RSS
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT