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.
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ś.
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;
...
}
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).
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.
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.
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ć)
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ń.