Конференция "Прочее" » Как лучше сделать
 
  • ProgRAMmer Dimonych © (29.06.08 15:01) [0]
    хранение порядка отображения элементов?

    Есть таблица в БД (MySQL). В ней, например, новости сайта. Есть страница, на которой отображаются все новости. Пока всё просто.

    Теперь ставим перед собой задачу: разрешить администратору сайта менять порядок следования новостей. Причём менять абсолютно независимо от каких-либо параметров новостей вродже даты создания//изменения и т.д., другими словами, нужно предоставить возможность поменять местами любую новость с любой, причём неограниченное количество раз.

    Мои варианты (ни один мне не нравится :().

    1. Ввести в таблицу дополнительное числовое поле, при выборке упорядочивать по значению этого поля. Для обмена новостей - обновлять значение этого поля.



    Пусть есть три новости, у которых значения этого order-поля равны, скажем, 35, 36 и 37. Я хочу поставить 35-ую новость между 36-й и 37-й. Если не туплю, то придётся тупо обменивать значения order-поля (в дроби уходить не хочется, они тоже имеют предел прочности). Получается 3 запроса: 1) найти две записи, между которыми будем обменивать значения order-полей; 2) обновить первую запись; 3) обновить вторую запись.

    2. Если уж обменивать, то почему бы не обойтись без order-поля? Брать и просто обменивать содержимое записей.



    Мне кажется, очень криво получится, а если придётся добавлять к таблице новые поля, то вероятность ошибки возрастает с бешеной скоростью. Плюс, опять же, три запроса, что, как по мне, многовато.

    =====

    Собственно, вопрос. Как лучше сделать такую возможность?
  • тимохов (29.06.08 15:18) [1]
    давай кажддой новости значение через 1000 (т.е. 0, 1000, 2000, 3000 и т.д.). Или через сотню.

    тогда обмен будет тривиален: не нужно ничего двигать - нужно будет менять числовое поле только у одной новости.

    хотя если админ фанат и будет менять по 10000 тыс раз, тогда не знаю...

    Имхо для решения задачи хватит с головой.
  • Пробегал2.... (29.06.08 15:20) [2]
    абсолютно непонятно - зачем.

    Сложности реализации данной логики связаны именно с тем, что неправильная логика вывода информации.

    Какой смысл указывать какая публикация будет идти после какой? Это в конце концов приведет к трудностям восприятия. Ведь как человек интуитивно читает список новостей?

    Он ищет глазами прочтенную новость, после чего считает, что все что ниже - он уже прочел и читает только новое. Все это основывается на том, что новости идут подряд, причем в большинстве случаев - именно по дате создания или обновления новости.

    Зачем ломать эту очевидную иерархию - непонятно совершенно.

    Если нужно видеть сначала самые просматриваемые новости - так надо сделать кнопку фильтр типа "Показывать в порядке популярности". Если нужно самые комментируемые - аналогично.

    Иногда нужно прибить объявления - то есть, новость, которая будет висеть выше остальных, какое-то системное объявление и типа того, ну это так и называется "Прилепить" или там "Важное". Реализуется легко, надо ввести только поле типа "Level", и выводятся новости по двойной фильтрации, сначала по уровню, потом по дате создания например.

    В общем, описанная проблема есть продолжение неправильной логики.
  • VirEx © (29.06.08 15:27) [3]

    >  [2] Пробегал2....   (29.06.08 15:20)

    тоже так считаю

    как пример, допустим есть колонка новостей:
    4. новость
    3. новость
    2. новость
    1. новость
    я прочитал все четыре
    через пять минут админ вклинит новость 3.1:
    6. новость
    5. новость
    4. новость
    3.1 новость
    3. новость
    2. новость
    1. новость
    а я продолжу читать 5 и 6ю новости, т.к. не замечу 3.1
  • tesseract © (29.06.08 15:29) [4]

    > абсолютно непонятно - зачем.


    Выводить популярные новости первыми например. На самом деле задача решаеться по другому - лента быстрых новостей + лента популярных новостей. Ничего сложного, просто нужно вводить "градус". Тот же гугл выводит мне новости согласно моим интересам " клик рейтинг" учитывает. Мне нравиться.
  • VirEx © (29.06.08 15:32) [5]
    для примера рейтинговых новостей: news2.ru
  • ProgRAMmer Dimonych © (29.06.08 15:32) [6]
    > Пробегал2....   (29.06.08 15:20) [2]

    Ну, такая логика не только у меня :)

    http://www.sitepoint.com/forums/showthread.php?t=438707
    http://forums.mysql.com/read.php?10,138171,138171#msg-138171

    и здесь, в принципе, тоже: http://forums.mysql.com/read.php?10,116864,116864#msg-116864

    Иногда вместо создания новостей "Через год", "Через полгода", "Сегодня" бывает проще создать одну новость и раз в полгода выносить её вверх. Хотя, согласен, пример с новостями не самый удачный. Можно взять, скажем, список программ, доступных для скачивания на сайте: по каким-то причинам иногда может возникать необходимость поменять их местами на странице со списком.

    Ещё более яркий пример: меню сайта. Сегодня хочу, чтобы новости были первыми в меню, завтра хочу перед ними вставить раздел "О сайте".

    > тимохов   (29.06.08 15:18) [1]

    Ну, то, что такой вариант будет работать - это здорово. Но, по-правильному, надо будет ещё писать скрипт, который эту нумерацию будет восстанавливать. Опять же, отследить, когда дошли до упора, сложно. А предполагается, что обмены будут частыми и осуществляться будут далёкими от программирования и баз данных люди, которым нельзя объяснить, что там что-то нумеруется, а потом интервал сокращается и надо иногда делать перенумерацию: они или забудут про перенумерацию, или будут её делать по десять раз в час, или, опять же, по-правильному, придётся писать скрипт, который будет напоминать про необходимость такой "дефрагментации" о мере приближения к критическому состоянию. :(
  • Пробегал2.... (29.06.08 15:35) [7]
    tesseract ©   (29.06.08 15:29) [4]
    Выводить популярные новости первыми например


    Пробегал2....   (29.06.08 15:20) [2]
    Если нужно видеть сначала самые просматриваемые новости - так надо сделать кнопку фильтр типа "Показывать в порядке популярности".
  • tesseract © (29.06.08 15:40) [8]

    > ли нужно видеть сначала самые просматриваемые новости -
    > так надо сделать кнопку фильтр типа "Показывать в порядке
    > популярности".


    Ой ёёёёёё, читать книжки по UI, пока такое само не отвалиться.
  • Zeqfreed © (29.06.08 15:41) [9]
    > Ещё более яркий пример: меню сайта. Сегодня хочу, чтобы
    > новости были первыми в меню, завтра хочу перед ними вставить
    > раздел "О сайте".

    Меню это обычно дерево. Там все несколько сложнее чем три запроса.
    А сабжевая задача должна решаться по методу 1, потому что незачем экономить на спичках. Плюс, стоит обратить внимание на [2].
  • Пробегал2.... (29.06.08 15:41) [10]
    ProgRAMmer Dimonych ©   (29.06.08 15:32) [6]

    ну если так, то я бы сделал одно единственное поле - например, TOP. И при выводе идет тупо сортировка по этому TOP.

    А уж администратор сайта пусть сам решает как ему что делать. TOP будет иметь тип integer и по нему будет происходить сортивка первая при выводе, а как использовать - админ думает сам. Может, какие-то свои диапазоны разрабатывать, например 0-100 для вывода верхних новостей, 150-300 для вывода списка программ... ну в общем как угодно.

    Следить за неповторимостью этого TOP не надо - слишком геморно. Если две новости имеют одно значение TOP - ну значит будут отсортированы в зависимости от вторичной сортировки или от того как БД сделана, это не критично.
  • ProgRAMmer Dimonych © (29.06.08 15:45) [11]
    Всем спасибо, пошёл крутить. Может написать разработчикам мускула, чтобы обмен значений сделали одним запросом? :)
  • Пробегал2.... (29.06.08 15:47) [12]
    tesseract ©   (29.06.08 15:40) [8]
    Ой ёёёёёё, читать книжки по UI, пока такое само не отвалиться.


    ой ёёёёё понт не засчитан: http://i076.radikal.ru/0806/22/1e86510f831e.jpg
  • tesseract © (29.06.08 15:47) [13]

    > Может написать разработчикам мускула, чтобы обмен значений
    > сделали одним запросом? :)


    Переходи на слоника. Мускул - недобаза.
  • Smile (29.06.08 15:52) [14]
    А я тоже считаю, что всем нужно внимательно читать Пробегал2....   (29.06.08 15:20) [2]
  • Zeqfreed © (29.06.08 15:55) [15]
    > ProgRAMmer Dimonych ©   (29.06.08 15:45) [11]

    mysql> select * from t_test;
    +----+-------+------+
    | id | value | pos  |
    +----+-------+------+
    |  1 |   100 |    1 |
    |  2 |   200 |    2 |
    |  3 |   300 |    3 |
    +----+-------+------+


    3 rows in set (0.00 sec)

    mysql> update t_test set pos = IF(id = 1, 3, 1) where id in (1,3);
    Query OK, 2 rows affected (0.00 sec)
    Rows matched: 2  Changed: 2  Warnings: 0

    mysql> select * from t_test;
    +----+-------+------+
    | id | value | pos  |
    +----+-------+------+
    |  1 |   100 |    3 |
    |  2 |   200 |    2 |
    |  3 |   300 |    1 |
    +----+-------+------+

  • ProgRAMmer Dimonych © (29.06.08 18:17) [16]
    > tesseract ©   (29.06.08 15:47) [13]
    > Переходи на слоника. Мускул - недобаза.

    Осталось дождаться, пока это станет понятно хостеру.

    > Zeqfreed ©   (29.06.08 15:55) [15]

    Это пример с двумя запросами? Спасибо, учтём, так даже красивее получится, чем два UPDATE'а.

    =====

    Ещё один вопрос: Как получить значение AUTO_INCREMENT поля для вставляемой записи?

    Т.е. хочу сделать что-то типа

    INSERT INTO MyTable(SomeField) VALUES(ID_OF_CURRENTLY_INSERTED_RECORD())



    LAST_INSERT_ID() в первый раз возвращает 0, а это не есть гуд. :(
  • Zeqfreed © (29.06.08 18:40) [17]
    > Ещё один вопрос: Как получить значение AUTO_INCREMENT поля
    > для вставляемой записи?

    В общем случае никак. Опять чувствуется дух мисдизайна. Зачем это понадобилось? :)
  • ProgRAMmer Dimonych © (29.06.08 18:43) [18]
    > Zeqfreed ©   (29.06.08 18:40) [17]

    > Zeqfreed ©   (29.06.08 15:55) [15]

    mysql> select * from t_test;
    +----+-------+------+
    | id | value | pos  |
    +----+-------+------+
    |  1 |   100 |    1 |
    |  2 |   200 |    2 |
    |  3 |   300 |    3 |
    +----+-------+------+



    Не привязывать же к БД гадалку, чтобы она поле pos заполняла. IMHO, есть смысл вновь добавляемым записям сразу устанавливать это поле равным id и использовать DESC-сортировку.
  • Zeqfreed © (29.06.08 18:47) [19]
    > ProgRAMmer Dimonych ©   (29.06.08 18:43) [18]

    Что мешает сделать поле pos точно так же автоматически инкрементируемым? :)
 
Конференция "Прочее" » Как лучше сделать
Есть новые Нет новых   [134439   +35][b:0][p:0.002]