[MySQL] Zmniejszenie wartości kolumny o 1

[MySQL] Zmniejszenie wartości kolumny o 1
KI
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:64
0

Cześć. Sprawa wygląda następująco. Posiadam pewną tabelę. Znajduje się w niej kolumna, która jest ustawiona jako unique. Znajdują się w niej liczby od 1 do X. Ta kolumna służy mi do tego aby sortować na stronie WWW ręcznie rekordy z tej tabeli.

Mam napisaną taką funkcjonalność, która umożliwia usuwanie danych z tej tabeli. Jeśli usuwam rekord, który w kolumnie z sortowaniem miał wartość na przykład 6, chcą aby kolumny z wartością > 6 zmniejszyły się o 1 aby zachować spójność w sortowaniu.

W tym celu wykonuję takie zapytania:

Kopiuj
                        $db->query("START TRANSACTION") or die($db->error);
                        $q1 = $db->query("DELETE FROM objects WHERE object_id = '".$id."'") or die($db->error);
                        $q2 = $db->query("UPDATE objects SET object_order = object_order - 1 WHERE object_order > '".$order."'") or die($db->error);
                        
                        if($q1 && $q2) {
                            $db->query("COMMIT") or die($db->error);
                        } else {
                            $db->query("ROLLBACK") or die($db->error);
                        }

Niestety. Pierwsze zapytanie dostaje wartość true, drugie wywala błąd "Duplicate entry for key ...". Zmienna $order ma prawidłową wartość więc problem leży w bazie danych. Oczywiście sprawdziłem zawartość tej kolumny i nie występuje żaden duplikat.

Zapytanie "UPDATE cms_objects SET object_order = object_order - 1" użyte w phpMyAdmin wyrzuca taki sam błąd.

Co robię nie tak? Nie da się tak zmniejszać kolumny, która ma indeks Unique?

edytowany 1x, ostatnio: Kisialala
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 6 godzin
1

Trochę to bez sensu. Co zyskasz przenumerowując ?
Tak się nie robi ...
Przecież po usunięciu wiersza z tabeli bez przenumerowania, sortowanie również będzie działać

edytowany 4x, ostatnio: grzegorz_so
KI
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:64
0

Ma to sens bo nie mam przerw między cyframi w tej kolumnie po usunięciu.
A jak mam funkcje od sortowania to wykorzystuję zmienne $order_actual oraz $order_previous = $order_actual - 1.

To przecież musi tak działać. Pytanie dlaczego nie chce.

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
2

Zdaje się, że mamy do czynienia z typowym problemem X/Y - dlaczego zaprojektowałeś Twoje sortowanie tak, że "nie może być dziur"?
W jaki sposób sortujesz te obiekty?

(btw, actual znaczy prawdziwy - słowo, które powinieneś wykorzystać, to current)


edytowany 3x, ostatnio: Patryk27
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 6 godzin
0

@Kisialala:
jak napisał @Patryk27
Twoim problemem jest sam algorytm sortowania

edytowany 1x, ostatnio: grzegorz_so
cerrato
Moderator Kariera
  • Rejestracja:około 7 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:Poznań
  • Postów:8769
0

@Patryk27: Pozwolę sobie się nie-do-końca zgodzić z tym, co napisałeś odnośnie słowa actual :P

screenshot-20190304213313.png


KI
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:64
0

Nawet jakbym się zgodził na dziury to nie chcę dopuścić do takiej sytuacji, że wiele rekordów będzie miało tą samą wartość order, np 2.

GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 6 godzin
2

Dziury w numeracji a duplikaty coś zupełnie innego.
Samo usuwanie wierszy nie stworzy duplikatów
Uważam że walczysz z problemem który sam sobie stworzyłeś przez niezbyt szczęśliwy algorytm sortowania, który wymaga stałego i równego jeden kroku w polu będącym argumentem sortowania

edytowany 1x, ostatnio: grzegorz_so
KI
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:64
0

Usuwanie nie ale funkcje sortujące już tak.

