Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Struktura tabeli dla dokumentów
Forum PHP.pl > Forum > Bazy danych > MySQL
misiek172
Witam.

Mam mała łamigłówkę i pomyślałem, że poproszę o pomoc bardziej doświadczonych w aplikacjach internetowych.

Pisze program do księgowości i magazynowania, mam problem, jestem na etapie zaprojektowania tabeli baz danych dla dokumentów, zaczynam pierw od Faktury, cały formularz jest już gotowy.

Problem leży w tym, że chce zrobić ją aby była jak najbardziej wygodna do zapisu i odczytu. Dane z faktury będą również używane przy innych dokumentach i odwrotnie, np. wystawianie Faktury na podstawie WZ (wydane na zewnątrz). Jak mają nazywać się kolumny w tabeli aby były wygodne? Tak jak pola w formularzu?

Nie wiem jak dobrze wytłumaczyć mój problem. Ogółem proszę o zasugerowanie struktury tabeli w MySQL dla przechowywanie dokumentów.

Pozdrawiam, Łukasz.

PS: Jak najlepiej przechowywać tablice w MySQL? Serialize odpada bo nie potrzebnie dużo zajmuje i krzaczy się ze znakami typu: " \ etc.
krzyszbi
ja często robię tak ze mam podobne nazwy jak w formularzu + te co dla mnie tylko do oznaczeń potrzebne
pamiętaj ze dane do faktury ( imię nazwisko itp klienta ) najlepiej w osobnej tabeli trzymać a do samej faktury tylko relacja
tablice gdzieś czytałem ze najlepiej przechowywać w formacie JSON choć sam jeszcze osobiście nie stosowałem
takie moje luźne sugestie

p.s. do projektowania polecam DBDesigner-a ( mi bardzo pomaga )
misiek172
Jeszcze dzisiaj spróbuje zaprojektować coś tym programem ale mile widziane dalsze sugestie no i więcej info nt. tych tablic (to mój główny problem)


poczytałem trochę o JSON i jest jeden malutki problem... mianowicie standardowo występuje on od wersji PHP 5.2, w wersja poniżej jest mały problem, aby go mieć musimy mieć dostęp do PEAR.

Więc, jeżeli użyłbym JSON do przechowywania tablic w MySQL, to w przyszłości gdy wylądowałby on na serwerze poniżej 5.2 będzie problem, czyli odpada.
Zastanawiam się czy po prostu nie użyć najzwyklejszego implode();


EDIT:

skorzystałem z tego narzedzia do projektowania bazy danych, jest SUPER!!

mam tylko jedno pytanie, zrobiłem sobie 2 tabele i ustawiłem relacje



i stworzył mi sie klucz o nazwie: TabelaZDanymi_idTabelaZDanymi po co?questionmark.gif Jak ja chciałem użyć do tego wiersza: nrDanych

Moje pytanie brzmi czy do relacji dwóch tabel musi byc klucz i taka nazwa? O co chodzi z tymi relacjami? I tak musze je sam tworzyć za pomocą JOIN, no chyba ze sie same tworzą ... może mi ktoś wytłumaczyć?
nospor
join jedynie łączy tabele ze sobą przy zapytaniu.
Relację służa temu, iż jawnie mówisz, ze ta tabela jest powiązana z tą poprzez takie a takie pole. przyklad:
W fakturze masz fkuser, ktore odnosi sie do tabeli user. dzieki temu w fakturze trzymasz tylko identyfikator user. wszystkie jego dane leża w oddzielnej tabeli. zakladasz relacje. dzieki temu możesz powiedziec, ze nie wolno usunać danego usera, jesli ma on wpis w jakiejs fakturze. Tego pilnuje ci baza, ty nie musisz sie martwic. Jak bedziesz probowal usunac usera, ktory juz jest w fakturze to baza wypluje ci errora.

kolejny przyklad:
user pisze komentarze. w tabeli komentarzy masz znowu fkuser. zakladasz relacje i mowisz, ze gdy dany user zostanie usuniety, to mają zostac usuniete rowniez jego komentarze. I znowu zrobi to za ciebie baza. ty tylko usuwasz usera, a baza robi reszte - usuwa komentarze.

