我需要单独存储客户购买的产品,并使用一个名为order_id
的主键来了解产品所属的订单。
在一张表中,我存储订单,在另一张表中存储购买的产品
我的orders
表结构是:
order_id (PRIMARY KEY),
customer_id,
customer_name,
order_price,
order_date
我的purchased_products
表结构是:
order_id (FOREIGN KEY with REFERENCES orders(order_id)),
product_name,
product_price,
quantity
工作原理
当有人买东西时,我运行此代码来存储所有数据:
try
{
$connection = new PDO("mysql:host={$HOST};dbname={$DB_NAME}", $USERNAME, $PASS);
}
$connection->beginTransaction();
$sql = "INSERT INTO orders (customer_id, customer_name, order_price, order_date)
VALUES (?, ?, ?, ?)";
$query = $connection->prepare($sql);
$query->execute(array
(
$user_id,
$user['user_name'],
$order_price,
$date
));
$id_of_respective_order = $connection->lastInsertId();
$sql = "INSERT INTO purchased_products (order_id, product_name, product_price, quantity)
VALUES (?, ?, ?, ?)";
$query = $connection->prepare($sql);
foreach($_SESSION['cart'] as $product)
{
$query->execute(array
(
$id_of_respective_order,
$product['product_name'],
$product['product_price'],
$product['quantity']
));
}
$connection->commit();
使用此逻辑我锁定表,然后插入订单,并为我们使用PDO lastInsertId
分配正确的订单ID给属于它的产品。我可以使用:
SELECT * FROM orders c, purchased_products pc WHERE c.customer_id LIKE {$user_id} AND pc.order_id = c.order_id ORDER BY c.order_id DESC
我的问题是:
1.这种方法100%安全吗?如果没有,该怎么办?
2.如果同时购买的客户太多,表格将被锁定,但所有数据将按顺序一个接一个地正确插入,等待上一个订单或者在插入某个数据时购买的用户将收到错误,需要稍后尝试完成订单?
3.如果有太多顾客同时购买,是否有可能为产品分配错误的订单ID?
我很感激这种关注,我非常希望得到一个具体的答案,它可以消除我所有的疑虑并向我保证,我可以毫不畏惧地使用这种方法。
答案 0 :(得分:1)
- 这种方法100%安全吗?如果没有,该怎么办?
醇>
从SQL注入POV,至少你通过使用绑定参数阻止了1种方法。不过,我仍然建议使用手动预检。黄金法则是:永远不要相信任何用户输入,我在你的代码中没有看到,但我认为是这样。
- 如果同时购买的客户太多,表格将被锁定,但所有数据将按顺序逐个正确插入,等待上一个订单或插入某个数据时购买的用户会收到错误,并且需要稍后尝试完成订单吗?
醇>
在MySQL中,这取决于存储引擎和事务隔离级别,但通常事务可以并行运行,因此“按顺序逐个”不适用。 DBMS级别不会出现错误,但如果您在products表中有stock字段,则可能会丢失更新。购买相同产品的两个(甚至更多!)用户可以独立更新库存,而不会知道另一个。结果范围从负库存到不一致库存与数量。我们之前遇到过这种情况,需要使用应用程序级事务锁定来解决它。但是,如果你没有它,你应该是安全的。
- 如果有太多客户同时购买,是否有可能为产品分配错误的订单ID?
醇>
您使用交易来保护它,所以没有。