단일 mysql 필드에 데이터 배열을 저장하는 좋은 방법은 무엇입니까?
또한 mysql 테이블에서 해당 배열을 쿼리하면 배열 형식으로 되 돌리는 좋은 방법은 무엇입니까?
대답을 직렬화하고 직렬화 해제합니까?
답변:
단일 필드에 배열을 저장하는 좋은 방법 은 없습니다 .
관계형 데이터를 검사하고 스키마를 적절하게 변경해야합니다. 이 접근 방식에 대한 참조는 아래 예를 참조하십시오.
배열을 단일 필드에 저장 해야하는 경우 serialize()
및 unserialize()
함수가 트릭을 수행합니다. 그러나 실제 콘텐츠에 대해서는 쿼리를 수행 할 수 없습니다.
직렬화 기능의 대안으로 json_encode()
및 json_decode()
.
다음 배열을 고려하십시오.
$a = array(
1 => array(
'a' => 1,
'b' => 2,
'c' => 3
),
2 => array(
'a' => 1,
'b' => 2,
'c' => 3
),
);
데이터베이스에 저장하려면 다음과 같은 테이블을 만들어야합니다.
$c = mysql_connect($server, $username, $password);
mysql_select_db('test');
$r = mysql_query(
'DROP TABLE IF EXISTS test');
$r = mysql_query(
'CREATE TABLE test (
id INTEGER UNSIGNED NOT NULL,
a INTEGER UNSIGNED NOT NULL,
b INTEGER UNSIGNED NOT NULL,
c INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (id)
)');
레코드로 작업하려면 다음과 같은 쿼리를 수행 할 수 있습니다 (예, 이것은 예입니다.주의하십시오!)
function getTest() {
$ret = array();
$c = connect();
$query = 'SELECT * FROM test';
$r = mysql_query($query,$c);
while ($o = mysql_fetch_array($r,MYSQL_ASSOC)) {
$ret[array_shift($o)] = $o;
}
mysql_close($c);
return $ret;
}
function putTest($t) {
$c = connect();
foreach ($t as $k => $v) {
$query = "INSERT INTO test (id,".
implode(',',array_keys($v)).
") VALUES ($k,".
implode(',',$v).
")";
$r = mysql_query($query,$c);
}
mysql_close($c);
}
putTest($a);
$b = getTest();
이 connect()
함수는 mysql 연결 리소스를 반환합니다.
function connect() {
$c = mysql_connect($server, $username, $password);
mysql_select_db('test');
return $c;
}
일반적으로 예, 직렬화 및 직렬화 해제가 갈 길입니다.
하지만 데이터가 단순한 경우 쉼표로 구분 된 문자열로 저장하는 것이 저장 공간에 더 적합 할 것입니다. 예를 들어 배열이 숫자 목록 일 뿐이라는 것을 알고 있다면 implode / explode를 사용해야합니다. 1,2,3
과 의 차이 a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}
입니다.
그렇지 않은 경우 모든 경우에 대해 직렬화 및 직렬화 해제 작업을 수행하십시오.
DB에 저장하기 위해 어레이 직렬화 / 직렬화 해제
http://php.net/manual/en/function.serialize.php를 방문 하십시오.
PHP 매뉴얼에서 :
페이지의 "반품"을보십시오.
어디에나 저장할 수있는 값의 바이트 스트림 표현을 포함하는 문자열을 반환합니다.
이것은 널 바이트를 포함 할 수있는 2 진 문자열이며 저장 및 처리해야합니다. 예를 들어, serialize () 출력은 일반적으로 CHAR 또는 TEXT 필드가 아닌 데이터베이스의 BLOB 필드에 저장되어야합니다.
참고 : html을 blob에 저장하려면 base64로 인코딩해야합니다. 그렇지 않으면 직렬화 기능이 중단 될 수 있습니다.
인코딩 예 :
$YourSerializedData = base64_encode(serialize($theHTML));
$YourSerializedData
이제 blob에 저장할 준비가되었습니다.
blob에서 데이터를 가져온 후에는 base64_decode를 수행 한 다음 예제 디코딩을 직렬화 해제해야합니다.
$theHTML = unserialize(base64_decode($YourSerializedData));
내가 찾은 가장 좋은 방법은 분리 문자가있는 데이터 문자열로 배열을 저장하는 것입니다.
$array = array("value1", "value2", "value3", "...", "valuen");
$array_data = implode("array_separator", $array);
$query = "INSERT INTO my_tbl_name (id, array_data) VALUES(NULL,'" . $array_data . "');";
그런 다음 간단한 쿼리로 배열에 저장된 데이터를 검색 할 수 있습니다.
$query = "SELECT * FROM my_tbl_name WHERE array_data LIKE '%value3%'";
explode () 함수를 사용하여 "array_data"문자열을 배열로 변환
$array = explode("array_separator", $array_data);
이것은 다차원 배열에서 작동하지 않으며 "array_separator"가 고유하고 배열 값에 존재하지 않았는지 확인하십시오.
조심해 !!! 양식 데이터를 가져 와서 데이터베이스에 넣으면 양식 데이터가 SQL에 안전하지 않기 때문에 함정에 빠질 것입니다! mysql_real_escape_string 을 사용하거나 MySQLi mysqli :: real_escape_string을 사용 하거나 값이 정수 또는 부울 캐스트 (int) (부울) 인 경우 양식 값을 처리해야 합니다.
$number = (int)$_POST['number'];
$checked = (boolean) $_POST['checked'];
$name = mysql_real_escape_string($db_pt, $_POST['name']);
$email = mysqli_obj->real_escape_string($_POST['email']);
앞서 언급했듯이-배열 내에서 데이터를 검색 할 필요가없는 경우 직렬화를 사용할 수 있지만 이것은 "php 전용"입니다. 따라서 성능뿐만 아니라 가독성과 이식성 을 위해 json_decode / json_encode 를 사용하는 것이 좋습니다 (JavaScript와 같은 다른 언어는 json_encoded 데이터를 처리 할 수 있음).
어, 모든 사람들이 어레이 직렬화를 제안하는 이유를 모르겠습니다.
가장 좋은 방법은 실제로 데이터베이스 스키마에 맞추는 것입니다. 배열에있는 데이터의 실제 의미 론적 의미에 대해 전혀 알지 못합니다 (단서도 제공하지 않음).하지만 일반적으로 이와 같은 시퀀스를 저장하는 두 가지 방법이 있습니다.
create table mydata (
id int not null auto_increment primary key,
field1 int not null,
field2 int not null,
...
fieldN int not null
)
이런 식으로 배열을 단일 행에 저장합니다.
create table mydata (
id int not null auto_increment primary key,
...
)
create table myotherdata (
id int not null auto_increment primary key,
mydata_id int not null,
sequence int not null,
data int not null
)
첫 번째 방법의 단점은 분명히 배열에 많은 항목이있는 경우 해당 테이블로 작업하는 것이 가장 우아하지 않다는 것입니다. 가변 길이의 시퀀스로 작업하는 것도 비실용적입니다 (가능하지만 매우 부적절합니다. 열을 nullable로 설정).
두 번째 방법의 경우 길이에 상관없이 한 가지 유형의 시퀀스를 가질 수 있습니다. 물론 하나의 유형을 varchar 또는 다른 유형으로 만들고 배열의 항목을 직렬화 할 수 있습니다. 최선의 방법은 아니지만 전체 배열을 직렬화하는 것보다 확실히 낫습니다.
어느 쪽이든,이 메서드는 시퀀스의 임의의 요소에 액세스 할 수 있다는 분명한 이점을 얻습니다. 배열 직렬화 및 그와 같은 추악한 일에 대해 걱정할 필요가 없습니다.
그것을 되 찾는 것에 관해서. 글쎄, 질의로 적절한 행 / 시퀀스를 얻고 루프를 사용하라 .. 맞지?
배열을 json으로 저장할 수 있습니다.
json 데이터 유형에 대한 문서가 있습니다. https://dev.mysql.com/doc/refman/5.7/en/json.html
이것이 최상의 솔루션이라고 생각하며 미친 기능을 피하여 코드를 더 읽기 쉽게 유지하는 데 도움이 될 것입니다. .
나는 이것이 당신에게 도움이 될 것으로 기대합니다.
개별 배열 항목에 포함되지 않을 것으로 알고있는 문자로 implode / explode를 사용하는 것이 좋습니다. 그런 다음 SQL에 문자열로 저장하십시오.
implode 함수를 확인하십시오. 값이 배열에 있으므로 배열의 값을 테이블에 삽입하는 mysql 쿼리에 넣으려고합니다.
$query = "INSERT INto hardware (specifications) VALUES (".implode(",",$specifications).")";
배열의 값이 텍스트 값이면 따옴표를 추가해야합니다.
$query = "INSERT INto hardware (specifications) VALUES ("'.implode("','",$specifications)."')";
mysql_query($query);
또한 중복 값을 원하지 않는 경우 "INto"를 "IGNORE"로 전환하면 고유 한 값만 테이블에 삽입됩니다.
데이터베이스에 저장하는 대신 파일에 저장 한 다음 나중에 호출하십시오.
많은 PHP 앱 (예 : sugarcrm)은 var_export를 사용하여 배열의 모든 데이터를 파일에 에코하는 것입니다. 이것은 내 구성 데이터를 저장하는 데 사용하는 것입니다.
private function saveConfig() {
file_put_contents($this->_data['pathtocompileddata'],'<?php' . PHP_EOL . '$acs_confdata = ' . var_export($this->_data,true) . ';');
}
이것이 데이터를 저장하는 더 좋은 방법이라고 생각합니다!