Czy istnieją relacje warunkowe?

Czy istnieją relacje warunkowe?
K1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5
1

Cześć,
Jestem inżynierem budownictwa i próbuję zastąpić stare ekselki bazą danych typu mysql...
Trochę o bazach czytałem w Internecie, ale praktyka to nie to samo... 🙂
Znalazłem program, który pozwala to trochę ogarnąć na zasadzie drag and drop, działa dobrze jak na moje potrzeby dopóty dopóki relacje są pomiędzy dwoma tabelami....
A ja chciałbym stworzyć relację warunkową... (np, jeśli ID_TypStrony = 1 to relacja z tabelą Reprezentnci, jeśli ID_TypStrony = 2 to relacja z tabelą Pracownicy, jeśli ID_TypStrony = 3 to relacja z tabelą Kontrahenci. Nie wiem czy się da tak zrobić.

Idea:
Umowę można zawrzeć z Reprezentantem, albo z Pracownikiem, albo z Kontrahentem (każdorazowo tylko z jednym użytkownikiem).

  1. Tabela TypStrony ma 3 rekordy: 1=Reprezentanci, 2=Pracownicy, 3=Kontrahenci.
  2. Nie wiem, czy jest zasadne dopisywanie ID_TypStrony do tabel Reprezentanci, Pracownicy, Kontrahenci , bo wartości są identyczne w obrębie całej tabeli.
  3. Czy można zbudować relację, by po wyborze TypuStrony odwoływać się do właściwej tabeli Reprezentanci, Pracownicy, Kontrahenci?
  4. Poniżej print z tego co ułożyłem:

screenshot-20241223163656.png

Wydaje się, że to działa, ale dużo informacji jest zbędnych (o wartości 0) w tabeli Kto.
Pozdrawiam

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10227
4

A czemu Reprezentanci, Pracownicy i Kontrahent to są osobne tabele? Wydawać by się mogło że z powodzeniem mógłbyś mieć dla nich jedną wspólną, np. Osoby, która miała by ID_Osoba, Nazwa, ID_TypStrony oraz dodatkowo kolumnę z rozróżnieniem typu osoby, np 0,1,2. Mógłbyś do tej jednej tabeli wsadzić reprezentantów, pracowników i kontrahentów, i wtedy możesz mieć normalną pojedynczą relację.

flinst-one
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 348
1

Dodatkowo bym budował wszystko wokół tabeli Umowa (tam wsadzać wszystkie dane dot. konkretnej umowy, po co jest StronaUmowa?).

K1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5
0
Riddle napisał(a):

A czemu Reprezentanci, Pracownicy i Kontrahent to są osobne tabele? Wydawać by się mogło że z powodzeniem mógłbyś mieć dla nich jedną wspólną, np. Osoby, która miała by ID_Osoba, Nazwa, ID_TypStrony oraz dodatkowo kolumnę z rozróżnieniem typu osoby, np 0,1,2. Mógłbyś do tej jednej tabeli wsadzić reprezentantów, pracowników i kontrahentów, i wtedy możesz mieć normalną pojedynczą relację.

Osobnymi tabelami sugerowałem się jak w przykładzie z internetu: tabela Uczniowie i tabela Nauczyciele....
Zastanawiałem się nad tym, żeby zrobić jedną tabelę Osoby, ale później będę musiał tworzyć dalsze tabele (inne relacje są z pracownikami, inne z kontrahentami itp), np faktury dla kontrahentów, pensje dla pracowników, upoważnienia dla Reprezentantów, itp... Nie będzie to problemem? Nie będzie problemu, żeby filtrować po tej dodatkowej kolumnie?

flinst-one napisał(a):

Dodatkowo bym budował wszystko wokół tabeli Umowa (tam wsadzać wszystkie dane dot. konkretnej umowy, po co jest StronaUmowa?).

To co zrobiłem, to fragment tego co mam w głowie ;). Założenie jest takie, żeby zrobić małą bazę dla obsługi mojej firmy. Dziś to wszystko mam w ekselach.... Zająłem się fragmentem, uczę się jak to ma działać. Wydaje mi się, że całość powinna działać wokół tabel z ludzmi (kontrahenci, reprezentanci, pracownicy).