Podsumowując: relacje pomagają zarządzac baza, niedopuszczają do dziwnych sytuacji, ze np. masz komentarze z przypisanym id usera ktory juz nie istnieje. Dobre założenie relacji naprawdę uproszcza wiele rzeczy.
Oczywiscie relacje nie zrobią za ciebie pobrania informacji o userze przy wyswietlaniu komentarza - nadal musisz uzyc join


Co do faktury to zakladasz takie pola, jakie ma faktura. Moze sie to pokrywac z polami z forma i zazwyczaj tak jest.
A po co cie serializowac tablice i zapisywac do bazy to nie wiem. nie powinno sie tego robic. Na takich danych nie mozna robic zadnych sensownych operacji

ps: troche haotycznie mi to wyszlo, ale jestem zmeczony dzis tym liczeniem postow przy akcji z pomogl winksmiley.jpg
Mchl
W mySQL funkcjonalne relacje obsługuje InnoDB. W myISAM można użyc składnie REFERENCES ale właściwie tylko dla dokumentacji.

Jeśli chodzi o przechowywanie faktur itp, ja to robię tak.

Jedna tabela na dane "nagłówkowe" + dodatki o których za chwilę
Kod
DROP TABLE IF EXISTS `faktury`;
CREATE TABLE  `faktury` (
   `ID` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Klucz podstawowy',
   `IDodbiorcy` int(10) unsigned NOT NULL COMMENT 'ID odbiorcy',
   `status` enum('BUFOR','ANULOWANE','ZATWIERDZONE') NOT NULL DEFAULT 'BUFOR' COMMENT 'Stan dokumentu',
   `nrDokumentu` varchar(20) NOT NULL COMMENT 'Nr dokumentu',
   `dataSprzedazy` date NOT NULL COMMENT 'Data Sprzedazy',
   `dataWystawienia` date NOT NULL COMMENT 'Data Wystawienia',
   `sprzedawcaNazwa` varchar(255) NOT NULL COMMENT 'Nazwa sprzedawcy',
   `sprzedawcaAdres` varchar(255) NOT NULL COMMENT 'Adres sprzedawcy',
   `sprzedawcaNIP` varchar(25) NOT NULL COMMENT 'NIP sprzedawcy',
   `sprzedawcaBank` varchar(255) NOT NULL COMMENT 'Bank sprzedawcy',
   `sprzedawcaKonto` varchar(100) NOT NULL COMMENT 'Konto sprzedawcy',
   `sposobZaplaty` enum('GOTOWKA','PRZELEW','GOTOWKA/PRZELEW') NOT NULL COMMENT 'Sposób zapłaty',
   `terminZaplaty` varchar(511) NOT NULL COMMENT 'Termin zapłaty',
   `odbiorcaIndeks` char(7) NOT NULL COMMENT 'Indeks odbiorcy',
   `odbiorcaNazwa` varchar(255) NOT NULL COMMENT 'Nazwa odbiorcy',
   `odbiorcaKodPocztowy` char(6) NOT NULL COMMENT 'Kod pocztowy odbiorcy',
   `odbiorcaMiejscowosc` varchar(255) NOT NULL COMMENT 'Miejscowość odbiorcy',
   `odbiorcaAdres` varchar(255) NOT NULL COMMENT 'Adres odbiorcy',
   `odbiorcaNIP` char(13) NOT NULL COMMENT 'NIP odbiorcy',
   `rabat` decimal(3,2) NOT NULL DEFAULT '0.00' COMMENT 'Rabat',
   `osobaWystawiajaca` varchar(255) NOT NULL COMMENT 'Osoba wystawiająca',
   `upowaznienie` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Zgoda na wystawianie faktury bez podpisu',
   `szablonWydruku` varchar(30) NOT NULL COMMENT 'Sablon wydruku',
   `wydrukRabat` enum('WIERSZE','PODSUMOWANIE','UKRYTY') NOT NULL DEFAULT 'WIERSZE' COMMENT 'Opcje wydruku rabatu',
   `sumaEgz` int(6) NOT NULL,
   `sumaNetto` decimal(8,2) NOT NULL,
   `sumaVat` decimal(8,2) NOT NULL,
   `sumaBrutto` decimal(8,2) NOT NULL,
   PRIMARY KEY (`ID`));


Druga tabele na dane "wierszowe" (świadomie nie do końca znormalizowana)

