我正在制作一个简单的数据库,用作电子商务网站的模拟示例。我需要做的一件事是使用PHP从数据库中删除记录。我可以删除用户名或订单等。但是,当我尝试一次性完成这些操作时,我正在搞砸了。我想要发生的是删除有关用户的所有信息。示例:用户信息,装运信息,账单信息,信用卡信息以及与特定用户有关的任何其他信息。我的表格如下。
mysql> SHOW columns FROM shirt_billing_addresses;
+----------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+--------------+------+-----+---------+----------------+
| shirt_billing_addresses_id | mediumint(9) | NO | PRI | NULL | auto_increment |
| house | mediumint(9) | NO | | NULL | |
| street | varchar(100) | NO | | NULL | |
| city | varchar(100) | NO | | NULL | |
| state | char(2) | NO | | NULL | |
| zip | char(5) | NO | | NULL | |
+----------------------------+--------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)
mysql> SHOW columns FROM shirt_credit_cards;
+-----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------+----------------+
| shirt_credit_cards_id | mediumint(9) | NO | PRI | NULL | auto_increment |
| shirt_users_id | mediumint(9) | NO | MUL | NULL | |
| type | varchar(30) | NO | | NULL | |
| no | char(16) | NO | | NULL | |
| security_code | char(3) | NO | | NULL | |
+-----------------------+--------------+------+-----+---------+----------------+
5 rows in set (0.04 sec)
mysql> SHOW columns FROM shirt_orders;
+-----------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------------+--------------+------+-----+---------+----------------+
| shirt_orders_id | int(11) | NO | PRI | NULL | auto_increment
| order_total | double(6,2) | NO | | NULL | |
| payment_date | datetime | NO | | NULL | |
| shirt_credit_cards_id | mediumint(9) | NO | MUL | NULL | |
| shirt_shipping_addresses_id | mediumint(9) | NO | MUL | NULL
| shirt_billing_addresses_id | mediumint(9) | NO | MUL | NULL |
| shirt_shipping_methods_id | tinyint(4) | NO | MUL | NULL |
+-----------------------------+--------------+------+-----+---------+----------------+
7 rows in set (0.02 sec)
mysql> SHOW columns FROM shirt_shipping_addresses;
+-----------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------------+--------------+------+-----+---------+----------------+
| shirt_shipping_addresses_id | mediumint(9) | NO | PRI | NULL | auto_increment
| house | mediumint(9) | NO | | NULL | |
| street | varchar(100) | NO | | NULL | |
| city | varchar(100) | NO | | NULL | |
| state | char(2) | NO | | NULL | |
| zip | char(5) | NO | | NULL | |
+-----------------------------+--------------+------+-----+---------+----------------+
6 rows in set (0.03 sec)
mysql> SHOW columns FROM shirt_users;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| shirt_users_id | mediumint(9) | NO | PRI | NULL | auto_increment |
| first_name | varchar(30) | NO | | NULL | |
| last_name | varchar(30) | NO | | NULL | |
| email | varchar(30) | NO | | NULL | |
| user_id | varchar(30) | NO | | NULL | |
| password | char(40) | NO | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
6 rows in set (0.03 sec)
mysql> SHOW columns FROM shirt_users_types;
+----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+--------------+------+-----+---------+----------------+
| shirt_users_types_id | int(11) | NO | PRI | NULL | auto_increment |
| shirt_users_id | mediumint(9) | NO | MUL | NULL | |
| shirt_types_id | smallint(6) | NO | MUL | NULL | |
| shirt_orders_id | int(11) | NO | MUL | NULL | |
| type_quantity | smallint(6) | NO | | NULL | |
| type_total | double(6,2) | NO | | NULL | |
+----------------------+--------------+------+-----+---------+----------------+
6 rows in set (0.03 sec)
我的PHP代码如下:
@mysqli_query($link, "SET AUTOCOMMIT=0");
$select_sui = "SELECT
shirt_users.shirt_users_id,
shirt_users_types.shirt_users_types_id,
shirt_orders.shirt_orders_id,
shirt_shipping_addresses.shirt_shipping_addresses_id,
shirt_billing_addresses.shirt_billing_addresses_id,
shirt_credit_cards.shirt_credit_cards_id
from
shirt_users,
shirt_users_types,
shirt_orders,
shirt_shipping_addresses,
shirt_billing_addresses,
shirt_credit_cards
where
shirt_users.shirt_users_id = shirt_users_types.shirt_users_id and
shirt_users_types.shirt_orders_id = shirt_orders.shirt_orders_id and
shirt_orders.shirt_shipping_addresses_id = shirt_shipping_addresses.shirt_shipping_addresses_id and
shirt_orders.shirt_billing_addresses_id = shirt_billing_addresses.shirt_billing_addresses_id and
shirt_orders.shirt_credit_cards_id = shirt_credit_cards.shirt_credit_cards_id and
shirt_users.shirt_users_id = $shirt_users_id";
唯一的问题是此查询将返回一个空集,除非所有表中都包含正确的信息。这是一个问题,因为如果用户尚未订购任何项目,但我想从数据库中删除它们,它将不允许我。任何有关此事的帮助将不胜感激。
答案 0 :(得分:2)
您必须使用LEFT JOIN
链接表格(MySQL doc)。
SELECT [...]
FROM shirt_users
LEFT JOIN shirt_users_types ON shirt_users.shirt_users_id = shirt_users_types.shirt_users_id
LEFT JOIN shirt_orders ON shirt_users_types.shirt_orders_id = shirt_orders.shirt_orders_id
LEFT JOIN shirt_shipping_addresses ON shirt_orders.shirt_shipping_addresses_id = shirt_shipping_addresses.shirt_shipping_addresses_id
LEFT JOIN shirt_billing_addresses ON shirt_orders.shirt_billing_addresses_id = shirt_billing_addresses.shirt_billing_addresses_id
LEFT JOIN shirt_credit_cards ON shirt_orders.shirt_credit_cards_id = shirt_credit_cards.shirt_credit_cards_id
WHERE
shirt_users.shirt_users_id = $shirt_users_id
使用此功能,即使其他表中没有链接记录,您也可以加载shirt_users
。
编辑删除记录
如果只想在一个请求中删除所有表,则必须使用与第一次尝试完全相同的语法(通过SELECT
替换DELETE
语句)。你会得到同样的问题(它只会删除每个表中都有链接记录而不是空的记录)。
方法1:
注意:您的数据库必须支持外键(例如,MyISAM不支持它,但InnoDB支持外键)。
如果您在应用中始终需要删除所有链接的记录,则可以使用此方法。
实现这一目标的最美妙方法是在你的关系中添加ON DELETE CASCADE
约束:
-- Drop the old constraint ("fk_test" must be replace by your constraint name)
ALTER TABLE shirt_users_types DROP FOREIGN KEY `fk_test`;
-- Create the new with ON DELETE
ALTER TABLE shirt_users_types
ADD CONSTRAINT `fk_test`
FOREIGN KEY (`shirt_users_id` )
REFERENCES `shirt_users` (`shirt_users_id` )
ON DELETE CASCADE;
当您删除shirt_users
条目时,shirt_users_types
中的所有关联记录。
简而言之,使用ON DELETE CASCADE
,每次删除父元素(关系的One
侧)时,所有子项(关系的Many
侧)或者包含列<related_record>_id
的表格也将被自动删除。
方法2:
如果您的关系可以为空(例如,如果shirt_users_types.shirt_orders_id
可以为null),或者您的数据库架构不允许使用ON DELETE CASCADE
删除所有需要的记录。
您可以使用与DELETE
的关系删除多个shirt_users
的记录,以便检索每个链接表中的记录。 (有关DELETE
的正确语法,请参阅MySQL docs)。
在您的代码中,您的唯一标识符为$shirt_users_id
,因此您必须首先删除与shirt_users
没有直接关联的表格,然后通过表格{{返回您的关系来完成1}}。
如果您没有按正确的顺序删除记录,您将无法删除所需的全部内容。
例如,对于问题中描述的架构,如果您在shirt_users
之前删除shirt_orders
中的记录,则您将无法再使用shirt_shipping_addresses
检索送货地址,因为$shirt_users_id
由于与shirt_shipping_addresses
的关系,因此与shirt_users
相关联。
因此,您当前架构的正确顺序是(不需要在上面的列表的同一行上订购表):
由于外键,您可能会出现shirt_orders
错误。在这种情况下,您可以使用contraint fails
进行删除(这是最佳做法)或禁用外键检查。
TRANSACTION