在数据库中存储项目顺序有哪些方法?

时间:2014-02-19 16:44:29

标签: php mysql symfony

我正在创建一个包含图片的图库的投资组合网站。我希望此投资组合的用户能够在图库中订购图像。问题本身很简单我只是在努力决定实施的解决方案。

到目前为止,我有两种解决方案:

  1. 只需添加order列(或优先级?),然后使用该列上的ORDER BY子句进行查询。这样做的缺点是,要更改单个图像的顺序,我必须更新库中的每个图像。
  2. 第二种方法是添加2个可空列nextprevious,它们只存储下一个和上一个图像的ID。这意味着订单更改时更新的数据会更少;但是,设置起来要复杂得多,而且我不完全确定如何实现它。
  3. 额外的选择会很棒。

    • 这些选项是否可行?
    • 有更好的选择吗?
    • 他们怎么可能/应该实施?

    有问题的两个表的当前结构如下:

    mysql> desc Gallery;
    
    +--------------+------------------+------+-----+-------------------+-----------------------------+
    | Field        | Type             | Null | Key | Default           | Extra                       |
    +--------------+------------------+------+-----+-------------------+-----------------------------+
    | id           | int(10) unsigned | NO   | PRI | NULL              | auto_increment              |
    | title        | varchar(255)     | NO   |     | NULL              |                             |
    | subtitle     | varchar(255)     | NO   |     | NULL              |                             |
    | description  | varchar(5000)    | NO   |     | NULL              |                             |
    | date         | datetime         | NO   |     | NULL              |                             |
    | isActive     | tinyint(1)       | NO   |     | NULL              |                             |
    | lastModified | timestamp        | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
    +--------------+------------------+------+-----+-------------------+-----------------------------+
    
    mysql> desc Image;
    +--------------+------------------+------+-----+-------------------+-----------------------------+
    | Field        | Type             | Null | Key | Default           | Extra                       |
    +--------------+------------------+------+-----+-------------------+-----------------------------+
    | id           | int(10) unsigned | NO   | PRI | NULL              | auto_increment              |
    | galleryId    | int(10) unsigned | NO   | MUL | NULL              |                             |
    | description  | varchar(250)     | YES  |     | NULL              |                             |
    | path         | varchar(250)     | NO   |     | NULL              |                             |
    | lastModified | timestamp        | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
    +--------------+------------------+------+-----+-------------------+-----------------------------+
    

    目前没有以任何形式实施订购。

2 个答案:

答案 0 :(得分:2)

虽然1可能会有点丑陋:

  UPDATE table set order=order+1 where order>='orderValueOfItemYouCareAbout';

这将更新所有剩余的图像,你不必做大量的腿部工作。

答案 1 :(得分:0)

正如bart2puck所说,我在问题中说过,选项1有点难看;然而,我选择的选择是全面简化解决方案。

我在displayOrder int UNSIGNED之后向Image表中添加了一列(path)。当我想在表中重新排序一行时,我只需交换行。所以,如果我有3行:

mysql> SELECT id, galleryId, description, displayOrder FROM Image ORDER BY displayOrder;
+-----+-----------+----------------------------------+--------------+
| id  | galleryId | description                      | displayOrder |
+-----+-----------+----------------------------------+--------------+
| 271 |        20 | NULL                             |            1 |
| 270 |        20 | Tracks leading into the ocean... |            2 |
| 278 |        20 | NULL                             |            3 |
+-----+-----------+----------------------------------+--------------+
3 rows in set (0.00 sec)

如果我想重新排序第278行而不是第三行,我只需通过执行以下操作将其与第二行交换:

UPDATE Image SET displayOrder =   
  CASE displayOrder     
    WHEN 2 THEN 3
    WHEN 3 THEN 2
  END 
WHERE galleryId = 20 
AND displayOrder BETWEEN 2 AND 3;

导致:

mysql> SELECT id, galleryId, description, displayOrder FROM Image ORDER BY displayOrder;
+-----+-----------+----------------------------------+--------------+
| id  | galleryId | description                      | displayOrder |
+-----+-----------+----------------------------------+--------------+
| 271 |        20 | NULL                             |            1 |
| 278 |        20 | NULL                             |            2 |
| 270 |        20 | Tracks leading into the ocean... |            3 |
+-----+-----------+----------------------------------+--------------+
3 rows in set (0.00 sec)

有些人可能会发现的一个可能的问题是,你只能用这种方法将位置改变一个位置,即将图像278移动到第一个,我必须将其作为第二个,然后是第一个,否则当前第一个图像会出现在第三位。