Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Проблема с пронумеровкой поля N


Автор: InfMag 23.5.2006, 20:48
У меня есть MySQL таблица. У нее есть ID, который работает автоматом и есть поле N, которое забивается от 1ого и до конца по порядку по циклу сортируясь от ID:
Код

function numreset($table)
{
    $res = mysql_query("SELECT * FROM `".$table."` ORDER BY `id` ASC");
    $n = 0;
    while ($arr = mysql_fetch_array($res))
    {
        $n++;
        mysql_query("UPDATE `".$table."` SET `n` = '$n' WHERE `id` = '".$arr['id']."' LIMIT 1");
    }
}

Проблема в том, что я использую N для сдвига записей вверх и вниз, ID должен оставаться у записи тем же. Я меняю только местами N. Но когда использую пронумеровку в зависимости от ID, то все N перемещения сбрасываются, потому что сортировка идет от ID.
Посоветуйте что можно придумать в данной ситуации.

ЗЫ: Просьба не перемещать тему к Базам Данных, поскольку проблема заключается не в самой БД. 

Автор: PARROT 23.5.2006, 21:01
Код

function numreset($table)
{
    $res = mysql_query("SELECT * FROM `".$table."` ORDER BY `id` ASC");
    $n = 1;
    while ($arr = mysql_fetch_array($res))
    {
       $n=$n+1;
        mysql_query("UPDATE `".$table."` SET `n` = '$n' WHERE `id` = '".$arr['id']."' LIMIT 1");
    }
}


может так? 

Автор: InfMag 23.5.2006, 21:08
PARROT, ну? и что это изменит? вобще функцию я сам писал, она работает и к ней у меня никаких вопросов нету.
На заметку: в php, также как и в си, есть сокращенные действия.
$n++ и $n=$n+1; выполняют одно и тоже, но стоит признаться, что $n++ писать быстрее и удобнее для глаза.
$n-- и $n=$n-1; анологично 

Автор: Mal Hack 23.5.2006, 21:18
Цитата(InfMag @  23.5.2006,  20:48 Найти цитируемый пост)
ЗЫ: Просьба не перемещать тему к Базам Данных, поскольку проблема заключается не в самой БД. 

Перекинул именно туда, т.к. Все это противоречит 1 НФ, 2 НФ и вообще сути ключа. Идет дубляж данных.
Модератор: перемещено в Базы Данных -> MySQL из PHP -> PHP для начинающих 

Автор: igorold 24.5.2006, 07:18
а что значит - все N перемещения сбрасываются
объясни на примере, легче будет тебе помочь ... т.е. что делаешь, что получается, а что хочешь получить?
а что такое - $arr['id'] ?
я с РНР не знаком - работаю с перлом и mysql ... и зачем пишешь LIMIT 1, если поле id  - уникально?
 

Автор: Ignat 24.5.2006, 09:09
Цитата(Mal Hack @  23.5.2006,  22:18 Найти цитируемый пост)
Все это противоречит 1 НФ, 2 НФ и вообще сути ключа. Идет дубляж данных.

Ни фига подобного. Дубляжа здесь нет: Поле N отражает порядок следования записей и никак не отражает уникальность (по сути), в то время как id уникален и является ключом. Все данные атомарны. А где же противоречие НФ?

InfMag, а вот вопрос я так и не понял, собственно как и смысл в приведенном участке кода.

Добавлено @ 09:10 

M
Ignat
Перемещаю в PHP для новичков
 

Автор: igorold 24.5.2006, 11:15
Цитата(Ignat @ 24.5.2006,  09:09)
Ни фига подобного. Дубляжа здесь нет: Поле N отражает порядок следования записей и никак не отражает уникальность (по сути), в то время как id уникален и является ключом. Все данные атомарны. А где же противоречие НФ?

если взять частный случай, когда записи не удалялись, то это будут равные поля ...  

Автор: Ignat 24.5.2006, 11:17
Цитата(igorold @  24.5.2006,  12:15 Найти цитируемый пост)
если взять частный случай, когда записи не удалялись, то это будут равные поля ...   

Единственно возможный  случай smile  

Автор: InfMag 24.5.2006, 11:58
Вот, попытаюсь обьяснить.
У меня есть таблица, которая выводится так:
Код

SELECT * FROM `table` ORDER BY `n` ASC

Тоесть сортируется она по полю N. ID тоже есть.
Поле N должно быть точно от 1ого и до конечного числа.
Не так, как может быть в ID:
Код

1
2
3
5

А так:
Код

1
2
3
4

И чтобы было именно так - я написал функцию:
Код

function numreset($table)
{
    $res = mysql_query("SELECT * FROM `".$table."` ORDER BY `id` ASC");
    $n = 0;
    while ($arr = mysql_fetch_array($res))
    {
        $n++;
        mysql_query("UPDATE `".$table."` SET `n` = '$n' WHERE `id` = '".$arr['id']."' LIMIT 1");
    }
}

Но получился один ньюанс. У записей еще есть кнопочки Вниз и Вверх, а когда нажимаешь на любую из них, то просто перемещается значение N, а ID не меняется, просто так и задумано, чтобы ID всегда оставался тем же, но когда я запускаю функцию NUMRESET, то сортировка записей идет от ID и N простанавливаются через цикл по этой последовательности и получается так, что все, что я переместил Вверх и Вниз становится обратно на свои места. smile
Надеюсь понятно.

