Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Mój pomysł: brak ID w tabeli, Czy rozwiązanie ma jakieś minusy?
Zajec
post
Post #1





Grupa: Zarejestrowani
Postów: 1 086
Pomógł: 8
Dołączył: 10.12.2003

Ostrzeżenie: (0%)
-----


Potrzebuję stworzyć tabelę, która będzie kojarzyła ze sobą pozycje dwóch innych tabel:

1) Tabela "users" z id użytkownika i jego danymi
2) Tabela "hobby" z id hobby i nazwą hobby

Chcę, aby każdy użytkownik mógł sobie obrać kilka zdefiniowanych przeze mnie hobby. Tworzę więc tabelę z dwoma polami:
1) user_id
2) hobby_id

Teraz pytanie: Czy jest jakiś silny argument, aby dodawać pole id w tabeli łączącej? Zawsze mnie uczono, że id musi być i że ułatwia pracę, ale w tym przypadku szczerze mówiąc nie widzę zastosowania. Gdy user zmienia hobby po prostu kasuję jego dotychczasową listę hobby i tworzę jeszcze raz. Nie mam potrzeby odwoływania się do konkretnego wiersza tabeli łączącej.

Co więcej boję się, że przy częstej zmianie hobby, wartości jej pól "id" drastycznie urosną mimo ogólnie małej ilości wierszy. Dlatego głównie nie chciałbym dodawać pola "id".

Ten post edytował Zajec 6.04.2007, 23:10:03
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 15)
envp
post
Post #2





Grupa: Zarejestrowani
Postów: 359
Pomógł: 1
Dołączył: 16.04.2006
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Oczywiście że id nie musi być. Id jest potrzebne tylko po to aby zidentyfikować wpis (np. gdy chcemy go usunąć) Najlepszym rozwiązaniem będzie chyba zrobienie tej tabeli jako dwóch kolum które dodatkowo są PK, co zapobiegnie zduplikowaniu wpisu...
Go to the top of the page
+Quote Post
NuLL
post
Post #3





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

Ostrzeżenie: (0%)
-----


Zalezy w jakiej bazie - sa takie gdzie mozna zdefiniowac aby para wartosci byla unikalna smile.gif


--------------------
Javascript, Coffeescript, Node.js, Mongo, CouchDb, chmury, workery & inne bajery - zycie jest zbyt krotkie aby miec nudna prace :)
Go to the top of the page
+Quote Post
Zajec
post
Post #4





Grupa: Zarejestrowani
Postów: 1 086
Pomógł: 8
Dołączył: 10.12.2003

Ostrzeżenie: (0%)
-----


Dzięki za odpowiedź. Pominę w takim razie id.

(Baza: MySQL)

Cytat(envp @ 7.04.2007, 00:15:50 ) *
Najlepszym rozwiązaniem będzie chyba zrobienie tej tabeli jako dwóch kolum które dodatkowo są PK, co zapobiegnie zduplikowaniu wpisu...

PK:
Politechnika Poznańska
KB PK
Biblioteka PK
Polski Katalog
Panorama Kultur

Tyle zasugerowało Google. A co Ty miałeś na myśli? ;-)

Ten post edytował Zajec 7.04.2007, 09:47:20
Go to the top of the page
+Quote Post
maryaan
post
Post #5





Grupa: Zarejestrowani
Postów: 380
Pomógł: 2
Dołączył: 5.01.2007

Ostrzeżenie: (0%)
-----


primary key....


--------------------
Wybierasz się do Zakopanego? Odwiedź Willę Pod Górami. Następnym razem na pewno do niej wrócisz :)
Go to the top of the page
+Quote Post
Void(Null)
post
Post #6





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 12.04.2007
Skąd: Błonie

Ostrzeżenie: (0%)
-----


Nie wiem czy dobrze rozumuje, ale...

Jeśli chodzi ci o to aby każdy użytkownik miał w bazie więcej niż jedno hobby to niezbędna ci będzie tabela składająca relacje - jest to klasyczny przypadek encji wiele - do wielu, która nie ma prawa istnieć zgodnie z teorią relacyjnych baz danych. Możesz tak:

