Автор Тема: как да вмъквам записи в номериран лист  (Прочетена 2335 пъти)

nov_chovek

  • Напреднали
  • *****
  • Публикации: 536
  • Distribution: Ubuntu 8.10 по принуда
  • Window Manager: Gnome
    • Профил
    • WWW
Идеята ми е следната:

Имам таблица с две полета: ID и position

Позициите(Поле positions) се номерират с цели числа и са последователни - 1,2,3,4,5 и т.н.

Проблема ми е как да вмъкна примерно нов запис, който да е между 2 и 3, така че той да стане 3 а 3=4, 4=5, 5=6.

Т.е. при вмъкване, останалите записи да се ъпдейтват с едно нагоре??

Немога да го измисля това... '<img'>(
Активен

pink

  • Напреднали
  • *****
  • Публикации: 94
    • Профил
    • WWW
как да вмъквам записи в номериран лист
« Отговор #1 -: Jun 11, 2007, 12:33 »
Просто трябва да увеличиш позицията на елементите след току що вмъкнатия:

UPDATE my_table SET position = position + 1 WHERE position >= 3;
INSERT INTO my_table (Position) VALUES (3);



Активен

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
как да вмъквам записи в номериран лист
« Отговор #2 -: Jun 11, 2007, 12:47 »
Така е, но когато ID е зададен като primary key, такова увеличение би довело до конфликт, защото не може да има 2 реда с едни и същи стойности на ID. Ето защо трябва увеличението с единица да започне от най-голямото число към най-малкото. Ще трябва един цикъл да се врътне в php или perl (може и bash, ама който иска, да го направи там). Като се освободя към края на деня, ако някой не ме е преварил, ще ти драсна скрипта. Пък можеш и ти да помислиш по въпроса, не е кой знае какъв скрипт  '<img'>
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

nov_chovek

  • Напреднали
  • *****
  • Публикации: 536
  • Distribution: Ubuntu 8.10 по принуда
  • Window Manager: Gnome
    • Профил
    • WWW
как да вмъквам записи в номериран лист
« Отговор #3 -: Jun 11, 2007, 12:55 »
neter: ами ID e primary key, обаче аз при вкарване на новата position, вкарвам и нов primary key ж полето ID. Той се взема от друга таблица, където също е праймъри кий. Т.е. май няма да се получи конфликт, защото дефакто не се променя ничий ID, а просто се добавя ново поле с ново ID  и вмъкната позиция.

Довечера ще го пробвам това.
Активен

pink

  • Напреднали
  • *****
  • Публикации: 94
    • Профил
    • WWW
как да вмъквам записи в номериран лист
« Отговор #4 -: Jun 11, 2007, 14:02 »
nov_chovek: абсолютно си прав - няма да има конфликт. Даже и колоната Position да е обявена UNIQUE, UPDATE заявката ще работи.

Относно ID - препоръчвам ти да не primary key, а да е foreign key към таблицата от която се генерира ID-то. Също така добави constrain UNIQUE INDEX на ID (за да ти се гарантира one-to-one relation със другата таблица. (предполагам ползваш ползваш InnoDB)
Активен

nov_chovek

  • Напреднали
  • *****
  • Публикации: 536
  • Distribution: Ubuntu 8.10 по принуда
  • Window Manager: Gnome
    • Профил
    • WWW
как да вмъквам записи в номериран лист
« Отговор #5 -: Jun 11, 2007, 14:26 »
pink: Ами там е работата, че незнам моя хостинг дали ползва InnoDB. Затова реших да го направя със LAST_INSERT_ID() - така прехвърлям ID-то.
Активен

alex_c

  • Напреднали
  • *****
  • Публикации: 122
    • Профил
как да вмъквам записи в номериран лист
« Отговор #6 -: Jun 11, 2007, 14:28 »
Да взена да изокам и я  '<img'> С моите откъслечни познания по Бази данни се питам защо е нужно подреждането на записите по големината на стойностите в полето position - доколкото си спомням, едно от свойствата на релационните бази данни е, че няма зависимост между позициите на записите в дадена таблица (поправете ме, ако греша). Та в случая - щом полето ID ти е primary key, защо е нужно това сортиране на елементите в колоната position. Ако се касае до визуализирането на извадка от таблицата в някаква форма, то подреждането може да се извърши от съответния middleware софтуер - perl, php, специализирана програма, още повече, че ако се прави извадка от тази таблица, може да има ситуация, в която записите в извадката няма да бъдат със строго последователни номера на елементите position.

Best wishes!
Alex
Активен

VladSun

  • Moderator
  • Напреднали
  • *****
  • Публикации: 2166
    • Профил
как да вмъквам записи в номериран лист
« Отговор #7 -: Jun 11, 2007, 14:50 »
@alex_c

Аз също използвам подобно поле в БД за сайтове - прим. в таблицата на менютата им задавам ред на визуализация. Най-лесно е да стане по-този начин според мен.

ПП: Хм, това с отделната таблица за релация на позициите ми се струва излишно, макар че това зависи от приложението де '<img'>



Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
как да вмъквам записи в номериран лист
« Отговор #8 -: Jun 11, 2007, 16:09 »
Ех, pink, наизуст ли говориш? Вземи изпълни заявката, която си дал и виж няма ли да ти каже, че имаш Duplicate Key?! Ето го обещания от мен скрипт
Примерен код
#!/usr/bin/php5
<?

$host = "";
$db_user = "";
$db_password = "";
$db_name = "";
$table_name = "";

$insert1 =; // Nomer na noviq red (id)
$insert2 = ""; // Sydyrjanie na noviq red (position)

###### NADOLU PROMENI SAMO IMENATA NA KOLONITE, AKO SE NALAGA ######

$db = mysql_connect("$host", "$db_user", "$db_password");
mysql_select_db("$db_name",$db) or die("Could not connect to $db_name" . mysql_error());

$broi = "SELECT * FROM $table_name";
$broi1 = mysql_query($broi);
$broi2 = @mysql_num_rows($broi1);

while ($broi2 >= $insert1) {                                                                                                              
    mysql_query("UPDATE proba SET id = id + 1 WHERE id = '$broi2'");
    $broi2 = $broi2 - 1;
}  

mysql_query("INSERT into $table_name SET id = '$insert1' , position = '$insert2'");

?>

Не забравяй да промениш имената на колоните в INSERT и UPDATE, ако ти се казват по различен начин. А ако си с php4, замени надписа за php5 на първи ред със запис за php4 и махни знака @ пред mysql_num_rows



Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

Hapkoc

  • Напреднали
  • *****
  • Публикации: 2117
    • Профил
как да вмъквам записи в номериран лист
« Отговор #9 -: Jun 11, 2007, 16:31 »
neter, нещо мисля че не си разбрал съвсем условието...

CREATE TABLE table1 (
  id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
  position INTEGER NOT NULL,
  value VARCHAR(100)
);

Аз поне така си представям таблцата. Сега какъв конфликт на първичния ключ може да има, при положение, че никой не го закача него:

UPDATE table1 SET position = position + 1 WHERE position >= 3;

?
Активен

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
как да вмъквам записи в номериран лист
« Отговор #10 -: Jun 11, 2007, 16:42 »
Ахааа, възможно е. Извинявам се на всички, ако съм сгрешил.  ':p'
Но... карай. Ей го скрипта, току виж на някой му свърши работа за нещо. Всъщност той и за другата цел става, само трябва да се редактират имената на колоните  '<img'>
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

pink

  • Напреднали
  • *****
  • Публикации: 94
    • Профил
    • WWW
как да вмъквам записи в номериран лист
« Отговор #11 -: Jun 15, 2007, 10:12 »
За "туря пепел" на темата - netter, твоя скрипт има конкурентен проблем. Възможно е някой да вмъкне запис между твоите SELECT и UPDATE заявки, така новия запис няма да бъде с нова позиция и ще имаш еднакви индекси. За целта използвай LOCK TABLE my_table преди SELECT и UNLOCK TABLES след последния INSERT.

Виж това: http://en.wikipedia.org/wiki/Atomic_operation#Example
Ще ти спести главоболия
Активен

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
как да вмъквам записи в номериран лист
« Отговор #12 -: Jun 15, 2007, 10:48 »
Да, прав си. Трудно е да се случи такова нещо, но не е невъзможно, особено ако въпросната таблица съдържа голям брой записи. Е, на мен главоболия няма да ми създаде, защото за момента нямам нужда от такъв скрипт, но ако някой ден ми потрябва, ще го имам предвид. Колкото и трудно реализуем да е един проблем, той си е пак проблем и трябва да бъде отстранен. Мерси  ':ok:'
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти