วิธีที่ดีในการบันทึกอาร์เรย์ของข้อมูลลงในฟิลด์ mysql เดียวคืออะไร?
นอกจากนี้เมื่อฉันค้นหาอาร์เรย์นั้นในตาราง mysql วิธีที่ดีในการทำให้อาร์เรย์กลับมาอยู่ในรูปแบบอาร์เรย์คืออะไร?
เป็นซีเรียลไลซ์และยกเลิกการเข้ารหัสคำตอบหรือไม่
วิธีที่ดีในการบันทึกอาร์เรย์ของข้อมูลลงในฟิลด์ mysql เดียวคืออะไร?
นอกจากนี้เมื่อฉันค้นหาอาร์เรย์นั้นในตาราง mysql วิธีที่ดีในการทำให้อาร์เรย์กลับมาอยู่ในรูปแบบอาร์เรย์คืออะไร?
เป็นซีเรียลไลซ์และยกเลิกการเข้ารหัสคำตอบหรือไม่
คำตอบ:
ไม่มีวิธีที่ดีในการจัดเก็บอาร์เรย์ลงในฟิลด์เดียว
คุณต้องตรวจสอบข้อมูลเชิงสัมพันธ์ของคุณและทำการเปลี่ยนแปลงที่เหมาะสมกับสคีมาของคุณ ดูตัวอย่างด้านล่างสำหรับการอ้างอิงถึงแนวทางนี้
หากคุณต้องบันทึกอาร์เรย์ลงในช่องเดียวฟังก์ชันserialize()
and 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;
}
โดยทั่วไปแล้วการทำให้เป็นซีเรียลไลซ์และการยกเลิกการเข้ารหัสเป็นวิธีที่จะไป
หากข้อมูลของคุณเป็นแบบธรรมดาการบันทึกเป็นสตริงที่คั่นด้วยจุลภาคน่าจะดีกว่าสำหรับพื้นที่จัดเก็บ หากคุณรู้ว่าอาร์เรย์ของคุณจะเป็นเพียงรายการตัวเลขคุณควรใช้การระเบิด / ระเบิด มันคือความแตกต่างระหว่าง1,2,3
และa:3:{i:0;i:1;i:1;i:2;i:2;i:3;}
และ
ถ้าไม่เช่นนั้นให้ทำให้เป็นอนุกรมและยกเลิกการเข้ารหัสสำหรับทุกกรณี
เพียงใช้ฟังก์ชัน PHP แบบอนุกรม:
<?php
$myArray = array('1', '2');
$seralizedArray = serialize($myArray);
?>
อย่างไรก็ตามหากคุณใช้อาร์เรย์แบบธรรมดาเช่นนั้นคุณอาจใช้การระเบิดและการระเบิดได้เช่นกันใช้อาร์เรย์ว่างแทนใหม่
Serialize / Unserialize array สำหรับการจัดเก็บใน DB
ไปที่http://php.net/manual/en/function.serialize.php
จากคู่มือ PHP:
ดูใต้ "Return" บนหน้า
ส่งคืนสตริงที่มีการแสดงค่าไบต์สตรีมที่สามารถเก็บไว้ที่ใดก็ได้
โปรดทราบว่านี่เป็นสตริงไบนารีซึ่งอาจมีไบต์ว่างและจำเป็นต้องจัดเก็บและจัดการเช่นนี้ ตัวอย่างเช่นโดยทั่วไปเอาต์พุต serialize () ควรถูกเก็บไว้ในฟิลด์ BLOB ในฐานข้อมูลแทนที่จะเป็นฟิลด์ CHAR หรือ TEXT
หมายเหตุ: หากคุณต้องการจัดเก็บ html ลงในหยดตรวจสอบให้แน่ใจว่าได้เข้ารหัส base64 ไม่เช่นนั้นอาจทำให้ฟังก์ชันซีเรียลไลซ์เสียหายได้
ตัวอย่างการเข้ารหัส:
$YourSerializedData = base64_encode(serialize($theHTML));
$YourSerializedData
ตอนนี้พร้อมที่จะเก็บไว้ในหยดแล้ว
หลังจากรับข้อมูลจาก 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 หรือถ้าค่าเป็นจำนวนเต็มหรือบูลีน cast (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']);
การทำให้เป็นอนุกรมและการยกเลิกการเข้ารหัสเป็นเรื่องปกติสำหรับสิ่งนั้น คุณยังสามารถใช้ JSON ผ่าน json_encode และ json_decode สำหรับรูปแบบเฉพาะ PHP ที่น้อยลง
ดังที่กล่าวไว้ก่อนหน้านี้ - หากคุณไม่ต้องการค้นหาข้อมูลภายในอาร์เรย์คุณสามารถใช้ serialize ได้ แต่เป็น "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
)
ข้อเสียของวิธีแรกคือเห็นได้ชัดว่าหากคุณมีหลายรายการในอาร์เรย์การทำงานกับตารางนั้นจะไม่ใช่สิ่งที่หรูหราที่สุด นอกจากนี้ยังทำไม่ได้ (เป็นไปได้ แต่ก็ค่อนข้างไม่ดีเช่นกัน - เพียงแค่ทำให้คอลัมน์เป็นโมฆะ) เพื่อทำงานกับลำดับความยาวตัวแปร
สำหรับวิธีที่สองคุณสามารถมีลำดับความยาวเท่าใดก็ได้ แต่จะมีเพียงประเภทเดียวเท่านั้น แน่นอนคุณสามารถสร้าง varchar ประเภทหนึ่งหรืออะไรก็ได้และทำให้เป็นลำดับรายการของอาร์เรย์ของคุณ ไม่ใช่สิ่งที่ดีที่สุดที่จะทำ แต่ดีกว่าการจัดลำดับอาร์เรย์ทั้งหมดใช่ไหม?
ไม่ว่าจะด้วยวิธีใดวิธีการใดก็ได้รับประโยชน์อย่างชัดเจนในการเข้าถึงองค์ประกอบของลำดับโดยพลการและคุณไม่ต้องกังวลเกี่ยวกับการจัดลำดับอาร์เรย์และสิ่งที่น่าเกลียดเช่นนั้น
สำหรับการกลับมา เอาแถว / ลำดับของแถวที่เหมาะสมพร้อมคิวรีและใช้ลูป .. ใช่ไหม?
คุณสามารถบันทึกอาร์เรย์ของคุณเป็น json
มีเอกสารสำหรับประเภทข้อมูล json: https://dev.mysql.com/doc/refman/5.7/en/json.html
ฉันคิดว่านี่เป็นทางออกที่ดีที่สุดและจะช่วยให้คุณรักษาโค้ดให้อ่านง่ายขึ้นโดยหลีกเลี่ยงฟังก์ชั่นที่บ้าคลั่ง .
ฉันคาดว่านี่จะเป็นประโยชน์สำหรับคุณ
ใช่ซีเรียลไลซ์ / ยกเลิกการเข้ารหัสเป็นสิ่งที่ฉันเห็นมากที่สุดในโครงการโอเพ่นซอร์สมากมาย
ฉันขอแนะนำให้ใช้การระเบิด / ระเบิดด้วยอักขระที่คุณรู้ว่าจะไม่มีอยู่ในรายการอาร์เรย์ใด ๆ จากนั้นเก็บไว้ใน SQL เป็นสตริง
ตรวจสอบฟังก์ชั่นการระเบิดเนื่องจากค่าอยู่ในอาร์เรย์คุณต้องการใส่ค่าของอาร์เรย์ลงในแบบสอบถาม mysql ที่แทรกค่าลงในตาราง
$query = "INSERT INto hardware (specifications) VALUES (".implode(",",$specifications).")";
หากค่าในอาร์เรย์เป็นค่าข้อความคุณจะต้องเพิ่มเครื่องหมายคำพูด
$query = "INSERT INto hardware (specifications) VALUES ("'.implode("','",$specifications)."')";
mysql_query($query);
นอกจากนี้หากคุณไม่ต้องการให้ค่าซ้ำกันให้เปลี่ยน "INto" เป็น "IGNORE" และจะมีการแทรกเฉพาะค่าที่ไม่ซ้ำกันลงในตาราง
คุณสามารถแทรกอ็อบเจ็กต์ซีเรียลserialize($object)
ไลซ์(อาร์เรย์) ไปยัง mysql ตัวอย่างและคุณสามารถยกเลิกการกำหนดขนาดอ็อบเจกต์ได้unserialize($object)
แทนที่จะบันทึกลงในฐานข้อมูลให้บันทึกลงในไฟล์แล้วเรียกใช้ในภายหลัง
แอป php จำนวนมากทำอะไร (เช่น sugarcrm) คือใช้ var_export เพื่อสะท้อนข้อมูลทั้งหมดของอาร์เรย์ไปยังไฟล์ นี่คือสิ่งที่ฉันใช้เพื่อบันทึกข้อมูลการกำหนดค่าของฉัน:
private function saveConfig() {
file_put_contents($this->_data['pathtocompileddata'],'<?php' . PHP_EOL . '$acs_confdata = ' . var_export($this->_data,true) . ';');
}
ฉันคิดว่านี่เป็นวิธีที่ดีกว่าในการบันทึกข้อมูลของคุณ!