Rozpoczęcie liczenia od nowa przy każdym nowy miesiącu


(arlid) #1

Witajcie. Mam generator numerów zleceń, który wygląda następująco Kolejny numer/MM/YYY. I tu wszystko gra - kolejny numer to po prostu MAX(ID) podniesiony o 1. Jak uzyskać coś takiego, że w przypadku nowego miesiąca numeracja zaczyna się ponownie od "1"? Zapewne musi nastąpić sprawdzanie obecnej daty - to logiczne, ale jak wymusić nowe generowanie liczb?

Z tego co myślałem to odpada generowanie numeru po ID z innej tabeli, bo ono jest unikalne. Można by to zrobić i instrukcją IF, albo SWITCH, ale to chyba nie najlepsze rozwiązanie.


(Fizyda) #2
  1. Napisz za pomocą czego chcesz to osiągnąć.

  2. format określający numer zlecenia jest bezsensowny. Powinno być YYYY/MM/ID, albo YY/MM/ID. Najlepiej pierwszy. Dużo łatwiej będzie pobierać dane do analizy niż przy tym co Ty zaproponowałeś.


(arlid) #3

Generalnie numer ma być nadawany przy wysyłaniu formularza. Miesiąc i rok pobrany do zmiennych $miesiac, $rok za pomocą DATE(), więc format można zmienić - rzeczywiście łatwiej będzie pracować z SQLem. Wpadłem na pomysł, żeby “resetować” licznik ID  zlecenia, jeśli DD=1, bo wtedy zaczyna się nowy miesiąc. Tylko nie mam żadnego pomysłu jak zrealizować “reset”. Najprościej chyba byłoby zrobić to w podobny sposób, ale nie wiem czy to dobre wyjście.

 

IF ($dzien=01){
    ...
    $ID=1;
    ...
}else{
    ...
    $ID=$ID+1;
    ...
}

 


(Drobok) #4

Nie zadziała, bo w razie zapytania 1-wszego każdy id będziesz miał 1.

Prościej zapisać sobie poprzedni miesiąc i jeżeli miesiąc jest inny niż ten poprzedni to zresetuj identyfikator.


(Fizyda) #5

Opiszę Ci jak to zrobić, nad samą implementacją nie chce mi się teraz myśleć.

SQL - tabela

id, data, dane…

PK(id, data)

Gdy odbierasz formularz masz date - czyli rok i miesiąc, teraz robisz selecta zliczającego ilość wprowadzonych zleceń w danym miesiącu danego roku, dodajesz +1 i masz id dla aktualnego zlecenia. Bez ifów, a Twój kod nie zadziała, jeśli będziesz chciał dodać 2 zlecenia pierwszego dnia miesiąca masz błąd i naruszenie struktury danych w bazie danych (czy jak to tam się profesjonalnie nazywa).


(Drobok) #6

Mając kolumnę datetime powinieneś użyć:

SELECT dane,id_zlecenia,data FROM tabela WHERE MONTH(data) = $data->format(‘m’);

Nowe id będziesz miał wg powyższego posta: $mysqli_result->num_rows+1;

Data nie może być unikalnym identyfikatorem, więc powinieneś dołożyć pole id. W wypadku gdybyś dostał więcej niż jedno zapytanie w ciągu sekundy.


(Fizyda) #7

“Taniej” użyć SQL-owego COUNT() tak jak pisałem.


(ziggurad) #8

Boże broń przed $mysqli_result itp


(Drobok) #9

Tylko pytanie - skoro autor nie wyświetla listy zamówień przy dodawaniu nowego, po co pytać o cokolwiek tę tabelę skoro można zapisać licznik w tabeli zewnętrznej i zmieniać go 1if, lub przy użyciu crona (update o 0:00 1wszego każdego miesiąca).

Pytanie co szybsze, zapytanie bez agregacji danych, czy 1warunek który można zastąpić cronem.

@**ziggurad, **Trochę wypadłem z obiegu :stuck_out_tongue:


(Fizyda) #10

