如何确定新商品的订单?

时间:2020-03-06 14:27:27  来源:igfitidea点击:

我在MySQL中有一个成员表

CREATE TABLE  `members` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(65) collate utf8_unicode_ci NOT NULL,
  `order` tinyint(3) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB;

我想让用户按自己的喜好订购会员。
我将订单存储在"订单"列中。

我想知道如何插入要添加到列表底部的新用户。
这就是我今天所拥有的:

$db->query('insert into members VALUES (0, "new member", 0)');
$lastId = $db->lastInsertId();
$maxOrder = $db->fetchAll('select MAX(`order`) max_order FROM members');
$db->query('update members 
            SET 
                `order` = ?
            WHERE 
                 id = ?', 
           array(
               $maxOrder[0]['max_order'] + 1, 
               $lastId
        ));

但是,当有多个用户同时添加新成员时,这可能不是很准确,这可能是因为MAX(order)将返回相同的值。

我们如何处理这种情况?

解决方案

由于我们已经为每个新成员自动增加了ID,因此我们可以按ID进行订购。

我不确定我是否理解。如果每个用户想要不同的顺序,我们将如何在"成员"表的一个字段中存储各个用户的首选项?

通常,我们只是让用户根据字段的自然顺序进行排序。订单字段的目的是什么?

通常,我将所有选择语句按"顺序,名称"进行排序;然后,我总是为Order插入相同的值(0还是9999999,具体取决于我要第一个还是最后一个)。然后,用户可以根据自己的喜好重新排序。

InnoDB支持事务。在插入之前执行"开始"语句,并在完成时进行提交。有关mySql中事务的解释,请参见本文。

我们可以将SELECT作为INSERT的一部分来执行,例如:

INSERT INTO members SELECT 0, "new member", max(`order`)+1 FROM members;

请记住,我们将需要在order列上建立索引以优化SELECT部件。

另外,除非我们只希望有255个订单,否则我们可能要重新考虑tinyint的订单。

同样,order是保留字,我们将始终需要将其写为order,因此我们也可以考虑重命名该列。

我们可以做的是创建一个具有键(member_id,position)的表,该键映射到另一个member_id。然后,我们可以将顺序与成员列表本身分开存储在该表中。 (每个成员都保留自己的列表顺序,这是我假设我们想要的...?)

假设我们有一个像这样的成员表:

+-----------+--------------+
| member_id | name         |
+-----------+--------------+
|         1 | John Smith   |
|         2 | John Doe     |
|         3 | John Johnson |
|         4 | Sue Someone  |
+-----------+--------------+

然后,我们可能会有一个订购表,如下所示:

+---------------+----------+-----------------+
| member_id_key | position | member_id_value |
+---------------+----------+-----------------+
|             1 |        1 |               4 |
|             1 |        2 |               1 |
|             1 |        3 |               3 |
|             1 |        4 |               2 |
|             2 |        2 |               1 |
|             2 |        3 |               2 |
+---------------+----------+-----------------+

我们可以使用内部联接选择给定存储顺序的成员列表。例如:

SELECT name
FROM members inner join orderings 
  ON members.member_id = orderings.member_id_value
WHERE orderings.member_id_key = <ID for member you want to lookup>
ORDER BY position;

例如,对John Smith的列表(即WHERE member_id_key = 1)运行此查询的结果将是:

+--------------+
| name         |
+--------------+
| Sue Someone  |
| John Smith   |
| John Johnson |
| John Doe     |
+--------------+

我们可以通过将给定ID的最大位置值加1来计算要添加到列表底部的位置。