Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: uzytkownicy a dane logowania
Forum PHP.pl > Forum > Bazy danych > MySQL
goroteb
Witam,
Mam pewien problem. Otoż, załóżmy, że mam dwie tabele:

dane_autentykacyjne: id_da (PK), login, haslo, rola
uzytkownicy: id_uzytkownik(PK), da_id(FK), imie, nazwisko, ulica, miasto, nr domu etc (sporo tego)

tylko jedna rola: klienci ma wpisy w tabeli uzytkownicy, o użytkonikach z innymi rolami (admin, sprzedawca etc) przechowujemy tylko dane w tabeli dane_autentykacyjne. Tak więc tabela uzytkownicy jest niepotrzebna dla wszystkich oprócz jednej ról.

Czy da się to jakoś ładniej zmontować, bez NULLI?
thek
Ja się zastanawiam nad jednym... Skoro robisz podział danych w ten sposób, to czy id_uzytkownik(PK), da_id(FK) nie są identyczne? No chyba że dopuszczasz by wielu userów łączyło się za pomocą tych samych danych lub jeden użytkownik miał wiele różnych ról i każda z nich inny login i hasło. To raz. A pytanie inne to po co cokolwiek zmieniać jeszcze? Zwyczajnie zakładasz ten rekord w tabeli użytkownicy tylko gdy ktoś jest klientem. A to przecież właśnie dobra droga i prawidłowa. Robisz normalnie JOINy jak chcesz, a jeśli już po stronie skryptu wykryjesz, że ktoś nie jest klientem, to wiesz, że i tak w ewentualnych dodatkowych kolumnach napotkasz nulle. Twoje podejście (poza zdublowanymi kluczami, o czym wspomniałem) jest jednak jak najbardziej poprawne i nie unikniesz nulli w kolumnach które nie istnieją. Możesz jedynie próbować je "ukryć" poprzez IFNULL i wpisywanie wtedy pustego stringa czy innej wartości gdzie trzeba, bądż IF i uzupełnienie kolumn, ale nie widzę sensu tego zbytnio.
kalmaceta
Cytat(goroteb @ 14.12.2010, 03:19:19 ) *
Czy da się to jakoś ładniej zmontować, bez NULLI?

ogólnie nie wiem w czym masz problem, jak wcześniej wspomniał thek. Przekombinowałeś ze strukturą, poczytaj o ACL.
goroteb
Po pierwsze to dzięki za odpowiedź. Jeszcze mam jednak pytania.

Cytat
id_uzytkownik(PK), da_id(FK) nie są identyczne?

tak, one sa powiązane ze sobą. Dlaczego zdublowane klucze są niepoprawne? Jak dla mnie to proste PK i FK z referencją do siebie.
Jak inaczej powiązać klienta (czyli rekord w tabeli dane_autentykacyjne z rolą "klient") z dodatkowymi informacjami z tabeli "uzytkownicy"?

Edit:
Aha, no tak. W tym wypadku nie jest potrzebna tabela uzytkownicy. Jedynce co się ostatnie to tabela dane_autentykacyjne z Nullami w przypadku każdej innej roli niż klient w rekordach, tak?


Cytat
Zwyczajnie zakładasz ten rekord w tabeli użytkownicy tylko gdy ktoś jest klientem.

I właśnie zdaje się, że tu mam problem. Bo rekord w tabeli uzytkownicy musi istnieć dla kazdego rekordu tabeli dane_autentykacyjne (dlatego to że jest ta referencja). Przez to miałbym sporo rekordów w tabeli uzytkownicy z NULLAMI.
thek
Skoro klucze są identyczne to jaki jest sens ich dublowania? Masz kolumny, która zawsze są identyczne, co jest zwyczajnym marnotrawieniem miejsca. Na dodatek masz na tych kolumnach indeks jeszcze założony, co jest już podwójnie niekorzystne pod względem zajętości. Wystarczy, że jest ta kolumna tylko raz. To co zrobiłeś nazywa się partycjonowaniem pionowym tabeli. A co jest w tym złego? Popatrz na to tak... Zrób jeszcze 10 takich kolumn w drugiej tabeli winksmiley.jpg To też tylko referencje "do siebie". Samo powiązanie masz już zrobione i nie musisz nic zmieniać. Zauważ, że id_uzytkownik(PK), da_id(FK) rozdzielone nie są potrzebne. Bo przecież ktoś, kto jest użytkownikiem ma także dane autentykacyjne, a więc id_uzytkownik jest równoznaczne wtedy z da_id i tworzenie kolejnego klucza jest bezcelowe, skoro nie widzę byś przewidywał, żeby ktoś miał więcej niż 1 rolę (nie można być jednocześnie userem, adminem i sprzedawcą).

Poza tym widzę, że nie zauważasz faktu, iż tabela może zawierać "luki". Kto powiedział, że każda tabela musi mieć kolumnę z autoinkrementującym się id? Skoro pewne wiersze nie muszą mieć wpisu w tej tabeli to je olej(!) i zwyczajnie do niej nie dodawaj(!). Dla silnika bazy nie ma znaczenia zbytniego czy po rekordzie 1 jest 2 czy 100. Może po rekordzie 100 być nawet 32, czyli teoretycznie wcześniejszy. I tak podczas JOINowania jeśli nie napotka pasującego wiersza, to w brakujących kolumnach wstawi NULL. Twoim kluczem głównym i jednocześnie kluczem obcym w userach jest id_uzytkownik. To czego nie zauważasz, to fakt, że ów rekord nie zawsze musi być dodawany. Wiem, że wrzucanie on cascade lub innych modyfikatorów jest wygodne i zrzuca z odpowiedzialności za poprawność, ale może się kończyć tak jak podałeś -> wstawianiem rekordów zbędnych. Dla mnie sensowne jest jedynie wstawianie rekordu do tabeli userów gdy wykryje, że ma do czynienia z klientem. Ściąga to ze mnie konieczność późniejszego kombinowania czy wpis w tabeli user to rzeczywiście user czy nie. Ja to po prostu wtedy wiem. Nie user nie ma tam wpisu i tyle.

Przykład? Sam mam tabelę, gdzie mam kilka różnych "ról". Jest user, jest klient itp. Mam więc główną tabelę z danymi usera niezbędnymi do logowania, tabelę z danymi usera i tabelę z danymi klienta. Powiązanie jest takie, że klient jest jednocześnie userem, ale już w drugą stronę nie. W efekcie mam tak, że mam strukturę na zasadzie:
auth_id, typ(user, firma, admin czy jakieś inne), inne kolumny
profil_id (równy auth_id), inne kolumny
klient_id (równy auth_id), inne kolumny

Czy ilość rekordów we wszystkich tabelach jest identyczna? Ależ skąd! Tylko auth i profil mają tyle samo. Klientów jest zdecydowanie mniej, ponieważ istnieją w tej tabeli tylko rekordy tych, których auth.typ = klient. U Ciebie jest z tego co widzę identycznie.

Nawet gdybym na pałę napisał JOIN, gdzie auth_id = klient_id to mi baza to zrobi, ale sama uzupełni brakujące dane nullami. Mogę nawet JOINować wszystkie trzy po owych id i też dostanę wyniki. Ale tylko klienci będą mieć wszystkie. Jeśli zaś będę chciał tylko klientów to główna tabelą do której będę łączył pozostałe będzie już nie auth, ale klient. To mi wyeliminuje userów. Pozbywam się dodatkowego WHERE typ=klient z zapytania. Nie po to wprowadza się kilka metod JOIN (left, right, inner, cross, natural, outer) by się różniły nazwami winksmiley.jpg
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.