Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Rozplanowanie bazy - Problem
Forum PHP.pl > Forum > Bazy danych > MySQL
bahu232
Witam wszystkich,
jest to mój pierwszy post na tym forum.

Planuję napisać prosty katalog firm - rejestracja, wyszukiwanie, promowane oferty itp.
Przy pierwszym punkcie pojawia się mały problem, ponieważ mam w formularzu dużo pól:

-------------------------------
- nazwa firmy
- ulica
- miasto
- wojewodztwo

- telefon1
- telefon 2
- email
- www

- godziny otwarcia (pon-pt; sob; nd)
- krotki opis firmy
- co robi (kilka pol do wyboru)
-------------------------------

Początkowo chciałem to zrobić w jednej tabeli:
  1. CREATE TABLE `znajdwar_glowna` (
  2. `id` INT NOT NULL AUTO_INCREMENT ,
  3. `nazwafirmy` TINYTEXT NOT NULL ,
  4. `ulica` TEXT NOT NULL ,
  5. `miasto` TEXT NOT NULL ,
  6. `wojewodztwo` TEXT NOT NULL ,
  7. `telefon1` TEXT NOT NULL ,
  8. `telefon2` TEXT NOT NULL ,
  9. `email` TEXT NOT NULL ,
  10. `www` TEXT NOT NULL ,
  11. `godzponpt` TEXT NOT NULL ,
  12. `godzsob` TEXT NOT NULL ,
  13. `godznd` TEXT NOT NULL ,
  14. `opis` TEXT NOT NULL ,
  15. `rodzaj` TEXT NOT NULL ,
  16. `data` VARCHAR( 50 ) NOT NULL ,
  17. PRIMARY KEY ( `id` )
  18. );

Jednak zdaje mi się, że to by było za dużo tego wszystkiego, jak wam się wydaje?
Dzięki za odpowiedzi.
thek
To jak będzie wyglądać tabela zależy tylko i wyłącznie od tego JAKIE i ILE chcesz danych umieścić
Na pierwszy rzut oka:
Wywal z tabeli: województwo(możesz ewentualnie zostawić tu id_województwa dla szybkości wyszukiwania), telefon i miasto(zostanie tu id_miasta)
Zrób z nich osobne tabele:

Tabela Telefon:
ID_firmy(index), numer_telefonu

Tabela Województwo
ID_województwa(primary), nazwa_województwa

Tabela Miasto
ID_miasta(primary), ID_województwa(index), nazwa_miasta

W tabeli firmy zaś zamiast miasta ustaw id_miasta

Dzięki temu podziałowi będziesz mógł do firmy przypisać wiele telefonów, zmniejszysz tabelę firm o nadmiarowe kolumny oraz nieco sobie ułatwisz ewentualne zmiany na przyszłość w tabeli miast i województw. Co istotne, w tabeli firm będziesz miał szybsze wyszukiwanie po miastach i województwach, jeśli tam sobie indeksy założysz, bo będzie to o wiele szybsze niż działanie z użyciem LIKE (choć można niby założyć Full index tu na nazwę miasta, ale czy warto to nie jestem przekonany). To tak na szybko winksmiley.jpg
MiChaSSs
Hej bahu232,
Pozwol prosze, ze sie dolacze w Twoim temacie ze swoim pytaniem (szkoda nowego tematu zakladac smile.gif). Czy nalezy zawsze dodawac kolumne ID np. dla wojewodztw? Przeciez one zawsze beda unikalne i mozna po nazwach szukac? Czy wyszukiwanie po nazwach zajmuje wiecej czasu? Co w przypadku gdy mam tabele z ID + jakies inne kolumny i np. duzo rekordow jest dodawane i kasowane dziennie? Wtedy przekroczenie wartosci int duzo czasu nie zajmie (bo MySQL nie zorientuje sie ze nie ma juz np. ID rownego 2 tylko caly czas sobie inkrementuje - chyba ze sie myle?), pozdrawiam MD winksmiley.jpg
thek
Wyszukiwanie po int jest szybsze niż po stringu, do którego musisz użyć LIKE. Do tego po ustawieniu na obu indexów masz jeszcze przyspieszone to. Pojemność int jest wbrew pozorom dla bazy ciężka do wykorzystania szybko, bo kończy się gdzie powyżej 2 miliardów. A tyle rekordów raczej szybko nie przerobisz na swojej stronie smile.gif
Kolumna ID nie jest konieczna w każdym przypadku. Zależy to w dużej mierze od projektu bazy. Jeśli mamy gdzieś pole liczbowe unikatowe, to możemy mu ustawić indeks i wtedy sobie odpuścić możemy ID. Innymi słowy najważniejsze jest dobre przemyślenie bazy. Czasem lepiej jest nawet zdublować pole niż wyrzucić je całkowicie. Przykład mieliśmy nawet tutaj. Mogłem wyrzucić z tabeli Firmy id_województwa, gdyż miałbym tę daną po zrobieniu join z tabelą miast. Mogę jednak równie dobrze zostawić to pole i od razu mogę wyszukiwać firmy po województwie. Oszczędza mi to konieczność łączenia ewentualnego z tabelą miast. To jest jeden z wyborów wielu przed jakimi stają często projektanci baz: zrezygnować z dodatkowej kolumny na rzecz szybkości dostępu czy wyrzucić ją by uzyskać zmniejszenie jej wielkości. Posiedzisz trochę w bazach to takie myślenie się samo wkradnie smile.gif
MiChaSSs
Cytat(thek @ 26.08.2009, 15:36:39 ) *
Wyszukiwanie po int jest szybsze niż po stringu, do którego musisz użyć LIKE. Do tego po ustawieniu na obu indexów masz jeszcze przyspieszone to. Pojemność int jest wbrew pozorom dla bazy ciężka do wykorzystania szybko, bo kończy się gdzie powyżej 2 miliardów. A tyle rekordów raczej szybko nie przerobisz na swojej stronie smile.gif (...)