Nie dyskutujmy na temat mojej metody sortowania. Wyjaśnijcie proszę dlaczego nie da się zmniejszać wartości kolumny z indeksem Unique nawet poprzez phpMyAdmin. A jeśli się da to czemu to nie chce działać?

GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 6 godzin
0

Usuwanie nie ale funkcje sortujące już tak.

dobrze widzę ???funkcje sortujące tworzą duplikaty ??

edytowany 1x, ostatnio: grzegorz_so
KI
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:64
0

Oto zrzut kawałka tabeli. Może to Wam coś podpowie.

Kopiuj
-- phpMyAdmin SQL Dump
-- version 4.4.12
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Czas generowania: 04 Mar 2019, 21:47
-- Wersja serwera: 5.6.20
-- Wersja PHP: 5.5.15

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Baza danych: `xxx`
--

-- --------------------------------------------------------

--
-- Struktura tabeli dla tabeli `cms_objects`
--

CREATE TABLE IF NOT EXISTS `cms_objects` (
  `object_id` int(10) unsigned NOT NULL,
  `object_order` int(10) unsigned NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8;

--
-- Zrzut danych tabeli `cms_objects`
--

INSERT INTO `cms_objects` (`object_id`, `object_order`) VALUES
(23, 1),
(14, 2),
(16, 3),
(22, 4),
(10, 5),
(17, 6),
(25, 7),
(15, 8),
(24, 9),
(20, 10);

--
-- Indeksy dla zrzutów tabel
--

--
-- Indexes for table `cms_objects`
--
ALTER TABLE `cms_objects`
  ADD PRIMARY KEY (`object_id`),
  ADD UNIQUE KEY `object_order` (`object_order`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT dla tabeli `cms_objects`
--
ALTER TABLE `cms_objects`
  MODIFY `object_id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=56;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 6 godzin
2

@Kisialala:
spróbuj dodać do update klauzlę order by object_order

edytowany 1x, ostatnio: grzegorz_so
R7
To chyba zadziała tylko w MySQL. Order by jest dla SELECTa.
GS
nie wiem jak w innych bazach, ale w Firebirdzie działa
KI
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:64
0

O matko. Taka głupota :D Działa pięknie :)

GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 6 godzin
0

@Kisialala:
to teraz zastanów się dlaczego z klauzulą where działa a bez niej nie

edt.
oczywście miało być order

edytowany 1x, ostatnio: grzegorz_so
KI
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:64
0

Działa już w obu przypadkach. Dokonywało update w kolejności id rekordów a nie kolumny order i trafiało na duplikat.

Dziękuję za pomoc!

GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 6 godzin
2

@Kisialala:
Bez order działało w kolejności przypadkowej, bez żadnej gwarancji porządku

edytowany 1x, ostatnio: grzegorz_so
R7
  • Rejestracja:około 6 lat
  • Ostatnio:7 miesięcy
  • Postów:216
1

Zakładając, że w $order masz wartość pola OBJECT_ORDER dla usuwanego rekordu $id
oraz, że w OBJECT_ORDER mamy np.

10
11
12
13

to problem może wynikać ze sposobu aktualizacji danych w kolumnie i tego raczej nie przeskoczysz.

Skoro od OBJECT_ORDER odejmujesz jeden, a nie masz wpływu na kolejność wykonywania tej operacji,
to może się zdarzyć, że najpierw zostanie wykonane:

OBJECT_ORDER = 12 - 1 = 11

a taka wartość jest w tabeli i masz naruszenie unikalności.

To by mogło zadziałać, gdyby baza aktualizowała rekordy zaczynając od najmniejszej wartości.
Ale nie masz gwarancji jak ona to zrobi.

Tak czy inaczej, daruj sobie to aktualizowanie. Dziury w numeracji w niczym nie przeszkadzają, skoro masz unikalność na tym polu.
Poza tym jest to skrajnie nieefektywne, przy dużej liczbie rekordów to by tylko zamulało bazę.

"nie chcę dopuścić do takiej sytuacji, że wiele rekordów będzie miało tą samą wartość order, np 2."

Skoro pole jest unikalne, to do takiej sytuacji baza nie dopuści.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)