Kod
DROP TABLE IF EXISTS `faktury_wiersze`;
CREATE TABLE  `faktury_wiersze` (
   `ID` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Klucz podstawowy',
   `dokumentID` int(10) unsigned NOT NULL COMMENT 'Wskazuje na fakturę',
   `towarID` int(10) unsigned NOT NULL COMMENT 'Wskazuje na towar',
   `indeks` char(6) NOT NULL COMMENT 'Indeks towaru',
   `towarDoWydruku` varchar(255) NOT NULL COMMENT 'Towar w wersji do wydruku',
   `ilosc` int(5) NOT NULL COMMENT 'Ilosc',
   `PKWiU` varchar(10) NOT NULL COMMENT 'Symbol PKWiU',
   `cenaNetto` decimal(6,2) NOT NULL COMMENT 'Cena netto',
   `stawkaVat` decimal(3,2) NOT NULL COMMENT 'Stawka VAT',
   `wartoscNetto` decimal(8,2) NOT NULL,
   `wartoscVat` decimal(8,2) NOT NULL,
   `wartoscBrutto` decimal(8,2) NOT NULL,
   PRIMARY KEY (`ID`))


Obciąłem trochę z rzeczywistych definicji, a;e mniej więcej tak to wygląda.
misiek172
dzięki ślicznie bardzo mi pomogły wasze informacje w szczególności nospor'a chciałem przedstawić swój projekt bazy, mam jeszcze tylko jeden problem, są rożne rodzaje relacji, nie do końca wiem których użyć, czytałem trochę w internecie ale nie wyjaśniło to wszystkich moich pytań, proszę o ocenę wydajności i krotki info nt. rodzajów relacji.

o to mój projekt:

Projekt DB.png

z uwagi na rozdzielczość obrazka, daje link.

Z góry dziękuje i pozdrawiam, Łukasz.
phpion
Ale poszalałeś z kluczami głównymi biggrin.gif zaleca się aby klucz główny zbudowany był maksimum na 3 kolumnach, a u Ciebie ta liczba dochodzi do 7 smile.gif
misiek172
one same mi się potworzyły gdy stworzyłem relacje, gdy je wywalę, wywala się relacja
nospor
@phion to nie są klucze glowne a klucze obce winksmiley.jpg glowny jest tylko jeden.
misiek172
mój projekt wgrałem do bazy, włączylem PMA i przetestowalem wedlug informacji nospor'a , dodalem fakture która w każdym polu miała wartość 1, i dodałem klienta o id 1,

według informacji nospor z tego co zrozumiałem nie powinno być możliwe usunięcie faktury ani clienta, jeżeli mają ze sobą relacje, jednak każde z osobna mimo relacji dało się usunąć... czy ja wogóle dobrego typu relacji użyłem w DBDesigner questionmark.gif

Nazywa się on: " New Generalization: A 1 : 1 Relation which has its own graphical representation "
phpion
Cytat(nospor @ 26.09.2008, 12:47:36 ) *
@phion to nie są klucze glowne a klucze obce winksmiley.jpg glowny jest tylko jeden.

O ile pamiętam DB Designer nie oznaczał kluczy obcych za pomocą ikonki kluczyka, a tu ewidentnie widzę takowe w sporych ilościach w tabeli FV i wz (swoją drogą mógłbyś trzymać się jednej konwencji nazewniczej - albo duże albo małe litery).

@misiek:
Powinieneś raczej użyć relacji jeden-do-wielu (1:n)

// Edit:
@nospor: Sprawdziłem - mam rację.

@misiek: użyj tego co napisałem - pierwsza ikonka pod ikonką tabeli.
misiek172
w ten sposób?

Projekt DB2
nospor
Cytat
według informacji nospor z tego co zrozumiałem nie powinno być możliwe usunięcie faktury ani clienta

Nie zrozumiales. wszystko zalezy od relacji i od tego co w niej ustawisz.
http://dev.mysql.com/doc/refman/5.0/en/inn...onstraints.html

@phpion moze masz racje, nie znam tego programu i nie wiem jak oznacza. Ale napisal FK wiec myslalem ze FK tez oznacza kluczem.
phpion
Cytat(misiek172 @ 26.09.2008, 13:17:51 ) *
w ten sposób?

Projekt DB2

Tak, teraz masz poprawnie zdefiniowane relacje. Zauważ, że teraz FV oraz wz mają jeden klucz główny na polu id.