Strona Umowy to tabela, która ma przechowywać informację o numerze umowy i kto ją zawarł. Początkowo ID_Kto (kto zawarł umowę) miałem w tabeli Umowy. Później zasugerowałem się jakimś wideo na YT... Może się kiedyś w przyszłości zdarzyć, że z jedną umową będzie związanych więcej niż jedna osoba (coś jak autor i książka).

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10227
2
karol159 napisał(a):

Zastanawiałem się nad tym, żeby zrobić jedną tabelę Osoby, ale później będę musiał tworzyć dalsze tabele (inne relacje są z pracownikami, inne z kontrahentami itp), np faktury dla kontrahentów, pensje dla pracowników, upoważnienia dla Reprezentantów, itp... Nie będzie to problemem? Nie będzie problemu, żeby filtrować po tej dodatkowej kolumnie?

Jeśli będziesz miał tabelę Osoby, w której będziesz miał np 5 reprezentantów (id 1-5), 5 kontrahentów (id 6-10) i 5 pracowników (id 11-15); i będziesz chciał dodać faktury dla kontrahentów, to zrobisz sobie tabelę Invoices w której będzie (ID_Invoice, ID_Osoba) i dodasz faktury dla osób o id 6-10 i tyle.

@karol159 W ogóle mam wrażenie że strasznie gmatwasz tym migrowaniem "excela do bazy". Dużo prościej i lepiej byłoby gdybyś po prostu napisał słownie jakie dane chcesz trzymać - nie słownictwem z baz, nie słownictwem z excela, tylko słownictwem ludzkim. Wtedy moglibyśmy wymyślić spoko strukturę.

jurek1980
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3581
1

Kontrahent, Pracownik, czy Reprezentant mogą mieć różne dane. Jeśli w tym diagramie stosujesz uproszczenia to myśl o rozbiciu tego od razu.
Ja w tabeli kontrahent nie dałbym kolumn typu imię, nazwisko a nazwa firmy, nr NIP. Co Oczywiście nie będzie zapewne miało miejsca dla pracowników, gdzie z kolei będziesz mieć PESEL.
Ale oczywiście wszystko zależy co chcesz trzymać w tych tabelach.
Zobacz sobie tutaj: https://www.sqlpedia.pl/relacyjne-bazy-danych-pojecia-podstawowe/
i poczytaj o relacji wiele do wielu.

K1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5
0
Riddle napisał(a):
karol159 napisał(a):

Zastanawiałem się nad tym, żeby zrobić jedną tabelę Osoby, ale później będę musiał tworzyć dalsze tabele (inne relacje są z pracownikami, inne z kontrahentami itp), np faktury dla kontrahentów, pensje dla pracowników, upoważnienia dla Reprezentantów, itp... Nie będzie to problemem? Nie będzie problemu, żeby filtrować po tej dodatkowej kolumnie?

Jeśli będziesz miał tabelę Osoby, w której będziesz miał np 5 reprezentantów (id 1-5), 5 kontrahentów (id 6-10) i 5 pracowników (id 11-15); i będziesz chciał dodać faktury dla kontrahentów, to zrobisz sobie tabelę Invoices w której będzie (ID_Invoice, ID_Osoba) i dodasz faktury dla osób o id 6-10 i tyle.

@karol159 W ogóle mam wrażenie że strasznie gmatwasz tym migrowaniem "excela do bazy". Dużo prościej i lepiej byłoby gdybyś po prostu napisał słownie jakie dane chcesz trzymać - nie słownictwem z baz, nie słownictwem z excela, tylko słownictwem ludzkim. Wtedy moglibyśmy wymyślić spoko strukturę.

