Много-ко-многим вставить запрос с помощью PHP/mysqli
У меня есть база данных с таблицей ссылок на видео YouTube, таблицей списков воспроизведения и соединительной таблицей, связывающей их в отношениях "многие ко многим". Я пытался создать функцию PHP/mysqli, которая добавляет ссылку на видео YouTube в таблицу 'vids' и идентификатор списка воспроизведения и идентификатор видео в таблицу соединений. Если видео уже находится в таблице vids, я хочу, чтобы оно получило идентификатор, в противном случае вставьте его и используйте что-то вроде mysqli_stmt_insert_id для возврата нового идентификатора.
Я переписывал его десятки раз, используя различные функции mysqli, и не могу заставить его работать. Это для приложения Flex, и я не очень разбираюсь в PHP или mysqli, но прибегнул к разбиению его на 3 более простых функции и обнаружил, что он все равно не будет работать.
Изменить: я удалил код, который я опубликовал, потому что он даже не был близок к правильности.
Конечно, это должно быть намного проще, чем это! Может кто-нибудь объяснить это или рекомендовать функцию / учебник / пример, чтобы помочь, пожалуйста? До сих пор я потратил 6 дней, пытаясь расшифровать документацию php.net, и теперь задаюсь вопросом, способна ли mysqli вставлять отношения "многие ко многим". Благодарю.
1 ответ
Наконец нашел способ сделать это, и это должно быть сделано с несколькими запросами.
Таблицы настроены таким образом, что при вводе новой ссылки на видео YouTube в таблицу vids он получает автоинкремент vid_id. Соединительная таблица, list_vid_junc, является MyISAM и имеет 3 столбца: list_id, vid_id и sort. Первичный ключ состоит из list_id и sort, с сортировкой, установленной на autoincrement. Это позволяет несколько записей одного и того же видео в списке, которые могут быть отсортированы по автоинкременту сортировки.
Обратите внимание, что в таблице MyISAM, поскольку индекс первичного ключа разделяется таким образом, mySql начинает автоинкремент сортировки с 1 для каждого нового создаваемого списка, а не делает каждую сортировку уникальным числом, см. http://dev.mysql.com/doc/refman/5.5/en/example-auto-increment.html. Список 1 может содержать идентификаторы сортировки 1,2,3, а список 2 также может иметь идентификаторы сортировки 1,2,3. Пары являются уникальными, а не индивидуальными номерами.
Это не производственная версия, а просто базовое решение:
class DbService {
var $username = "user";
var $password = "password";
var $server = "localhost";
var $port = "3306";
var $databasename = "database";
var $connection;
public function __construct() {
$this->connection = mysqli_connect(
$this->server,
$this->username,
$this->password,
$this->databasename,
$this->port
);
$this->throwExceptionOnError($this->connection);
}
// returns array of (vidID, sort); adds duplicate vids to list if run 2+ times
public function addToPlaylist($ytRef, $listID) {
$stmt = mysqli_prepare($this->connection, "INSERT IGNORE INTO vids(yt_ref) VALUES (?)");
mysqli_bind_param($stmt, 's', $ytRef);
mysqli_stmt_execute($stmt);
$vidID = mysqli_stmt_insert_id($stmt); // 0 if video already exists
mysqli_stmt_free_result($stmt);
if ($vidID == 0) {
$stmt = mysqli_prepare($this->connection, "SELECT vid_id FROM vids WHERE yt_ref = ? LIMIT 1");
mysqli_bind_param($stmt, 's', $ytRef);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $vidID);
mysqli_stmt_fetch($stmt);
mysqli_stmt_free_result($stmt);
}
$stmt = mysqli_prepare($this->connection, "INSERT IGNORE INTO fr_list_vid_junc(vid_id, list_id) VALUES(?, ?)");
mysqli_stmt_bind_param($stmt, 'ii', $vidID, $listID);
mysqli_stmt_execute($stmt);
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
$arr = array($vidID, mysqli_stmt_insert_id($stmt));
return $arr;
}
}
Я уверен, что есть много способов, которыми это можно улучшить, поэтому любые предложения будут приветствоваться.