链接 MySQL 数据库中的行并使用 PHP 进行查询
Linking rows in the MySQL database and querying with PHP
我刚刚用 PHP 完成了我的第一个网站,现在我注意到一个问题。我的很多动态内容是 "linked" 到其他 table 行。所以当其他 table 中的那些行被删除时,它显然给了我一个错误。
例如,我有一个 table "book_groups" 从 tables "books"、"hosts" 和 "locations" 中提取数据。所以我在查询了某个book_group之后,再根据存储在book_id、host_id和location_id中的其他table进行查询组.
我显然没有计划好。因为如果一本书不小心删了再重新添加,id会变,就坏了。
我的问题是,现在我几乎已经全部完成,解决这个问题的最佳方法是什么?我可以返回到每个查询并添加一个 if( $query_result != false ) 以查看该行是否仍然存在。但是伙计,有很多疑问,因为我有很多不同类型的组和相关 tables.
为了将来参考,是否有更好的方法将 link table 存储在 MySQL 中,而不是仅存储相关 table 行的 ID?
您的主题是参照完整性。在 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
记录被删除的 book_groups
记录,则会引发异常,并取消 delete
操作。
您可以通过 MySql
here 了解参照完整性。
您可以在 PHP
中做类似的事情,但是当通过其他工具(例如 phpAdmin
)连接时,这就留下了绕过此类代码的可能性。触发器的优点是它们的执行独立于您连接的位置,并且它们与主要操作在同一事务中执行。缺点是在 php
代码旁边还要维护另一层代码。 php
代码必须意识到这些触发器可能对其他表产生的副作用。
在 php
中对 book
进行控制 delete
的一些想法:
$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...
我刚刚用 PHP 完成了我的第一个网站,现在我注意到一个问题。我的很多动态内容是 "linked" 到其他 table 行。所以当其他 table 中的那些行被删除时,它显然给了我一个错误。
例如,我有一个 table "book_groups" 从 tables "books"、"hosts" 和 "locations" 中提取数据。所以我在查询了某个book_group之后,再根据存储在book_id、host_id和location_id中的其他table进行查询组.
我显然没有计划好。因为如果一本书不小心删了再重新添加,id会变,就坏了。
我的问题是,现在我几乎已经全部完成,解决这个问题的最佳方法是什么?我可以返回到每个查询并添加一个 if( $query_result != false ) 以查看该行是否仍然存在。但是伙计,有很多疑问,因为我有很多不同类型的组和相关 tables.
为了将来参考,是否有更好的方法将 link table 存储在 MySQL 中,而不是仅存储相关 table 行的 ID?
您的主题是参照完整性。在 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
记录被删除的 book_groups
记录,则会引发异常,并取消 delete
操作。
您可以通过 MySql
here 了解参照完整性。
您可以在 PHP
中做类似的事情,但是当通过其他工具(例如 phpAdmin
)连接时,这就留下了绕过此类代码的可能性。触发器的优点是它们的执行独立于您连接的位置,并且它们与主要操作在同一事务中执行。缺点是在 php
代码旁边还要维护另一层代码。 php
代码必须意识到这些触发器可能对其他表产生的副作用。
在 php
中对 book
进行控制 delete
的一些想法:
$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...