USERS

UserID | Name | Cośtam

HOBBYS

HobID | Hobby Name


HobbysOfUsers

AutoID | UID (to klucz UserID z tabeli USERS) | HID (analogiczny z HOBBYS)


pozdr.
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #7





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Zajac: nie musisz robic IDka.

Cytat
Id jest potrzebne tylko po to aby zidentyfikować wpis (np. gdy chcemy go usunąć)


Patrz nizej: nie jest potrzebny
Cytat
Najlepszym rozwiązaniem będzie chyba zrobienie tej tabeli jako dwóch kolum które dodatkowo są PK, co zapobiegnie zduplikowaniu wpisu...

a szukasz rekordu jednoczesnie po user_id i hobby_id i masz jednoznacznie okreslony rekord


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Darti
post
Post #8





Grupa: Zarejestrowani
Postów: 1 076
Pomógł: 62
Dołączył: 6.03.2005
Skąd: Wroc

Ostrzeżenie: (0%)
-----


A ciekawi mnie przypadek, kiedy chcesz wybrać dwóch użytkowników z takimi samymi hobby (np żeby stworzyć 'wspólne koło zainteresowań). Jak wyglądałoby zapytanie w projekcie od @Zajec questionmark.gif


--------------------
The answer is out there, Neo. It's looking for you. And it will find you, if you want it to.
SERVER_SOFTWARE : Apache/2.2.4 (Win32) PHP/5.2.1
MySQL Client API version : 5.0.27
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #9





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Tylko dwoch?
  1. SELECT h.name, u.name FROM hobbies h JOIN hobbies_users hu ON hu.hobby_id = h.id JOIN users u ON hu.user_ud = u.id LIMIT 2


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Darti
post
Post #10





Grupa: Zarejestrowani
Postów: 1 076
Pomógł: 62
Dołączył: 6.03.2005
Skąd: Wroc

Ostrzeżenie: (0%)
-----


@dr_bonzo coś Twoja metoda nie działa, zmontowałem na szybko takie dwie tabelki:
  1. CREATE TABLE `hobbies` (
  2. `user_id` int(5) NOT NULL DEFAULT '0',
  3. `hobby_id` int(5) NOT NULL DEFAULT '0'
  4. ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
  5.  
  6. INSERT INTO `hobbies` VALUES (5, 8);
  7. INSERT INTO `hobbies` VALUES (1, 1);
  8. INSERT INTO `hobbies` VALUES (1, 2);
  9. INSERT INTO `hobbies` VALUES (1, 3);
  10. INSERT INTO `hobbies` VALUES (2, 1);
  11. INSERT INTO `hobbies` VALUES (2, 2);
  12. INSERT INTO `hobbies` VALUES (2, 3);
  13. INSERT INTO `hobbies` VALUES (3, 3);
  14. INSERT INTO `hobbies` VALUES (4, 9);
  15.  
  16. CREATE TABLE `users` (
  17. `user_id` int(5) NOT NULL DEFAULT '0',
  18. `name` varchar(20) NOT NULL DEFAULT ''
  19. ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
  20.  
  21. INSERT INTO `users` VALUES (5, 'piaty');
  22. INSERT INTO `users` VALUES (1, 'pierwszy');
  23. INSERT INTO `users` VALUES (2, 'drugi');
  24. INSERT INTO `users` VALUES (3, 'trzeci');
  25. INSERT INTO `users` VALUES (4, 'czwarty');


i wmontowałem Twoje (podobne) zapytanie (pomińmy że miało być dwóch) :
  1. SELECT hu.name, u.name FROM hobbies h JOIN users hu ON h.hobby_id = hu.user_id JOIN users u ON h.user_id = u.user_id


Powinien wyświetlić tylko userów: pierwszy, drugi (bo mają zainteresowania 1,2,3) a wmieszał się tam jeszcze trzeci dziwnym trafem (bo ma tylko i wyłącznie zainteresowanie 3, ale się wkręcił na imprezkę i nie ma o czym gadać z pierwszym i drugim bo zeszli na tematy 1 lub 2 i trzeciemu grozi picie browara i rwanie lasek koło baru a chciał pogadać winksmiley.jpg ).


--------------------
The answer is out there, Neo. It's looking for you. And it will find you, if you want it to.
SERVER_SOFTWARE : Apache/2.2.4 (Win32) PHP/5.2.1
MySQL Client API version : 5.0.27
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #11





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Darti co nagle to po diable, co prawda tabela z samymi hobby jak i user są niepotrzebne, bo ważne są id obu.
A wybranie dwóch osób, o takim samych hobby wcale nie jest takie proste. Ja chwilowo widzę tylko taką możliwość, że dla danego użytkownika szukamy innych o tych samych zainteresowaniach. Ponieważ jak widz chcesz pełne pokrycie zbiorów zainteresowań.

Wracając do tematu, id jest w tym przypadku zbędne, i ogólnie jak możemy określić unikalne pole lub ich kombinacji, tu UNIGUE(user_id,hobby_id), ale czasem jak jest albo nie możliwe wybranie unikalnych, lub dla prostoty użytkowania dodaje się id.
Dla prostoty: załóżmy że mamy tabele osób i każda ma PESEL (bo tak wynika z wymagań że jest zawsze podany) i można w ten sposób unikalnie identyfikować daną osobę, ale po pierwsze łączenie po polu pesel jest niewygodne i wytwarza o wiele więcej danych (bo każda powiązana musiała by mieć cały pesel), do tego udostępnia pesel osoby a takie dane są objęte ochroną, po drugie możliwe jest że ktoś wprowadzi błędny, a potem będzie chciał poprawić, jak już będzie w wielu miejscach, chyba każdy wie co by to znaczyło.
Tu mamy wewnętrzną identyfikację i prostą unikalność, do tego do tej tabeli nie podłączmy innych do unikalnego rekordu więc można (ale nie musimy) sobie darować pole id.


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
Go to the top of the page
+Quote Post
Darti
post
Post #12





Grupa: Zarejestrowani
Postów: 1 076
Pomógł: 62
Dołączył: 6.03.2005
Skąd: Wroc

Ostrzeżenie: (0%)
-----


Tzn z mojego punktu widzenia ważna jest jedynie tabela 'hobbies', nie interesuje mnie to, jak nazywa się dany user (wystarczy mi ID).
Borykam się z tym problemem (braku unikalnej kolumny - nie mogę zmienić struktury tabel) od dosyć dawna.
Kombinowałem poprzez złączenie dwukrotnie jednej, tej samej tabeli (np pierwsza.hobby_id=druga.hobby_id) ale dawało mi w efekcie elementy 'niepełne' (tutaj niepełne zainteresowania trzeciej osoby).
Temat jest dla mnie niezwykle intrygujący ... po prostu nie lubię wiedzieć że czegoś nie wiem smile.gif A nie wiem jak unikatowo wybrać z takiej tabeli (hobbies) osoby o takich samych zainteresowaniach.
Pomóżcie proszę zapytaniem SQL ....


--------------------
The answer is out there, Neo. It's looking for you. And it will find you, if you want it to.
SERVER_SOFTWARE : Apache/2.2.4 (Win32) PHP/5.2.1
MySQL Client API version : 5.0.27
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #13





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Darti problem nie jest jak mi się wydaje banalny, bo jeśli chcesz wybrać osoby o danym hobby lub nawet kilku to nie jest problem.
Jednak gdy chcesz wybrać osoby o takich samych zainteresowaniach to pamiętaj że każdy może mieć inną długość listy hobby więc dla każdej osoby wybierasz takie które mają taką samą, takich osób może być kilka.
Więc wybierasz osobę i jej zainteresowania np.:
user_id|hobby_id
1|1
1|2
1|3
potem szukasz osoby która ma te zainteresowania, ale tu tracę pomysł jak...
albo mam błędne założenia od początku. Ale wynikiem końcowym będzie tablica o dwóch polach user_id gdzie obaj użytkownicy mają te same hobby (przy czym będzie coś w stylu 1|2 i 2|1 z powodu że to jest relacja dwu kierunkowa)

Mam małe doświadczenie w tworzeniu zapytań i jeszcze nie czytałem żadnej porządnej książki o tym :|

Coś wykombinowałem, działa, ale optymalności to pewnie ani ciut, ciut nie ma:
  1. SELECT `nalezy`.`u_id`,`zawiera`.`u_id` FROM (SELECT `max`.`u_id`,`sum`.`t_u` FROM (SELECT `u2`.`u_id`,count(*) AS `x` FROM `ush` AS `u2` GROUP BY `u2`.`u_id`) AS `max`
  2. JOIN (SELECT `ush`.`u_id` AS `f_u`,`u`.`u_id` AS `t_u`, COUNT(`u`.`h_id`) AS `ile` FROM `ush` LEFT JOIN `ush` AS `u` ON `u`.`h_id`=`ush`.`h_id` GROUP BY `ush`.`u_id`,`u`.`u_id`) AS `sum`
  3. ON (`max`.`x`=`sum`.`ile` AND `max`.`u_id`=`sum`.`f_u`)) AS `nalezy`
  4. LEFT JOIN (SELECT `max`.`u_id`,`sum`.`t_u` FROM (SELECT `u2`.`u_id`,count(*) AS `x` FROM `ush` AS `u2` GROUP BY `u2`.`u_id`) AS `max`
  5. JOIN (SELECT `ush`.`u_id` AS `f_u`,`u`.`u_id` AS `t_u`, COUNT(`u`.`h_id`) AS `ile` FROM `ush` LEFT JOIN `ush` AS `u` ON `u`.`h_id`=`ush`.`h_id` GROUP BY `ush`.`u_id`,`u`.`u_id`) AS `sum`
  6. ON (`max`.`x`=`sum`.`ile` AND `max`.`u_id`=`sum`.`f_u`)) AS `zawiera`
  7. ON (`nalezy`.`t_u`=`zawiera`.`u_id` AND `nalezy`.`u_id`=`zawiera`.`t_u`)
  8. WHERE `nalezy`.`u_id`<`zawiera`.`u_id`


proste nieprawdaż?

i i tabelka taka:
  1. CREATE TABLE `ush` (
  2. `u_id` int(11) NOT NULL,
  3. `h_id` int(11) NOT NULL,
  4. PRIMARY KEY (`u_id`,`h_id`)
  5. )


jak macie lepsze pomysły piszcie.

EDIT próba aby trochę połamało zapytanie

Ten post edytował Sedziwoj 16.05.2007, 23:32:27


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
Go to the top of the page
+Quote Post
Darti
post
Post #14





Grupa: Zarejestrowani
Postów: 1 076
Pomógł: 62
Dołączył: 6.03.2005
Skąd: Wroc

Ostrzeżenie: (0%)
-----


@Sedziwoj jesteś geniuszem w tym temacie smile.gif
działa doskonale, Dzięki wielkie smile.gif


--------------------
The answer is out there, Neo. It's looking for you. And it will find you, if you want it to.
SERVER_SOFTWARE : Apache/2.2.4 (Win32) PHP/5.2.1
MySQL Client API version : 5.0.27
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #15





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


1. Darti: sorry za blad; zle zrozumialem twoja prosbe (mialem wszystkich wypisac userow z jednym, ustalonym hobby -- zapomnialem o WHERE

2. Sedziwoj: WOW, jak ty sie w tym nie pogubiles smile.gif


3. [chyba zaraz dopisze]
edit: albo i nie bedzie, nie mam teraz czasu


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #16





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat(dr_bonzo @ 17.05.2007, 11:33:43 ) *
2. Sedziwoj: WOW, jak ty sie w tym nie pogubiles smile.gif


Tylko czy nie można lepiej tego zrobić, to jedynie mnie martwi...

A co do optymalizacji to po prostu stworzenie tymczasowej tabeli, bo w sumie łączem dwie takie same (LEFT JOIN) więc po co dwa razy używać skomplikowanego zapytania.

I nadal czekam na konstruktywną krytykę, bo może da się coś poprawić, albo ma metoda od założenia była błędna...


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 02:00