Что делать? 

Автор: InfMag 24.5.2006, 12:28
У меня конечно есть мелкие идейки, но все-равно не входят в рамки. Дело в том, что при добавлении записи, ни ID ни N не указывается и не должно. Все должна выполнять функция numreset.
Вот у меня например была идея в функции numreset поставить сортировку по самой N, но если добавить запись, то N будет равняться нулю и эта запись пойдет самой первой, проблему можно решить при указании N, когда добавляешь саму запись по запросу, но я уже говорил, что так быть не должно... smile 

Автор: Ignat 24.5.2006, 12:38
Понял. Вообще перетряхивать таблицу ради нумерации - не есть гуд. Но ответом на поставленный вопрос будет:

Код

function numreset($table)
{
    $res = mysql_query("SELECT * FROM `".$table."` ORDER BY `N` ASC");
    $n = 0;
    while ($arr = mysql_fetch_array($res))
    {
        $n++;
        mysql_query("UPDATE `".$table."` SET `n` = '$n' WHERE `id` = '".$arr['id']."' LIMIT 1");
    }
}


Возникает вопрос: "Для чего нужно сплошное заполнение поля N?" 

Автор: InfMag 24.5.2006, 12:49
Ignat, нет, то что ты написал я уже предлагал, но я говорил про INSERT INTO, то-бишь когда добавляешь значение, то N будет по умолчанию равняться 0 и получится так, что значение будет с номером 1, а остальные пойдут потом.

N нужно, для того чтобы можно было для юзера перемещать значения вверх и вниз, но чтобы ID всегда оставался тем же.

Ух... Попроюую сам сейчас накалякать, потом отпишусь. 

Автор: Ignat 24.5.2006, 12:56
Цитата(InfMag @  24.5.2006,  13:49 Найти цитируемый пост)
Ignat, нет, то что ты написал я уже предлагал

Вчитайся smile 

Цитата(InfMag @  24.5.2006,  13:49 Найти цитируемый пост)
но я говорил про INSERT INTO, то-бишь когда добавляешь значение, то N будет по умолчанию равняться 0

Какое умолчание поставишь, то и будет =) хоть MAXINT

Цитата(InfMag @  24.5.2006,  13:49 Найти цитируемый пост)
N нужно, для того чтобы можно было для юзера перемещать значения вверх и вниз, но чтобы ID всегда оставался тем же.

Для этого не обязательно сплошное заполнение. Ставь TIMESTAMP, а при необходимости поменять местами записи - поменяй занчение.
 

Автор: InfMag 24.5.2006, 13:21
Ignat, 
Цитата(InfMag @  24.5.2006,  13:49 ) 
Ignat, нет, то что ты написал я уже предлагал 
>>> Вчитайся  

Я точно тебе говорю.

А вот при создании тейбла поставить дефольт MAXINT это идея! smile Спасибо!

Добавлено @ 13:25 
Код

CREATE TABLE `admins` (
`id` INT NOT NULL AUTO_INCREMENT,
`login` TEXT,
`password` TEXT,
`n` INT NOT NULL,
PRIMARY KEY (`id`)
);

INSERT INTO `admins` (`login`, `password`) VALUES ('admin', MD5('admin'));

А что писать то?
Код

`n` INT NOT NULL DEFAULT MAXINT
 - не проходит

Добавлено @ 13:31 
Темка конечно переходит уже к теме mysql, но все же, как по дефольту проставить maxint? 

Автор: Ignat 24.5.2006, 13:34
Цитата(InfMag @  24.5.2006,  14:21 Найти цитируемый пост)
А что писать то?

что-то вроде
Код

`n` INT (11) UNSIGNED NOT NULL DEFAULT 4294967295
 

Автор: InfMag 24.5.2006, 13:47
Ignat, Ура! smile
Я пишу
Код

`n` INT NOT NULL DEFAULT 9999999999

И он сам ставит максимум возможного 

Автор: madFobos 24.5.2006, 22:27
Цитата(InfMag @  24.5.2006,  13:47 Найти цитируемый пост)
    
`n` INT NOT NULL DEFAULT 9999999999


Я такой извращенский метод первый раз вижу smile Сделай уж лучше n тогда AUTOINCREMENT. И по-моему есть еще какой-то параметр для таблицы, чтобы AUTOINCREMENT подставлялся автоматом в зависимости от текущего максимального значения колонки, а не от того, которое было когда-то максимальным...
 

Автор: igorold 25.5.2006, 06:11
у него id, я так понял уже AUTOINCREMENT ...
InfMag,  - тебе надо сортировать твои записи с использованием поля n
и если тебе не нужны пропуски чисел и надо сохранить прежнюю сортировку, то делай свою функцию с сортировкой по n, а не по id:
Код

    $res = mysql_query("SELECT * FROM `".$table."` ORDER BY `N` ASC");
 

как уже писал Ignat, а при вводе новой записи n можно присваивать id, а не какое-то максимальное число ..... 

Автор: madFobos 25.5.2006, 12:16
Цитата(igorold @  25.5.2006,  06:11 Найти цитируемый пост)
у него id, я так понял уже AUTOINCREMENT ...


Если оно AutoIncrement, то ему вобще не нужно думать об N в момент вставки. Тупо вставляй остальную инфу в таблицу и все. А потом уже делай с N что хочешь.
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)