Який хороший спосіб зберегти масив даних в одному полі 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;
}
Як правило, так, серіалізація та несеріалізація - це шлях.
Якщо ваші дані щось просте, збереження у вигляді рядка, розділеного комами, можливо, було б кращим для місця для зберігання. Якщо ви знаєте, що ваш масив буде просто списком чисел, наприклад, тоді вам слід використовувати implode / explode. Це різниця між 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);
?>
Однак, якщо ви використовуєте прості масиви, подібні до цього, ви також можете використовувати implode і explode. Використовуйте порожній масив замість нового.
Серіалізувати / десеріалізувати масив для зберігання в БД
Відвідайте http://php.net/manual/en/function.serialize.php
З Посібника PHP:
Подивіться на "Повернення" на сторінці
Повертає рядок, що містить подання байтового потоку значення, яке можна зберігати де завгодно.
Зверніть увагу, що це двійковий рядок, який може містити нульові байти, і його потрібно зберігати та обробляти як такий. Наприклад, вихід serialize () зазвичай повинен зберігатися в полі BLOB у базі даних, а не в полі CHAR або TEXT.
Примітка: Якщо ви хочете зберегти 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) (boolean) до них
$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
)
Недоліком першого методу є, очевидно, те, що якщо у вас є багато елементів у вашому масиві, робота з цією таблицею буде не найелегантнішою річчю. Також непрактично (можливо, але також досить неелегантно - просто зробіть стовпчики нульовими) працювати з послідовностями змінної довжини.
Для другого методу ви можете мати послідовності будь-якої довжини, але лише одного типу. Ви, звичайно, можете зробити такий тип 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", і в таблицю будуть вставлені лише унікальні значення.
ви можете вставити серіалізований об'єкт (масив) у mysql, наприклад, serialize($object)
і ви можете скасувати серіалізацію прикладу об'єкта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) . ';');
}
Я думаю, що це кращий спосіб зберегти ваші дані!