Dziekuje za odpowiedz winksmiley.jpg. A czy taka skladnia jest rowniez wolniejsza "WHERE nazwa_kolumny='jakis string'" od skladni gdzie bedzie uzyte pole ID? Czyli generalnie wychodzi na to ze w 95% przypadkow nalezy uzywac pola ID - ze wzgeldu na szybkosc wyszukiwania? Bo np. gdy robimy tabele z nazwami uzytkownikow, to loginy i tak musza byc unikatowe wiec teoretycznie mozna by po nich szukac a nie po ich ID. I ostatnie juz pytanie teoretyczne (tak z czystej ciekawosci) tongue.gif co w przypadku gdy przepelnie int-a? Mozna sie jakos przed tym zabezpieczyc?
bahu232
thek,
dzięki za odpowiedź.
thek
Jeśli będziesz miał w jakiś_string ciąg znaków a nie liczbę to baza może Ci przy użyciu = się burzyć, choć z reguły tego nie robi. Do stringów jest LIKE smile.gif Co do przepełnienia int to z tego co wiem mało kto osiąga. Ale jeśli już się zbliża to, możesz zawsze zmienić kolumnę z int na bigint tego już na bank nie przekroczysz biggrin.gif I tak... po int będziesz miał najszybsze wyszukiwanie. Stringi są wolniejsze smile.gif
MiChaSSs
yhm, okej dziekuje winksmiley.jpg
bahu232
thek,
jeśli dobrze rozumiem, ma to wyglądać jak poniżej?
Kod
CREATE TABLE `firma` (
`id` INT NOT NULL AUTO_INCREMENT ,
`nazwafirmy` TINYTEXT NOT NULL ,
`ulica` TEXT NOT NULL ,
`miasto` TEXT NOT NULL ,
`wojewodztwo` TEXT NOT NULL ,
`email` TEXT NOT NULL ,
`www` TEXT NOT NULL ,
`godzponpt` TEXT NOT NULL ,
`godzsob` TEXT NOT NULL ,
`godznd` TEXT NOT NULL ,
`opis` TEXT NOT NULL ,
`rodzaj` TEXT NOT NULL ,
`data` VARCHAR( 50 ) NOT NULL ,
PRIMARY KEY ( `id` )
);

CREATE TABLE `telefon` (
`id` INT NOT NULL AUTO_INCREMENT ,
'numer_telefonu1` TINYTEXT NOT NULL ,
'numer_telefonu2` TINYTEXT NOT NULL ,
PRIMARY KEY ( `id` )
);

CREATE TABLE `wojewodztwo` (
`id` INT NOT NULL AUTO_INCREMENT ,
`id_wojewodztwa` TINYTEXT NOT NULL ,
`nazwa_wojewodztwa` TEXT NOT NULL ,
PRIMARY KEY ( `id` )
);

CREATE TABLE `miasto` (
`id` INT NOT NULL AUTO_INCREMENT ,
`id_wojewodztwa` TINYTEXT NOT NULL ,
`nazwa_miasta` TEXT NOT NULL ,
PRIMARY KEY ( `id` )
);


1. Jako miasto planowałem podstawić jakiś id (np. 1 - Gdańsk, 2 - Gdynia, 3 - Sopot itd.), podobnie chciałem zrobić z województwem (zamiast wysyłać całych nazw jak "Gdańsk"; "Gdynia" itp. > tylko ID).
2. To, że przedrostkiem nazwy jest "id_" coś zmienia?
3. Jak będę wysyłał dane z formularza to będę musiał osobno wysyłać dane do poszczególnych tabel?