Cytat(nospor @ 26.09.2008, 13:18:58 ) *
@phpion moze masz racje, nie znam tego programu i nie wiem jak oznacza. Ale napisal FK wiec myslalem ze FK tez oznacza kluczem.

Ok smile.gif
misiek172
Ogromne podziękowania za waszą pomoc. Macie duże piwa za to, jak was kiedyś poznam to zapraszam do pubu winksmiley.jpg

Pozdrawiam, Łukasz.

edit:

kurcze stworzyłem baze z referencjami ON DELETE CASCADE

i nie ważne czy usune FV czy klienta i tak nie usuwa jedno drugiego, a według manuala opcja CASCADE, powinna dzialac tak ze jezeli usune FV, usunie się klient. Dlaczego tak nei jest? Jaka opcja jest na to ze jezeli faktura ma id klienta 1, to nie mozna klienta o takim id usunac z bazy?
piaseq
Cytat(misiek172 @ 26.09.2008, 14:27:13 ) *
według manuala opcja CASCADE, powinna dzialac tak ze jezeli usune FV, usunie się klient. Dlaczego tak nei jest?

Chyba nie doczytałeś dokładnie. To działa od tabeli "podrzędnej" w twoim przypadku tabeli klientów do "nadrzędnej" czyli faktury. Więc poprawne działanie opcji CASCADE jest takie, że jeżeli usuniesz klienta zostanie usunięta faktura, nie odwrotnie

Cytat(misiek172 @ 26.09.2008, 14:27:13 ) *
Jaka opcja jest na to ze jezeli faktura ma id klienta 1, to nie mozna klienta o takim id usunac z bazy?

ON DELETE RESTRICT

edit

Tak na marginesie powinieneś zainteresować się prawnymi aspektami przechowywania faktur, a to dosyć obszerna dziedzina. Należałoby wziąć pod uwagę różne ograniczenia z tego wynikające, np.:
- nie można edytować faktury, można co najwyżej wystawić fakturę korygującą
- dane wprowadzone do faktury nie mogą ulec zmianie, tzn., że w przypadku np. zmiany adresu klienta na fakturze wystawionej przed zmianą musi pozostać stary adres
- i wiele, wiele innych.
phpion
Cytat(misiek172 @ 26.09.2008, 14:27:13 ) *
i nie ważne czy usune FV czy klienta i tak nie usuwa jedno drugiego, a według manuala opcja CASCADE, powinna dzialac tak ze jezeli usune FV, usunie się klient. Dlaczego tak nei jest? Jaka opcja jest na to ze jezeli faktura ma id klienta 1, to nie mozna klienta o takim id usunac z bazy?

Usuwanie kaskadowe działa na tej zasadzie, że jeżeli faktura ma klucz obcy w postaci user_id odnoszący się do tabeli użytkowników to usunięcie użytkownika usuwa wszystkie faktury z nim powiązane. Odwrotnie relacja nie działa tj. usuwając fakturę nie usuniesz klienta.

Dlaczego Ci to nie działa? Zakładam, że typy tabel to MyISAM. W MyISAM relacje to w zasadzie ściema tongue.gif Takie gadżety jak usuwanie kaskadowe zadziała Ci w przypadku tabel typu InnoDB.

Ostatni Twój problem: zablokowanie usunięcia klienta, który ma nieopłaconą fakturę rozwiązałbym za pomocą triggerów, aczkolwiek w MySQL triggery są takie, że można sobie je wsadzić winksmiley.jpg
misiek172
niestety nie mam innego wyboru, ponieważ firma dla której to jest przeznaczone nie chce swojego serwera, tylko ma serwer w home.pl (Business Server - ten średni), a on ma tylko MySQL i basta.

Czyli uważasz, że jak przestawię na InnoDB to będzie zapychało? smile.gif

Dlaczego uważasz, że triggery w MySQL są do 4-liter (mam nadzieje, że każdy rozumie co znaczy określenie 4 litery winksmiley.jpg)?


Edit:

w PMA znalazłem błąd:

PMA Database ... błąd[ Dokumentacja ]
Ogólne funkcje relacyjne wyłączone

co jest grane?

Sprawdziłem to home.pl gdzie nie ma błędów w relacjami i też relacje nie działają mi ;/

EDIT:

Dobra działa wszystko, THX for All a w szczególności dla phpion i nospor
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.