Takie rozwiązanie jest zagrożeniem dla spójności i integralności danych w bazie danych. Przechowujesz w tabeli wartość którą można pobrać z bazy danych, skoro tak po co w ogóle baza danych. Bazy danych służą do tego by wyciągać z nich dane wszelkiego rodzaju, zapisane w prost lub wyliczone ba bazie znajdujących się w niej danych. Są szybsze, a dobrze zaprojektowana tabela z takim czymś poradzi sobie wystarczająco szybko.

Rozwiązanie z CRON to tworzenie dodatkowej zbędnej usługi o której należy pamiętać podczas zmianach w aplikacji i aktualizacji.

Gdy dojdzie do przypadkowej modyfikacji tej wartości w zewnętrznej tabeli to co w tedy zrobisz? Będziesz nadawał losowe ID? Takim danym nie można ufać bo mogą być przypadkiem zmodyfikowane. W moim rozwiązaniu jeśli pomiędzy ustaleniem ID a insertem w innym wątku zostanie użyty ten ID, wystarczy ponowić operację i wszystko.

W twoim przypadku szybko może dojść do błędu jeśli z różnicą kilku ms będziemy chcieli dodać dane, pierwszy pobierze ID i spróbuje dodać, zmodyfikuje je dopiero gdy uda mu się dodać formularz, a drugi w tym czasie głupieje bo nie udało mu się dodać formularza ponieważ ID już istnieje, teraz co? Sprawdza jeszcze raz ID w zewnętrznej tabeli, a co jeśli znów pobrał wartość przed zmodyfikowaniem wartości? Ile ma czekać? Co ma skrypt zrobić?

 

EDIT:

Poza tym nie każę pobierać całej listy, to Ty to zrobiłeś używając num_rows() ja każę pobrać jedną wartość typu INT określającą ilość zleceń danego roku i miesiąca.


(Drobok) #11

Mój “mysqli” rzeczywiście jest nieoptymalny (count byłby lepszy), ba nawet pobieram zbędne kolumny, mój zamysł był inny, ale po przeróbce posta zostało jak zostało.

W wypadku twojego pobierania “jednej wartości int” wszystkie dane musisz przetworzyć (mysql nie będzie trzymał ilości kolumn dla danego miesiąca w cache, jak to jest z ilością wpisów w danej tabeli). Więc to zapytanie będzie trwało dłużej niż takowe pobierające 1 wartość int z innej tabeli.

Co do tych samych id zwiększę identyfikator przy jego pobieraniu (następne zapytanie otrzyma kolejny identyfikator), a później na spokojnie sobie dodam dane.

Jak wg ciebie miała by nastąpić przypadkowa modyfikacja ?

Wiem że istnieje takie coś jak count, jednak w wypadku dużej bazy danych zliczanie części z nich jest zwyczajnie wolne. A jeśli coś się posypie zliczę sobie id tak jak byś to zrobił ty (tylko w celu odzyskania danych, ale nie widzę kiedy takowa utrata miała by nastąpić)


(Fizyda) #12

Jeśli to nie będą milionowe ilości w danym miesiącu narzut będzie niewielki.

To tak nie działa.

Możliwości jest wiele, a skoro są istnieje ryzyko przeciw któremu należało by podjąć jakieś kroki.

Starałem się wyjaśnić czemu lepiej zrobić tak jak mówię, najwidoczniej nie nadaję się na nauczyciela. Ogólnie sytuacja wygląda tak: każdy może sobie zrobić jak będzie chciał, ja stawiam na skalowalność, tym samym uniwersalność, elastyczność i łatwość modyfikacji w przyszłości. W tej chwili podjęcie decyzji które ułatwią późniejsze eksploatowanie aplikacji zwiększą koszt jej wytworzenia wcale lub minimalnie, później wycofanie pewnych rzeczy i zmienienie ich będzie dużo bardziej kosztowne.

Dlatego jest tyle syfiastego softu na świecie bo jest pisane byle działało, a później będziemy się martwić. Bo ciężko poświęcić tydzień na przemyślenie projektu i znalezienie lepszych rozwiązań.