Cách tốt để lưu một mảng dữ liệu vào một trường mysql duy nhất là gì?
Ngoài ra khi tôi truy vấn mảng đó trong bảng mysql, cách tốt để đưa nó trở lại dạng mảng là gì?
Serialize và unserialize có phải là câu trả lời?
Cách tốt để lưu một mảng dữ liệu vào một trường mysql duy nhất là gì?
Ngoài ra khi tôi truy vấn mảng đó trong bảng mysql, cách tốt để đưa nó trở lại dạng mảng là gì?
Serialize và unserialize có phải là câu trả lời?
Câu trả lời:
Không có cách nào tốt để lưu trữ một mảng vào một trường duy nhất.
Bạn cần kiểm tra dữ liệu quan hệ của mình và thực hiện các thay đổi thích hợp cho lược đồ của mình. Xem ví dụ dưới đây để tham khảo cách tiếp cận này.
Nếu bạn phải lưu mảng vào một trường duy nhất thì hàm serialize()
và unserialize()
sẽ thực hiện thủ thuật. Nhưng bạn không thể thực hiện các truy vấn trên nội dung thực tế.
Để thay thế cho chức năng tuần tự hóa, còn có json_encode()
và json_decode()
.
Hãy xem xét mảng sau
$a = array(
1 => array(
'a' => 1,
'b' => 2,
'c' => 3
),
2 => array(
'a' => 1,
'b' => 2,
'c' => 3
),
);
Để lưu nó trong cơ sở dữ liệu, bạn cần tạo một bảng như thế này
$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)
)');
Để làm việc với các bản ghi, bạn có thể thực hiện các truy vấn như sau (và vâng, đây là một ví dụ, hãy cẩn thận!)
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();
Các connect()
hàm trả về một nguồn tài nguyên kết nối mysql
function connect() {
$c = mysql_connect($server, $username, $password);
mysql_select_db('test');
return $c;
}
Nói chung, có, serialize và unserialize là cách để đi.
Tuy nhiên, nếu dữ liệu của bạn là một cái gì đó đơn giản, lưu dưới dạng một chuỗi được phân tách bằng dấu phẩy có lẽ sẽ tốt hơn cho không gian lưu trữ. Ví dụ: nếu bạn biết rằng mảng của bạn sẽ chỉ là một danh sách các số, thì bạn nên sử dụng implode / boom. Đó là sự khác biệt giữa 1,2,3
và a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}
.
Nếu không, hãy tuần tự hóa và hủy số hóa công việc cho mọi trường hợp.
Serialize / Unserialize mảng để lưu trữ trong DB
Truy cập http://php.net/manual/en/ Chức năng.serialize.php
Từ Hướng dẫn sử dụng PHP:
Xem phần "Quay lại" trên trang
Trả về một chuỗi chứa biểu diễn luồng byte của giá trị có thể được lưu trữ ở bất kỳ đâu.
Lưu ý rằng đây là một chuỗi nhị phân có thể bao gồm các byte rỗng và cần được lưu trữ và xử lý như vậy. Ví dụ: đầu ra serialize () thường phải được lưu trữ trong trường BLOB trong cơ sở dữ liệu, thay vì trường CHAR hoặc TEXT.
Lưu ý: Nếu bạn muốn lưu trữ html thành một blob, hãy đảm bảo mã hóa nó theo base64 nếu không nó có thể phá vỡ chức năng tuần tự hóa.
Mã hóa mẫu:
$YourSerializedData = base64_encode(serialize($theHTML));
$YourSerializedData
hiện đã sẵn sàng để được lưu trữ trong blob.
Sau khi lấy dữ liệu từ blob, bạn cần base64_decode rồi hủy mã hóa Ví dụ giải mã:
$theHTML = unserialize(base64_decode($YourSerializedData));
Cách tốt nhất mà tôi tự tìm ra là lưu mảng dưới dạng chuỗi dữ liệu với các ký tự phân tách
$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 . "');";
Sau đó, bạn có thể tìm kiếm dữ liệu, được lưu trữ trong mảng của mình bằng truy vấn đơn giản
$query = "SELECT * FROM my_tbl_name WHERE array_data LIKE '%value3%'";
sử dụng hàm boom () để chuyển đổi chuỗi "array_data" thành mảng
$array = explode("array_separator", $array_data);
lưu ý rằng điều này không hoạt động với mảng nhiều chiều và đảm bảo rằng "dấu_mảng_mảng" của bạn là duy nhất và không tồn tại trong các giá trị mảng.
Hãy cẩn thận !!! nếu bạn chỉ lấy một dữ liệu biểu mẫu và đưa vào cơ sở dữ liệu, bạn sẽ mắc bẫy, dữ liệu biểu mẫu không an toàn với SQL! bạn phải xử lý giá trị biểu mẫu của mình với mysql_real_escape_string hoặc nếu bạn sử dụng MySQLi mysqli :: real_escape_string hoặc nếu giá trị là số nguyên hoặc kiểu ép kiểu boolean (int) (boolean) trên chúng
$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']);
Như đã đề cập trước đây - Nếu bạn không cần tìm kiếm dữ liệu trong mảng, bạn có thể sử dụng serialize - nhưng đây là "chỉ php". Vì vậy, tôi khuyên bạn nên sử dụng json_decode / json_encode - không chỉ cho hiệu suất mà còn cho khả năng đọc và tính di động (các ngôn ngữ khác như javascript có thể xử lý dữ liệu json_encoded).
Uhh, tôi không biết tại sao mọi người đề xuất tuần tự hóa mảng.
Tôi nói, cách tốt nhất là thực sự đưa nó vào lược đồ cơ sở dữ liệu của bạn. Tôi không biết (và bạn không có manh mối nào) về ý nghĩa ngữ nghĩa thực tế của dữ liệu trong mảng của bạn, nhưng nói chung có hai cách lưu trữ chuỗi như vậy
create table mydata (
id int not null auto_increment primary key,
field1 int not null,
field2 int not null,
...
fieldN int not null
)
Bằng cách này, bạn đang lưu trữ mảng của mình trong một hàng duy nhất.
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
)
Nhược điểm của phương pháp đầu tiên rõ ràng là nếu bạn có nhiều mục trong mảng của mình, làm việc với bảng đó sẽ không phải là điều tốt nhất. Nó cũng không thực tế (có thể, nhưng cũng không phù hợp - chỉ làm cho các cột có giá trị rỗng) khi làm việc với các chuỗi có độ dài thay đổi.
Đối với phương pháp thứ hai, bạn có thể có các chuỗi có độ dài bất kỳ, nhưng chỉ có một loại. Tất nhiên, bạn có thể tạo một kiểu varchar hoặc một cái gì đó và tuần tự hóa các mục trong mảng của bạn. Không phải là điều tốt nhất để làm, nhưng chắc chắn tốt hơn, so với việc tuần tự hóa toàn bộ mảng, phải không?
Dù bằng cách nào, bất kỳ phương pháp nào trong số này đều có lợi thế rõ ràng là có thể truy cập vào một phần tử tùy ý của chuỗi và bạn không phải lo lắng về việc sắp xếp các mảng và những thứ xấu xí như vậy.
Đối với việc lấy lại nó. Chà, lấy hàng / chuỗi hàng thích hợp với một truy vấn và, tốt, sử dụng một vòng lặp .. phải không?
Bạn có thể lưu mảng của mình dưới dạng json.
có tài liệu về kiểu dữ liệu json: https://dev.mysql.com/doc/refman/5.7/vi/json.html
Tôi nghĩ đây là giải pháp tốt nhất và sẽ giúp bạn duy trì mã của mình dễ đọc hơn bằng cách tránh các hàm điên rồ .
Tôi hy vọng điều này sẽ hữu ích cho bạn.
Tôi sẽ đề xuất sử dụng implode / boom với một ký tự mà bạn biết sẽ không có trong bất kỳ mục mảng riêng lẻ nào. Sau đó, lưu trữ nó trong SQL dưới dạng một chuỗi.
hãy kiểm tra hàm implode, vì các giá trị nằm trong một mảng, bạn muốn đặt các giá trị của mảng vào một truy vấn mysql chèn các giá trị vào một bảng.
$query = "INSERT INto hardware (specifications) VALUES (".implode(",",$specifications).")";
Nếu các giá trị trong mảng là giá trị văn bản, bạn sẽ cần thêm dấu ngoặc kép
$query = "INSERT INto hardware (specifications) VALUES ("'.implode("','",$specifications)."')";
mysql_query($query);
Ngoài ra, nếu bạn không muốn các giá trị trùng lặp, hãy chuyển "INto" thành "BỎ QUA" và chỉ các giá trị duy nhất mới được chèn vào bảng.
bạn có thể chèn đối tượng tuần tự hóa (mảng) vào mysql, ví dụ serialize($object)
và bạn có thể hủy mã hóa ví dụ đối tượngunserialize($object)
Thay vì lưu nó vào cơ sở dữ liệu, hãy lưu nó vào một tệp và sau đó gọi nó sau.
Những gì nhiều ứng dụng php làm (như sugarcrm) là chỉ sử dụng var_export để lặp lại tất cả dữ liệu của mảng vào một tệp. Đây là những gì tôi sử dụng để lưu dữ liệu cấu hình của mình:
private function saveConfig() {
file_put_contents($this->_data['pathtocompileddata'],'<?php' . PHP_EOL . '$acs_confdata = ' . var_export($this->_data,true) . ';');
}
Tôi nghĩ đây là cách tốt hơn để lưu dữ liệu của bạn!