Dane, które chciałbym złożyć:

  1. Moja Firma (nazwa, adres, Telefon stacjonarny, Telefon komórkowy, @, www, NIP, REGON, VAT, Nazwa Banku, SWIFT, Nr konta w PLN, Nr konta w Euro, Reprezentant, Prokurent, Firma Księgowa).
  2. Pracownicy (Zwrot grzecznościowy, Nazwisko, Imię, Adres, data urodzenia, PESEL, telefon, @, Nazwa Banku, SWIFT, Nr konta w PLN, typ umowy (o pracę, zlecenie, dzieło), wielkość etatu (pełen, 1/2, x godzin w miesiącu), data zawarcia umowy, stanowisko, wynagrodzenie, dane do logowania do systemu z uwzględnieniem kilku zakresów dostępności do danych).
  3. Kontrahenci (nazwa, adres, Telefon stacjonarny, Telefon komórkowy, @, www, NIP, REGON, VAT, Nazwa Banku, SWIFT, Nr konta w PLN, Nr konta w Euro, Zwrot grzecznościowy, Pracownicy reprezentujący Kontrahenta + ich dane kontaktowe, branża i podbranża).
  4. Potencjalni Kontrahenci (nazwa, adres, Telefon stacjonarny, Telefon komórkowy, @, www, NIP, REGON, VAT, Zwrot grzecznościowy, Pracownicy reprezentujący Kontrahenta + ich dane kontaktowe, branża i podbranża).
  5. Kontakt z potencjalnymi Kontrahentami (z kim, kiedy, odczucia, czy wstępnie zainteresowani, droga kontaktu).
  6. Zawierane umów (z kim (kilka osób równocześnie), typ umowy (o pracę, B2B itp.), data zawarcia, data wypowiedzenia, termin wypowiedzenia, forma wypowiedzenia).
  7. Kosztorysy (od kogo zapytanie, data otrzymania, data odpowiedzi, numer zapytania, składanie kosztorysu na podstawie świadczonych usług, wartość kosztorysu, status kosztorysu (zaakceptowany, odrzucony, w oczekiwaniu).
  8. Moje usługi ( nazwa, podnazwa, wartość jednostkowa w PLN, wartość jednostkowa w godzinach).
  9. Faktury otrzymane/wystawione (na kogo/od kogo, numer, numer kosztorysu dla faktury, data wystawienia, data płatności, termin płatności, sposób płatności, wartość bez i z Vatem, wartość Vatu, informacja czy zapłacona).
  10. Harmonogram Gantta (uwzględnienie zaakceptowanych kosztorysów, dostępny personel, uwzględnienie potencjalnie zaakceptowanych kosztorysów, współczynnik obciążenia).
  11. Kalendarz spotkań (kto, z kim, kiedy, jak długo, o czym, uwagi).
  12. Wiadomości mailowe.

Wydaje się, że to wszystko. Takie sprawy jak Pracownicy, logowanie, kalendarz spotkań, wiadomości mailowe to przyszłość. W tej chwili jestem samozatrudniony i wierzę, że za jakiś czas będę pracował w zespole.

Wydaje mi się, że złożenie z tych informacji ciekawej bazy zajmie trochę czasu. Sam mam trochę czasu wolnego i chętnie pomajstruję...
Dzięki za zainteresowanie tematem.

jurek1980 napisał(a):

Kontrahent, Pracownik, czy Reprezentant mogą mieć różne dane. Jeśli w tym diagramie stosujesz uproszczenia to myśl o rozbiciu tego od razu.
Ja w tabeli kontrahent nie dałbym kolumn typu imię, nazwisko a nazwa firmy, nr NIP. Co Oczywiście nie będzie zapewne miało miejsca dla pracowników, gdzie z kolei będziesz mieć PESEL.
Ale oczywiście wszystko zależy co chcesz trzymać w tych tabelach.
Zobacz sobie tutaj: https://www.sqlpedia.pl/relacyjne-bazy-danych-pojecia-podstawowe/
i poczytaj o relacji wiele do wielu.

Dzięki za info. Właśnie napisałem co chciałbym mieć w tej bazie. Dokładnie tak jak piszesz, przyjąłem, że Kontrahent, Pracownik, czy Reprezentant mają inne dane.

Schemat jest totalnym uproszczeniem, ponieważ to nie jest moja branża: wiem co chcę otrzymać i szukam informacji. Jak coś znajdę to testuję. Jak działa to idę dalej, jak nie działa to szukam.... I właśnie stanąłem na samym początku, że nie wiem jak połączyć te tabele. Nie było sensu rozbudowywać dalej każdej z tabel skoro nie wiem, czy tak może być...

TR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 119
1

Dane, które chciałbym złożyć:

  1. Moja Firma (nazwa, adres, Telefon stacjonarny, Telefon komórkowy, @, www, NIP, REGON, VAT, Nazwa Banku, SWIFT, Nr konta w PLN, Nr konta w Euro, Reprezentant, Prokurent, Firma Księgowa).
  2. Pracownicy (Zwrot grzecznościowy, Nazwisko, Imię, Adres, data urodzenia, PESEL, telefon, @, Nazwa Banku, SWIFT, Nr konta w PLN, typ umowy (o pracę, zlecenie, dzieło), wielkość etatu (pełen, 1/2, x godzin w miesiącu), data zawarcia umowy, stanowisko, wynagrodzenie, dane do logowania do systemu z uwzględnieniem kilku zakresów dostępności do danych).
  3. Kontrahenci (nazwa, adres, Telefon stacjonarny, Telefon komórkowy, @, www, NIP, REGON, VAT, Nazwa Banku, SWIFT, Nr konta w PLN, Nr konta w Euro, Zwrot grzecznościowy, Pracownicy reprezentujący Kontrahenta + ich dane kontaktowe, branża i podbranża).
  4. Potencjalni Kontrahenci (nazwa, adres, Telefon stacjonarny, Telefon komórkowy, @, www, NIP, REGON, VAT, Zwrot grzecznościowy, Pracownicy reprezentujący Kontrahenta + ich dane kontaktowe, branża i podbranża).
  5. Kontakt z potencjalnymi Kontrahentami (z kim, kiedy, odczucia, czy wstępnie zainteresowani, droga kontaktu).
  6. Zawierane umów (z kim (kilka osób równocześnie), typ umowy (o pracę, B2B itp.), data zawarcia, data wypowiedzenia, termin wypowiedzenia, forma wypowiedzenia).
  7. Kosztorysy (od kogo zapytanie, data otrzymania, data odpowiedzi, numer zapytania, składanie kosztorysu na podstawie świadczonych usług, wartość kosztorysu, status kosztorysu (zaakceptowany, odrzucony, w oczekiwaniu).
  8. Moje usługi ( nazwa, podnazwa, wartość jednostkowa w PLN, wartość jednostkowa w godzinach).
  9. Faktury otrzymane/wystawione (na kogo/od kogo, numer, numer kosztorysu dla faktury, data wystawienia, data płatności, termin płatności, sposób płatności, wartość bez i z Vatem, wartość Vatu, informacja czy zapłacona).
  10. Harmonogram Gantta (uwzględnienie zaakceptowanych kosztorysów, dostępny personel, uwzględnienie potencjalnie zaakceptowanych kosztorysów, współczynnik obciążenia).
  11. Kalendarz spotkań (kto, z kim, kiedy, jak długo, o czym, uwagi).
  12. Wiadomości mailowe.

Ten przykład Uczniowie i Nauczyciele niekonicznie musi być dobrym szablonem w Twoim przypadku.
Koledzy już dużo świetnych wskazówek napisali, ja nie będę za dużo pisał, tylko wrzucam zrobiony na szybko schemat jak bym to z grubsza widział (też jest niedoskonały, bo nie wszędzie trzyma postać normalną, ale poszedłbym w tym kierunku, popatrz o tym możemy porozmawiać).

screenshot-20241226211219.png
ps
tu jeszcze dochdzą niuanse;

  • bo co jeśli pracownik stanie się jednocześnie kontrahentem
  • co jeśli umowa będzie aneksowana

Co do tabeli Kontrahenci/Pracownicy/Reprezentanci - formluarze accessa pozwoliłyby, abyś uzupełniając dane dla danego rodzaju, widział tylko te pola które dla tej grupy są niezbędne (a innych nie) mimo ze w tabeli miałbyś wszystkie pola dla wszystkich (oczywiście musiałyby być opcjonalne).

K1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5
0

Dzięki za wszystkie rady i informacje.
Chyba trochę zaczyna mi się rozjaśniać jak to zrobić 😀

Rozdzieliłem dane mojej firmy (tabela SPOLKA) od Kontrahentów (jako firmy) i Współpracowników (jako ludzi).

Na biało są tabele, w których będę dopisywał nowe dane (nowy bank, nowy adres, nowy Kontrahent, itp.).
Na żółto są tabele, które zmieniają dane danego użytkownika (zmiana adresu Kontrahenta, zmiana banku itp.).

W dalszej części chciałby trzymać się właśnie takiego schematu (dane mogące ulegać zmianom do tabel żółtych 😀 ).
Na pewno pojawi relacja, typu Współpracownik może być albo pracownikiem, albo Kontrahentem itp...

Wstępnie sprawdziłem ten poniższy schemat i działa. Nie wiem czy jest optymalny, ale wydaje mi się, że dla małej firmy optymalizacja nie jest najważniejsza, bo to nie jest mega duży zbiór danych... Drugi rysunek pokazuje jak sobie wyobrażam dodawanie danych, które ulegają zmianie. W przyszłości... ostatni rekord (aktualne dane) będzie zależał od daty (braku daty zakończenia rekordu).

obraz_2024-12-29_193733550.pngRelacje2.PNG

Wydaje mi się, że jeśli nie ma tutaj jakiś błędów krytycznych, to temat można zamknąć.

Raz jeszcze dzięki za wszystkie wskazówki i pomoc.

MY
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1107
1

Dlaczego rozdzielasz tabelę kontrahentów na dwie? Osobiście uważam, że dziwnie to wygląda. Mało to wygodne w obsłudze. Ja bym zrobił jedną tabelę na pełne, aktualne dane kontrahenta. Natomiast jeśli już tak bardzo chcesz mieć całą historię możesz mieć analogiczną tabelę z pełnymi danymi: kontrahenci oraz kontrahenci_historia przy czym w tabeli danych historycznych masz jeszcze dodatkowo pole z numerem wersji. Wtedy na tabeli faktur trzymasz dwa pola kontrahent_id oraz kontrahent_wersja odnoszące się odpowiednio do tabel kontrahenci oraz kontrahenci_historia Takie coś jest bardzo łatwe do zaimplementowania nawet po stronie samej bazy danych za pomocą wyzwalacza. Co tak naprawdę będzie bez żadnego dodatkowego nakładu od strony aplikacji zapisującej dane.

Jak również w realnym przypadku zrezygnowałbym z łączenia tabel adres dla wszystkich podmiotów. Poza tym pytanie czy naprawdę firma albo osoba fizyczna może mieć kilka adresów? Jak spojrzysz na dane zwracane np. przez API GUS'u nie ma tam mowy o kilku adresach. Jest tam po prostu adres siedziby. Tak samo jak adres osoby fizycznej. Odmienną sytuacją jest adres siedziby vs adres korespondencyjny. Jednak zazwyczaj w realnych systemach dane adresowe są w postaci dodatkowych pól w tabeli kontrahenta. Co innego jeśli masz system typu Allegro, gdzie masz kilka adresów do wysyłki. Tu trzeba posiłkować się dodatkową tabelą zawierającą wszystkie adresy gdyż użytkownik sobie wybiera i wpisuje tyle, ile zechce rekordów.

Dalej trochę mały ten podział administracyjny kraju. Jak już chcesz mieć jednostki terytorialne wydzielone do oddzielnych tabel, to zrób to z większą dokładnością. Są przypadki występowania takiej samej nazwy miejscowości z dwóch różnych województwach. Oficjalnie masz dostępny cały podział pod nazwą TERYT i taki należałoby użyć. Inne warianty mijają się z celem słownikowania tych danych.

K1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5
0

Dzięki za rady. Co się tyczy całości, robię to na własne potrzeby; pierwszy raz w życiu, amatorsko, no i jestem budowlańcem 😉 Jeszcze nie wiem co tak naprawdę przyniesie implementacja 😀
Pomyślę nad połączeniem tych tabel... Co do adresów, to nie chodzi o to by mieć kilka adresów jednocześnie, ale żeby wiedzieć w jakim okresie dany adres był przypisany do danej osoby, firmy... Osobiście zmieniałem adres kilkanaście razy... Idea jest taka, by aktualny adres odczytywać na podstawie dat z bazy.

Co do podziału administracyjnego kraju... tutaj nie mogę wchodzić tak dokładnie, bo kontrahenci mogą być zagraniczni. Na razie, do każdej miejscowości przypisuję kod pocztowy państwo....

MY
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1107
2
karol159 napisał(a):

Dzięki za rady. Co się tyczy całości, robię to na własne potrzeby; pierwszy raz w życiu, amatorsko, no i jestem budowlańcem 😉 Jeszcze nie wiem co tak na prawdę przyniesie implementacja 😀

Otóż to, czasami książkowy przykład wydaje się być fajny. Natomiast życie weryfikuje sprawy :D Na przykład dążenie do przesadnej normalizacji danych czasami jest przyczyną kłopotów. Ale o tym na końcu posta ;)

karol159 napisał(a):

Pomyślę nad połączeniem tych tabel... Co do adresów, to nie chodzi o to by mieć kilka adresów jednocześnie, ale żeby wiedzieć w jakim okresie dany adres był przypisany do danej osoby, firmy... Osobiście zmieniałem adres kilkanaście razy... Idea jest taka, by aktualny adres odczytywać na podstawie dat z bazy.

To mógłbyś to wtedy wydzielić faktycznie do innej tabeli. Wtedy wersjonowanie będzie łatwiejsze. Co do szukania adresu po dacie to musiałbyś się zabezpieczyć przed usunięciem nawet przypadkowym rekordu z daną wersją adresu. Szukanie po datach po wszystkich tabelach ręcznie będzie ciężkie. Natomiast jeśli byś miał numer wersji rekordu, wtedy byś mógł założyć odpowiedni klucz zewnętrzny na polach i baza sama by blokowała usunięcie użytego rekordu.

karol159 napisał(a):

Co do podziału administracyjnego kraju... tutaj nie mogę wchodzić tak dokładnie, bo kontrahenci mogą być zagraniczni. Na razie, do każdej miejscowości przypisuję kod pocztowy państwo....

W takim razie odpuściłbym sobie i dał zwykłe pola typu varchar na nazwę miasta, kodu pocztowego oraz ewentualnie państwa. Takie coś nie jest złe. Rozwiązuje jedne problemy, a stwarza inne. Jeden użytkownik wpisze Bielsko-Biała inny BielskoBiała, inny bielsko bi@la z powodu literówki i robi się wtedy kaszana. Szczególnie jak byś chciał potem z tego robić jakieś analizy ze względu na miejscowość. Z kolei jak będziesz miał słownik miejscowości to zmiana nazwy (co się zdarzało nie raz w historii kraju) pociągnie za sobą zmianę we wszystkich archiwalnych dokumentach. Przed tym chroni trzymanie wprost jako pól varchar. W przypadku faktur, umów innych dokumentów i tak musisz drukować dane w postaci w jakiej były w chwili wydruku dokumentu. Więc tych tabel trzymających dane historyczne robi się coraz więcej. Nie raz widziałem formularz wpisywania adresu gdzie dane trzeba było wklepać z palca. Jak widać musisz przemyśleć wszystkie za i przeciw :)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.