2

同様の質問を読みましたが、ON DELETE と ON UPDATE の使用に関する詳細な説明がないため、それを理解するのに苦労しています。また、レコードを削除または更新する場合にデータベースを更新する正しい手順は何ですか? FK 制約ですが、参照されたときに他のテーブルのレコードを削除しませんが、それらの参照を null または 0 または他のテーブルの何かに設定します。

バックグラウンド

管理者 (CMS など) がデータベースを管理できるように、このデータベース (e-cart システム用) の関数のライブラリを作成しようとしています。

外部キーとトランザクションを利用するために InnoDB エンジンを選択しました。

mysql_また、パラメーター化されたクエリを利用するために、標準の関数ではなく PHP PDO オブジェクトを使用しています。

これは、これらのテーブルの SQL 作成コードです。

# TBL_MENU_CATEGORY

DROP TABLE IF EXISTS tbl_menu_category;
CREATE TABLE tbl_menu_category(
    id INT NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(id),
    name VARCHAR(50)
) ENGINE = InnoDB;

# TBL_PRODUCT_CATEGORY

DROP TABLE IF EXISTS tbl_product_category;
CREATE TABLE tbl_product_category(
    id INT NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(id),
    name VARCHAR(50)
) ENGINE = InnoDB;


# TBL_MENU_CAT_BASKET

DROP TABLE IF EXISTS tbl_menu_cat_basket;
CREATE TABLE tbl_menu_cat_basket(
    menu_id INT,
    FOREIGN KEY(menu_id) REFERENCES tbl_menu_category(id),
    cat_id INT,
    FOREIGN KEY(cat_id) REFERENCES tbl_product_category(id)
) ENGINE = InnoDB;


# TBL_PRODUCT_CAT_BASKET

DROP TABLE IF EXISTS tbl_product_cat_basket;
CREATE TABLE tbl_product_cat_basket(
    cat_id INT,
    FOREIGN KEY(cat_id) REFERENCES tbl_product_category(id),
    product_id INT,
    FOREIGN KEY(product_id) REFERENCES tbl_product(id)
) ENGINE = InnoDB;

これは、メニューにサブメニューを追加するためのライブラリ内の機能です (メニュー > サブメニュー > 製品)。

function addSubmenu($menu_id, $sub_name) {
    $success = false;
    if ( dbTransaction() ) {
        $sql = "INSERT INTO tbl_product_cat(name) VALUES ('?');";
        dbQuery($sql, array($sub_name));
        $rows = dbRowsAffected();
        if ($rows == 1) {
            $cat_id = dbLastInsertId();
            $sql = "INSERT INTO tbl_menu_cat_basket(menu_id, cat_id) VALUES ('?','?');";
            dbQuery($sql, array((int)$menu_id, (int)$cat_id));
            $rows = dbRowsAffected();
            if ($rows == 1) {
                $success = true;
            }
        }
        if ($success)
            dbCommit();
            return "Add submenu successful.";
        else
            dbRollback();
            return "Add submenu failed.";
    }
}

クエリは次のように実行されます。

require_once "pdo.php"; # Creates PDO object '$db'
$query;

function dbQuery($sql, $data) {
    global $db, $query;
    $query = $db->prepare($sql);
    $query->execute($data);
}

# other PDO & PDOStatement methods like this
# (rowCount, lastInsertId, fetchAll, transaction-stuff).

問題

これが正しいかどうかさえわかりません。私は正しい道をたどっていますか、それとも間違ったことをしていますか?

現在、外部キーを持つレコードを更新するための同様の関数を作成することに固執しています。InnoDB は、参照があるためにレコードを更新できないというエラーをスローすることを知っています (私は思いますか?)。

レコードを更新するための正しい手順と、そのために利用できる機能を知る必要があります。

ON DELETE および ON UPDATE 制約について知りたいのですが、初心者向けの適切なチュートリアルが見つからないようです (MySQL ドキュメントは非常に不親切で、構文を強調することさえありません)。

私がしたいこと

レコードを更新するとき、更新をカスケードして、すべての参照が更新されるようにします。

レコードを削除するとき、削除されたレコードを削除したいだけですが、代わりにそれへの参照をリセットできます (製品カテゴリが削除された場合、製品は削除されるべきではありません。製品が削除された場合、その製品のすべての注文は削除されるべきではありません)ただし、製品の値は 0 または null に設定されています)

ON DELETE と ON UPDATE を使用してこれを行うにはどうすればよいですか? または、ここでやりたいことを達成するにはどのような手順を実行する必要がありますか?

読んでくれてありがとう。

4

1 に答える 1

1

外部キー仕様で指定ON UPDATE CASCADE ON DELETE SET NULLするとうまくいくはずです。

たとえば、FOREIGN KEY(product_id) REFERENCES tbl_product(id) ON UPDATE CASCADE ON DELETE SET NULL. 主キーの値を変更することが理にかなっている状況をどこで予測するのだろうか。

MySQL Workbenchに興味があるかもしれません。スキーマを視覚的に設計し、対応する DDL ステートメントを表示するのに役立ちます。

于 2012-04-13T16:29:46.347 に答える