Nano Hash - криптовалюты, майнинг, программирование

Связывание строк в базе данных MySQL и выполнение запросов с помощью PHP

Я только что закончил свой первый сайт с PHP и только сейчас заметил проблему. Большая часть моего динамического содержимого «связана» со строками в других таблицах. Поэтому, когда эти строки в других таблицах удаляются, это, очевидно, дает мне ошибку.

Например, у меня есть таблица «book_groups», которая извлекает данные из таблиц «books», «hosts» и «locations». Таким образом, после запроса определенной группы book_group я делаю дополнительные запросы к другим таблицам на основе book_id, host_id и location_id, которые хранятся в группе.

Очевидно, я недостаточно хорошо спланировал. Потому что, если книгу случайно удалить, а затем снова добавить, идентификатор изменится, и она будет сломана.

Мой вопрос в том, что это лучший способ исправить это сейчас, когда я все это практически закончил? Я мог бы вернуться к каждому запросу и добавить if( $query_result != false ), чтобы увидеть, существует ли еще строка. Но человек, есть много запросов, потому что у меня есть много разных типов групп и связанных таблиц.

Для дальнейшего использования: есть ли лучший способ связать таблицы в MySQL вместо того, чтобы просто хранить идентификатор связанной строки таблицы?

19.11.2015

  • Вы правильно их связываете. Одним из решений является наличие в вашем коде положения, согласно которому при удалении книги группы book_groups, полагающиеся на эту книгу, также удаляются. Многие фреймворки MVC имеют готовые решения для такого рода функций, например, зависимые от Rails: :destroy (я знаю, что вы используете PHP — это был только первый пример, который пришел на ум) 19.11.2015
  • Мне кажется, что отображение один ко многим. Я думаю, уже слишком поздно для ВНУТРЕННЕГО ПРИСОЕДИНЕНИЯ к вашим запросам? Я думаю, что book_group должен быть только списком идентификаторов, связанных с книгой, а затем сделать ВНУТРЕННЕЕ СОЕДИНЕНИЕ по group_id, вы будете получать только книги, которые существуют в таблице книг, и позже вы сможете обрезать свою book_group. 19.11.2015
  • Я не хочу удалять ни одну из групп. Я просто хочу иметь возможность изменить, какая книга в настоящее время связана с ним. Я ничего не знаю о фреймворках MVC (это все новое для меня), но я посмотрю на это. 19.11.2015

Ответы:


1

Ваша тема — ссылочная целостность. В MySQL вы можете обеспечить такую ​​целостность с помощью триггеров базы данных.

Например, вы можете определить триггер, который выполняется до того, как delete произойдет в родительской записи:

CREATE TRIGGER trg_books_bef_delete
    BEFORE DELETE
    ON books
    FOR EACH ROW
BEGIN
    DELETE FROM book_groups WHERE book_id = old.book_id;
END;

Этот конкретный триггер удалит все зависимые записи в book_groups, которые ссылаются на удаляемую запись book.

Вы можете решить реагировать по-другому и вызвать ошибку всякий раз, когда удаляется запись book, которая имеет зависимые записи. Начиная с MySQL 5.5 вы можете сделать это:

CREATE TRIGGER trg_books_bef_delete
    BEFORE DELETE
    ON books
    FOR EACH ROW
BEGIN
    IF (SELECT COUNT(*) FROM book_groups WHERE book_id = old.book_id) > 0
    THEN
       SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Foreign Key Constraint Violated!';
    END IF;
END;

В этом случае, если найдена запись book_groups, которая ссылается на удаляемую запись book, возникает резкое исключение, и операция delete отменяется.

Вы можете прочитать о ссылочной целостности с помощью MySql здесь .

Вы могли бы делать подобные вещи в PHP, но это оставляет возможность обойти такой код при подключении через другие инструменты, такие как phpAdmin. Преимущество триггеров в том, что они выполняются независимо от того, откуда вы подключаетесь, и выполняются в той же транзакции, что и основная операция. Недостатком является то, что вам нужно поддерживать еще один слой кода, следующий за кодом php. И этот код php должен знать о побочных эффектах на другие таблицы, которые могут иметь эти триггеры.

Некоторые идеи для контролируемого delete из book в php:

$confirmed = false;
if (isset($_POST["confirm"])) {
    $confirmed = true;
}

$book_id = $_POST["book_id"]);

$con = mysqli_connect(...);

// Check for dependent records that would also be deleted:
if ($stmt = mysqli_prepare($con, 
        "SELECT COUNT(*) AS cnt FROM book_groups WHERE book_id = ?")) {
    mysqli_stmt_bind_param($stmt, "i", $book_id);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_bind_result($stmt, $cnt);
    mysqli_stmt_fetch($stmt);
    mysqli_stmt_close($stmt);
    if ($cnt > 0 && !$confirmed) {
        ?>
        <html>
        <body>  
            <form action="" method="post">
                <input type="hidden" name="book_id" value="<?=$book_id?>"/>
                This book is categorised in groups, 
                are you sure to delete that information?
                <input type="submit" value="confirm" name="confirm"/> 
            </form>
        </body>
        </html>
        <?php
        exit;
    }
}

// continue to delete book below...
19.11.2015
  • Похоже, что второе решение может сработать. Но я бы хотел, чтобы все запросы к базе данных были возможны через CMS, которую я создал с помощью PHP. Могу ли я каким-то образом сделать этот запрос в PHP и сообщить пользователю, какие записи все еще полагаются на него, прежде чем он будет удален, а затем при желании предложить продолжить? 19.11.2015
  • Конечно, вы бы сделали mysqli_query, чтобы подсчитать количество записей в books_query с одинаковым идентификатором, а затем посмотреть, не равно ли оно нулю, представить страницу, на которой пользователь должен подтвердить свое согласие, и если вы php видите, что этот параметр подтверждения присутствует , вы выполняете удаления. 19.11.2015
  • Я добавил некоторые указания для такого php кода. Не проверял, просто для идеи. 20.11.2015
  • Похоже, это, наверное, то, что мне нужно. Теперь мне просто нужно выяснить, что делают все эти функции... :P Спасибо за вашу потрясающую помощь! 20.11.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..