Dopiero zaczynam z MySQL, więc proszę o wyrozumiałość smile.gif
thek
1. Jako miasto planowałem podstawić jakiś id (np. 1 - Gdańsk, 2 - Gdynia, 3 - Sopot itd.), podobnie chciałem zrobić z województwem (zamiast wysyłać całych nazw jak "Gdańsk"; "Gdynia" itp. > tylko ID).
2. To, że przedrostkiem nazwy jest "id_" coś zmienia?
3. Jak będę wysyłał dane z formularza to będę musiał osobno wysyłać dane do poszczególnych tabel?

ad 1) I tak właśnie jest. Zauważ, że dlatego mam id zawsze indeksowane, by wyszukiwanie jeszcze przyspieszyć.
ad 2) Nie zmienia nic. To jest dla czytelności kodu. Wiesz wtedy co jest kluczem do innej tabeli.
ad 3) Poczytaj o UPDATE to się sam dowiesz czy możesz tak zrobić czy nie.

Źle. Po pierwsze to mnóstwo razy text używasz, co już "na dzień dobry" spowalnia działanie bazy. Ogranicz się gdzie możesz do varchar. Miasto i wojewódzwo w tabeli firma to mają być INT, bo łączysz je po numerze województwa i numerze miasta. Właściwie to nawet w przypadku województwa możesz tinyint dać. Po co zmieniasz z mojego przykładu rzeczy smile.gif
  1. CREATE TABLE `firma` (
  2. `id` INT NOT NULL AUTO_INCREMENT ,
  3. `nazwafirmy` varchar(100) NOT NULL ,
  4. `ulica` varchar(100) NOT NULL ,
  5. `miasto` int NOT NULL ,
  6. `wojewodztwo` tinyint NOT NULL ,
  7. `email` varchar(75) NOT NULL ,
  8. `www` varchar(75) NOT NULL ,
  9. `godzponpt` varchar(15) NOT NULL ,
  10. `godzsob` varchar(15) NOT NULL ,
  11. `godznd` varchar(15) NOT NULL ,
  12. `opis` TEXT NOT NULL ,
  13. `data` VARCHAR( 50 ) NOT NULL ,
  14. PRIMARY KEY ( `id` ),
  15. INDEX ( miasto ),
  16. INDEX ( wojewodztwo )
  17. );
  18.  
  19. CREATE TABLE `rodzaj` (
  20. `id` int NOT NULL AUTO_INCREMENT ,
  21. `id_firmy` int NOT NULL ,
  22. `nazwa_kategorii` varchar(50) NOT NULL ,
  23. PRIMARY KEY ( `id` )
  24. );
  25.  
  26. CREATE TABLE `telefon` (
  27. `id_firmy` INT NOT NULL ,
  28. numer_telefonu varchar(15) NOT NULL ,
  29. INDEX ( `id_firmy` )
  30. );
  31.  
  32. CREATE TABLE `wojewodztwo` (
  33. `id` tinyint NOT NULL AUTO_INCREMENT ,
  34. `nazwa_wojewodztwa` varchar(30) NOT NULL ,
  35. PRIMARY KEY ( `id` )
  36. );
  37.  
  38. CREATE TABLE `miasto` (
  39. `id` INT NOT NULL AUTO_INCREMENT ,
  40. `id_wojewodztwa` tinyint NOT NULL ,
  41. `nazwa_miasta` TEXT NOT NULL ,
  42. PRIMARY KEY ( `id` ),
  43. INDEX ( `id_wojewodztwa` )
  44. );

To tak ze zmianami na szybko... A czemu? Bo niezbyt jeszcze się orientujesz. Operacje na tekstach są wolniejsze niż na liczbach. Można to przyspieszyć poprzez tworzenie indexów na nich, ale index na danych testowych ma sens przy tworzeniu porządnej wyszukiwarki w oparciu o FULLTEXT. Poczytasz, wprawisz się to wtedy się za to weźmiesz. Na razie opanuj podstawy. dlaczego wywaliłem Ci drugi numer teleonu i zmieniłem nazwę z id na id_firmy? Bo co zrobisz jeśli do firmy masz nie 1 lub 2 ale 7 numerów? Dodasz kolejne pola? Nie w tabeli dodasz kolejny rekord. Po prostu zapytasz tabelkę: "Podaj mi wszystkie numery gdzie id_firmy równa się X". Nie prościej? W województwie wywaliłem id bo skoro jest id i id_województwa to te dane się dublują, więc jedna z kolumn zbędna. Nie wiem co to jest rodzaj, ale domyślam, że to typ działalności firmy (informatyczna, budowlana etc.), więc dorzuciłem jeszcze jedną tabelę I tu podobnie jak z telefonami, możesz przypisać firmę do kilku typów działalności. dopiero porządne zastanowienie się CO ma zawierać baza, JAK ma działać od strony użytkownika, ILE danych ma określonych zawierać sprawia, że się modeluje ją. Ja podałem Ci jak mniej więcej to widzę, ale dopiero znając dokładnie jej model zachowania, można ulepszać dalej.
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.