Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL]Optymalizacja bazy danych
Forum PHP.pl > Forum > Przedszkole
kosma
Od kilku dni czytam na temat optymalizacji baz danych aby zrozumieć jak prawidłowo powinna być zbudowana baza aby działała optymalniej i nie rozumiem zasadniczej kwestii, a mianowicie tworzenia wielu tabel w bazie celem zwiększenia jej wydajności. Posłużę się prostym przykładem aby zobrazować o co mi chodzi. Tworzymy bazę w której gromadzone będą dane o użytkownikach i tak mamy:
- imię,
- nazwisko,
- płeć,
- wiek,
- województwo zamieszkania,
- miasto zamieszkania
Rekord w bazie z jedną tabelą wygląda tak:
Cytat
id, Jan, Kowalski, mężczyzna, 30, śląskie, Katowice

lub tak:
Cytat
id, Jan, Kowalski, 1, 30, 12, Katowice

gdzie 1 to mężczyzna, 12- nr województwa (śląskie).
Przykładowo zakładam, że rekordów w bazie mamy milion, mężczyzn w tym jest pół miliona, mieszkańców woj, śląskiego 200tys, mieszkańców Katowic 100tys, imię, nazwisko i wiek - pomijam. Na podstawie powyższego przykładu mam więc w tabeli setki tysięcy powtarzających się pól z płcią, województwem, miastem. Zgodnie z zaleceniami tworzę więc tabelę płeć, województwo i miasto, a w niej gromadzę rekordy z id użytkownika. Tym oto sposobem mam 4 tabele i o ile w tabeli z użytkownikami ubyło mi danych to nie ubyło mi w niej rekordów, przybyło zaś rekordów w trzech nowo utworzonych tabelach. Z miliona rekordów zrobiło się więc 4 mln rekordów i danych objętościowo wcale nie jest mniej lecz co najmniej tyle samo, o ile nie więcej.
Teraz zaś wyszukiwanie; np. na podstawie płci i województwa zamieszkania. Przeszukujemy tabelę płeć w której mamy pół mln numerów id mężczyzn i te pół miliona porównujemy z tabelą województwa w której jest 200tys rekordów z woj śląskiego, po czym sięgamy do tabeli użytkownicy aby pobrać dane tych 200 tys mężczyzn z woj śląskiego.
W zapytaniu użyliśmy warunku płci i woj. zamieszkania ale zapytanie skierowaliśmy do wszystkich 4 tabel, mimo że nie podaliśmy warunku odnośnie miasta zamieszkania to przecież i tą tabelę musimy przeszukać warunkując numerem id użytkownika. Gdy dorzucimy do tego pominięte wcześniej tabele z wiekiem, imieniem lub ewentualnie innymi danymi to wyjdzie nam zapytanie do wielu tabel zamiast jednej.
Dlaczego więc optymalniej jest przeszukiwać wiele tabel zamiast jednej skoro warunki zapytania nam się rozszerzają (o nr id) o tyle o ile tych tabel utworzyliśmy? Przecież gdyby wszystkie dane trzymać w jednej tabeli to zapytanie będzie prostsze, z wykluczeniem GROUP BY, JOIN czy też USING o których to czytałem w kontekście przeszukiwania wielu tabel.
Reasumując:
- rekordów w bazie więcej,
- danych nie ubyło,
- zapytania bardziej skomplikowane
Co więc się zyskuje?
thek
Nie do końca jest tak jak mówisz. Dane typu województwo są innej postaci. Jest tam tabela z id województwa i nie ma powiązania z konkretnym id usera. Czyli ta tabela ma tylko tyle rekordów ile masz unikalnych województw. Dla Polski jest to raptem kilkanaście. W polu województwo zaś pojawia Ci się numerek, po którym jest o wiele szybsze wyszukiwanie niż po stringu. Poza tym krótsze jeśli chodzi o zajmowane miejsce w bazie. To samo z płcią. przechowuj 0 jako kobieta i 1 jako mężczyzna. A teraz porównaj które szybciej się wykona przy szukaniu i ile wszystkie rekordy w bazie zajmują dla obu wersji winksmiley.jpg Twój przykład jeszcze da się optymalizować, ponieważ miasto też może dostać swój id z przynależnością do konkretnego województwa. Zmniejsza to ilość powtarzających się ciągów znakowych, zamiast których pojawiają się liczby, na których wyszukiwanie odbywa się szybciej. A jeśli jeszcze na tym polu jest indeks to zasuwają jak zając na dopingu.
Jak widzisz nie ma tak, że każda z tabel ma równą ilość rekordów. Każda ma ich tyle ile jest możliwości. Po prostu źle zrozumiałeś ideę rozdzielania informacji na tabele.

EDIT: Jeśli trzymasz dane w jednej tabeli to tylko mnożysz dane niepotrzebne. Na dodatek taka tabela szybko rośnie na serwerze i nawet nie zauważysz, kiedy dane zaczną być liczone w setkach MB a potem GB. Próbuj sobie potem zrobić backup bazy w miarę szybko to się pochlastasz. A tak robisz backup poszczególnych, o wiele mniejszych tabel już.

By było zaś, że nie odpowiadam to odpowiem po kolei na Twoje "zarzuty":
- rekordów w bazie więcej
Tak, to prawda, ale tylko gdy chodzi o ilość rekordów. Nie zaś ich miejsce zajmowane fizycznie w bazie. W tym wypadku więcej znaczy mniej.
- danych nie ubyło
To już wierutna bzdura. Sumarycznie przestrzeń jaką zajmują jest o wiele mniejsza niż te same przechowywane jako jedna tabela. Porównaj sumaryczną wielkość pól jako varchar i sumaryczną całej tabeli dodatkowej oraz liczb będących ich identyfikatorami. Jest ona przynajmniej kilkukrotnie mniejsza już nawet dla małej bazy danych.
- zapytania bardziej skomplikowane
Tylko Ci się tak wydaje. Wiele tabel pozwala bardziej optymalnie i szybciej zazwyczaj wykonać pewne operacje, gdyż warunki ograniczające i grupowania przebiegają na tabeli o mniejszej wielkości. Przykład? Szukanie po mieście. Przeszukaj wszystkie rekordy tabeli (dajmy na to 50k rekordów) używając LIKE. Zrób to samo na osobnej tabeli miast, która ma o przynajmniej rząd wielkości mniej rekordów, czyli 5k i wybierz pasujące id z niej a potem z głównej (tej z 50k rekordów) te pasujące id. A zważ, że LIKE wykona się na pewno o wiele wolniej niż przeszukiwanie po liczbach
W sumie więc zapytanie w stylu
  1. SELECT * FROM tabela WHERE miasto LIKE '%jakieś%'
(nie wiemy czy to cała nazwa co podał user!)
kontra
  1. SELECT * FROM tabela WHERE id_miasta IN ( SELECT id FROM tabela_miast WHERE miasto_nazwa LIKE '%jakaś%')

lub
  1. SELECT * FROM tabela t LEFT JOIN tabela_miast m ON t.id_miasta = m.id WHERE m.miasto_nazwa LIKE '%jakieś%'

Przetestuj sobie rozwiązania czasowo a zobaczysz które jest szybsze od którego i ile zajmują wszystkie dane w bazie smile.gif
kosma
Dziękuję Thek za odpowiedź, jednak nadal jest to dla mnie niezrozumiałe, gdyż o ile zauważyłeś to w:
Cytat
id, Jan, Kowalski, 1, 30, 12, Katowice

płeć i województwo zastąpione zostało identyfikatorem numerycznym i nie jest ono powiązane z tabelą płci i województwa, gdyż w tym przykładzie wszystkie dane przechowywane są w jednej tabeli. Nie widzę więc potrzeby aby tworzyć tabelę płci i województwa skoro zapis może wyglądać jak wyżej.
Ja optymalizację na powyższym przykładzie rozumiałem jednak inaczej, a mianowicie tworzy sie dodatkowo tabelę województwo i płeć, po to aby w tych tabelach przechowywać nr id użytkownika zgodny z jego "przynależnoscią", a tym samym ubywa mi danych w tabeli użytkownicy o dane odnośnie płci i województwa. Skoro jednak nie tak to wygląda to tym bardziej teraz nie rozumiem po co owe dwie dodatkowe tabele tworzyć jeśli w tabeli użytkownicy zapis może wyglądać jak wyżej, a już w PHP numerek zostanie przyporządkowany tablicy płci i województw.
Nie potrafię jakoś zrozumieć po co tworzyć kilka tabel i przeszukiwać je wszystkie razem bo przecież trzeba przeszukać tabelę województwa aby konkretnemu numerkowi przypisać nazwę województwa, jeśli to samo można zrobić z poziomu PHP, nie obciążając tym samym bazy. Przecież wiele informacji odnośnie użytkowników zapisywać można w bazie numerycznie, gdyż są to powtarzające się dane, takie jak: płeć, stan cywilny, wygląd i wszystko co da się ująć w ramy i tak zapis odnośnie wszystkich danych użytkownika może poza imieniem, nazwiskiem, nr PESEL czy dokładnym adresem zawierać same liczby.
Być może posłużyłem się zbyt prostym przykładem ale jest to przykład często występujący w objaśnieniach optymalizacji i w żaden sposób on do mnie nie przemawia, bo czy nie prościej, szybciej przeszukać jedną tabelę niż wiele?
Co mnie zastanowiło, mianowicie przypisanie miasta do województwa i o ile nie da się tego w prosty sposób osiągnąć w jednej tabeli to tak jak napisałeś w kilku jest to możliwe, jednak czy dodatkowe warunkowanie sprawdzania właściwości miejscowej miasta (do województwa) nie jest nadmiernym i niepotrzebnym obciążaniem bazy poprzez przeszukiwanie tabel miasto, a następnie województwo aby sprawdzić do którego zostało przyporządkowane?
W jednej tabeli mamy to przecież na dłoni.

Moja wyobraźnia zbyt ograniczona aby zrozumieć konieczność tworzenia dodatkowych tabel i co gorsza komplikowania zapytań w ich przeszukiwaniu i póki co nie widzę w tym optymalizacji, a dodatkowe obciążenie...

Edit:
W chwili gdy pisałem tego posta dodałeś Thek więcej wyjaśnień i zgadzam się z Tobą odnośnie przeszukiwania z warunkiem LIKE, jednak założyłem że takiego warunkowania nie będzie, a przecież i ten sam warunek tyczy się dodatkowej tabeli 'miasta', bo przecież trudno wprowadzić wszystkie miasta z selecta, a nie dać wolną rękę użytkownikowi na wpisanie z palca. Posłużyłeś się identyfikatorem id_miasta, a skąd owy identyfikator ma być znany jeśli nie zastosujemy LIKE do tabela_miasta lub też nie zaufamy użytkownikowi co do poprawności wprowadzonych danych. Czy w tabela_miasta mają być ujęte wszystkie miasta w Polsce (questionmark.gifquestionmark.gif) i po nich (id) znajdziemy miasto użytkownika?

Dlaczego zapytanie:
Cytat
znajdź jakieś_miasto w kolumnie miasta tabeli użytkownicy

wykona się wolniej niż:
Cytat
znajdź jakieś_miasto w kolumnie miasta w tabeli tabela_miast

jeśli miasto będzie przypisane do użytkownika, a więc tyle samo nazw miast co użytkowników...no chyba że jest to tabela z wszystkimi miastami w Polsce (albo na świecie smile.gif ) i do nich przypisani użytkownicy?

Odbiegając troszkę od tematu to zastanawiam się jaki typ pola w bazie wybrać dla danych które przyjmują jedną z 2 wartości czyli 0 lub 1 (on, off) , czy TINYINT będzie odpowiednim typem pola skoro nie będą wykonywane na nim żadne działania? Albo np dla danych w formie numerycznej z zakresu 0-15 (województwa) skoro też nie będą wykonywane na nich żadne działania? Rzekomo INT jest szybsze od TINYINT, tracimy jednak na wielkości ( 1 i 4 bajty), jaki wobec tego typ pola stosuje się przy tego typu danych?
thek
Zakładasz za dużo rzeczy winksmiley.jpg Użytkownikowi z reguły się "nie ufa" i wszelkie dane wprowadzane przez niego lub możliwe przez niego do edycji muszą być ciągle zabezpieczone. Liczby są także pewnym zabezpieczeniem winksmiley.jpg
Ale wracając do wątku... Co z tego, że można zapisywać dane numerycznie w bazie/pliku skoro sięgając do kodu po kilku miesiącach, nie wiesz co 3/4 liczb oznacza i szukasz tego potem smile.gif Takie rozwiązanie z dodatkową tabelą jest bardziej naturalne i przez to przyswajalne nawet dla osoby, która zerka do kodu po raz pierwszy. Teraz wiesz co oznacza 1 i 0 w płeć. Ale czy za rok będziesz to rozróżniał?
Gdy mowa o jednej tabeli to zastanów się... Ile rekordów przetwarza baza gdy zadasz pytanie o miasto i województwo? Za każdym razem wszystkie. To ogromny narzut czasowy w porównaniu do osobnych tabel.
Widać także, że nie pracowałeś wiele z bazami bo byś wiedział, że operacje w nich są często wielokrotnie szybsze niż w PHP. Zwłaszcza przy "obróbce danych". Dlatego "zrzuca się" na nie tyle, na ile jest to sensowne.
Gdy mowa o LIKE to jego użycie jest konieczne w przypadku wyszukiwarki miast. Jeśli użytkownik wpisze Biała i taki parametr podasz jako WHERE miasto = 'Biała' to nie znajdzie Ci nic poza tym dokładnie. A użytkownik mógł mieć na myśli także Bielsko-Biała lub Biała Podlaska. Poza tym wcale nie interesuje nas tabela miast całego świata bądź Polski. Powstaje ona samoistnie w bazie. Jeśli mamy grupę kilkuset tysięcy userów z kilku tysięcy miejscowości to wyszukiwanie wszystkich rekordów używając LIKE jest zwykłym zajeżdżaniem bazy. Lepiej te LIKE zrobić na kilku tysiącach rekordów bazy miast i znalezione id miast wyszukać potem w profilach wszystkich userów. Poza tym zauważ, że może być kilka miast o tej samej nazwie. To zaś oznacza dodatkowe ograniczenie w warunku WHERE, który znowu przyspieszyć może zapytanie wykonując się na kilku tysiącach zamiast kilkuset tysięcach.
Liczba miast w odpowiedniej tabeli nigdy nie będzie większa niż ilość userów (no chyba że kasujemy userów a miast nie, wtedy to jest możliwe) bo przecież skoro nikogo nie ma, przykładowo, z Pcimia Dolnego, to w tabeli miast takiego wpisu nie ma smile.gif A id_miasta znamy bo używam LIKE w zapytaniach w każdej wersji. Tylko inaczej konstruuję je co widać w przykładach. Rozdzielenie tabel przyspiesza zresztą całość serwisu, gdyż nie musimy działać w wielu przypadkach na wszystkich rekordach bazy. Przykład? Wyświetl wszystkie miasta z różną nazwą smile.gif W Twoim wypadku szuka w całej tabeli różnych nazw. U mnie przeszuka tylko konkretna tabelkę kilkukrotnie przynajmniej mniejszą. To samo w wyszukaniem miasta o konkretnej nazwie w konkretnym województwie. Sprawdzę to także w tabeli miasto. Znowu działam na znacznie mniejszej bazie.
Co do formatu danych to ja stosuję zawsze dopasowany do sytuacji. Pole ma tylko określone wartości? No to szukam takiego typu, który najlepiej się dopasuje. Po co mam mieć do dyspozycji cały int z 4 bajtami, skoro i tak używam cząstki tego? A co gdy baza się rozrośnie do setek tysięcy lub milionów rekordów? 3 bajty razy 100k rekordów to już 1/4MB. Teraz popatrz na wartości INT i zapis choćby nazwy województwa lub słowa 'mężczyzna', 'kobieta' w bazie. Ile bajtów mają a ile zajmują w typie tinyint? Przemnóż razy setki tysięcy. I tak samo w każdym przypadku. Szybko się okazuje, że na głupim formacie danych tracisz Megabajty miejsca.

Poza tym znowu patrzysz źle na tabelę miast. Jeśli kilku użytkowników jest z tego samego miasta, to mają oni podany ten sam id_miasta. Ilość danych przy większych serwisach znowu się zmniejsza. Każdy user musiałby podawać inne miasta by liczba była ta sama. Przypisanie zaś mu tego id jest na poziomie skryptu. Sprawdzasz czy miasto takie już istnieje w bazie i czy jest w danym wojewodztwie. Zapytanie jest banalne. Istnieje? Wpisz userowi id miasta, a jeśli nie ma to dorzuć do bazy nowe. Weź po prostu zaprojektuj sobie rozbudowany bardziej serwis i zauważysz, że jedna tabela to bardzo nieefektywne rozwiązanie, bo wszystko dzieje się zawsze na tej tabeli, choć często nie potrzebujesz operacji na całej, ale działasz tylko na konkretnej kolumnie i co gorsze, dane w niej są w formacie spowalniającym całość lub sprawiającym problem. Spróbuj jako parametr w GET przesłać coś z polskimi znakami to zobaczysz o czym mówię winksmiley.jpg

Format liczbowy ułatwia lub rozwiązuje wiele problemów jeśli jest stosowany z głową. Nie zawsze bowiem jest sens go stosować. Czasem dla optymalizacji wręcz dubluje się pewne informacje by niepotrzebnie nie używać JOIN. Posłużę się przykładem z miastami znów. Mamy usera, gdzie jedną z informacji jest miasto pochodzenia. Można to rozwiązać na kilka sposobów. Ja przedstawię dwa by zilustrować problem.
Tabela user z kluczem miasta, Tabela miasta z kluczem województwa, tabela województw.
Ładnie i sensownie podzielone patrząc od strony struktury. Prawda? Tyle by dokopać się do tego z jakiego wojewódzwa jest user musimy dwukrotnie robić JOIN a co jeśli chcemy znaleźć wszystkich userów z danego? W takim wypadku pewnym rozwiązaniem jest pozostawienie struktury jak jest by mieć te same możliwości, ale do tabeli user dodać jeszcze klucz województwa. Funkcjonalności dotychczasowe pozostały, ale jeśli wyszukiwanie po województwach jest częste, to kosztem jednego klucza i zajmowanego miejsca zwiększyliśmy szybkość zapytania.

Innymi słowy tabel nie produkuj na potęgę. Rób to z głową i dostosowuj do potrzeb i funkcjonalności. Ale stosowanie jednej do wszystkiego to tylko niepotrzebne zagracanie jej gorzej się indeksującymi i spowalniającymi całość. Przy nieco większej ilości userów zauważysz przez to znaczne spowolnienie działania. Pamiętaj, że nie można przeginać w żadną stronę. Nie stosuj jednej tylko, ale i nie rozczłonkuj bazy jak popadnie. Stąd projektowanie jest bardzo ważnym momentem, bo od niego zależy jakie problemy w przyszłości nastąpią lub jakich unikniemy.
kosma
Raz jeszcze dziękuję Thek za zabranie głosu i wskazówki. Nie mam żadnego doświadczenia z bazami danych i operuję tylko na jednej, tej której tworzę, dlatego też trudno mi coś przetestować, sprawdzić...
W tej chwili mam 5 tabel:
1. użytkownicy,
2. PW (wiadomości)
3. podgląd (kto odwiedził mój profil)
4. KG (księga gości)
5. ulubieni (lista znajomych)

Miałem jeszcze tabelę - online lecz sprawiało mi problem wyciągnięcie danych z bazy kto jest online i w tabeli użytkownicy dodałem kolumnę online w której co jakiś określony czas aktualizowana jest data i godzina. Ta likwidacja tabeli online jest przykładem na to, że zapytanie do kilku tabel może sprawić trudność, gdyż właśnie z tego powodu rozszerzyłem tabelę użytkowników, a zlikwidowałem - online.
Teraz zastanawiam się czy nie utworzyć jednej tabeli na dane typu CHAR, VARCHAR i TEXT bo i dzięki Tobie uświadomiłem sobie, że właśnie te kolumny tabeli użytkownicy są najmniej optymalne względem przeszukiwania i o ile większość z danych zastąpić mogę wartościami numerycznymi to są jednak takie które pozostaną w postaci alfanumerycznej. Zadam pytanie czy ma sens wyciąganie z tabeli użytkownicy - danych tekstowych jeśli i tak za każdym razem będą one wyciągane z nowo utworzonej tabeli, gdyż są to dane opisowe użytkownika?
Pewnym jest że skomplikuje mi to bardziej zapytania, nie wiem nawet czy sobie z tym poradzę, a póki co przeniosłem je na sam koniec tabeli, gdyż wyczytałem, że skraca to czas przeszukiwania. Przenosząc jednak te dane na koniec tabeli, tabela stała się dla mnie mniej czytelna, bo i na końcu znalazły się login i adres e-mail...czy ja oby nie przesadzam?
Zmiana struktury bazy cofa mnie dużo wstecz i już się boję jak ja przebuduję zapytania które dotychczas z mozołem tworzyłem, może lepszym wyjściem jest sprawdzenie w pracy tego co zrobiłem i późniejsza przebudowa bazy...tyle że już z danymi, bo póki co jest ona pusta?
Mam jeszcze kilka takich technicznych wątpliwości, otóż wyczytałem, że nazewnictwo ma też wpływ na wydajność, a dzisiaj ściągnąłem sobie celem podpatrzenia bazę forum PunBB i widzę, że nazewnictwo tabel i wierszy (kolumn) wcale nie jest okrojone (niektóre ponad 20 znaków) i jak to w takim razie z tym nazewnictwem jest?
Tabela użytkowników forum PunBB ma aż 43 wiersze i są to dane wszelakiego typu, a przy okazji kolejne pytania:
1. czy długość/wartość pola TINYINT ma znaczenie, gdyż widzę tam wartości 1, 2, 3 i czy znaczy to, że pole to zajmować może różną wielkość niż 1 bajt?
2. i to samo pytanie odnośnie pola INT?
3. czy nazwę pliku która przyjmuje losową nazwę w postaci alfanumerycznej, zawsze tej samej długości lepiej zapisać w polu typu VARCHAR czy TEXT?

Starczy na dzisiaj bo ledwo na oczy patrzę, a i tak nic nie zrobiłem od kilku dni bo dumam nad bazą danych sciana.gif
thek
Online bym jednak zostawił jak było. Zauważ, że tam było tylko tyle rekordów ilu jest zalogowanych/gości. A ta liczba z reguły jest mała i jesli dojdzie do kilkuset to jedynie w przypadku ogromnych serwisów/for. Przerzucenie tego do bazy userów sprawiło, że zamiast wyciągać tylko z niej id zalogowanych musisz przeszukać ją pod kątem tego pola i właściwej jego wartości. Różnica w szybkości z czasem będzie bardziej zauważalna.
Co do wyrzucania tekstowych danych z tabeli, ma to jedynie sens gdy te dane są rzadko używane. Login jest często w użyciu, więc pozbywanie się go z tabeli users to z reguły nietrafiony pomysł. Brak wtedy jest łączenia dodatkowej tabeli. Co do wydajności ze względu na nazewnictwo nie testowałem tego więc oddam głos lepiej zorientowanym. Ja używam takiego by było mi się prosto zorientować co jest czym.
Długość pola jakiegokolwiek oznacza ile znaków/cyfr może ono posiadać. Czyli pole int z długością 5 oznacza, że mamy do dyspozycji liczbę 5 cyfrową. To samo jest z innymi typami. Weź jednak pod uwagę, że każdy typ ma swoje ograniczenie i ustawienie choćby TinyInt(4) to bezsens, gdyż pole to ma zakres od -127 do 127, a więc nigdy nie będzie 4 cyfrowe.
Co do pola o stałej długości to zależy od długości ciągu. Text stosuje się w przypadku bardzo długich. Varchar ma ograniczenie do 256, ale może przyjmować zmienną ilość. Char ma określoną długość zawsze i jeśli ciąg jest krótszy to pozostałe znaki są puste. Char ma jednak przewagę optymalizacyjną. System bazy wie, że ciąg ten ma zawsze określoną długość i przez to działania na nim są nieco szybsze niż na Varchar. Jeśli więc ciąg ma stałą długość to bym się ku Char skłaniał.
nospor
Cytat
Czyli pole int z długością 5 oznacza, że mamy do dyspozycji liczbę 5 cyfrową
I tu sie mylisz. dlugosc przy liczbach oznacza jedynie do ilu miejsc liczba ma byc dopelniania zerami gdy ustawimy pole na ZEROFILL. W kazdym innym przypadku podanie dlugosci dla liczb jest bezsensu.

Cytat
Varchar ma ograniczenie do 256
w mysql5 juz nie

Cytat
Char ma jednak przewagę optymalizacyjną. System bazy wie, że ciąg ten ma zawsze określoną długość i przez to działania na nim są nieco szybsze niż na Varchar. Jeśli więc ciąg ma stałą długość to bym się ku Char skłaniał.
I tu tez jest pewien haczyk:
http://forum.php.pl/index.php?showtopic=11...&hl=varchar
kosma
A gdyby pola w których gromadzimy informacje o płci określić jako enum('K','M'), a do danych typu 0 lub 1 enum(0,1)?

W ramach treningu utworzyłem sobie w bazie dwie tabele, z województwami (2,4KB) i miastami (55,2KB), miasta przypisane do id województw. Miasta wyselekcjonowałem z co najmniej prawami gminy i wyszło tego 898 miast. Przeglądając wykaz wszystkich miast w Polsce nie znalazłem wśród nich miasta z nazwą dłuższą niż 30 znaków, to też pole typu VARCHAR określiłem limitem 30.
Zastanawiam się nad indeksami w tabeli miast, czy indeks poza głównym tj. id powinien być na id_woj czy na nazwę miasta?

Jako ciekawostkę dodam, że województwem z największą ilością miast na prawach co najmniej gminy jest woj. Wielkopolskie (109), zaś z najmniejszą ilością Świętokrzyskie (31) Rkingsmiley.png
nospor
Cytat
o płci określić jako enum('K','M')
mozna
Cytat
a do danych typu 0 lub 1 enum(0,1)?
po co?

Cytat
czy indeks poza głównym tj. id powinien być na id_woj
Zdecydowanie tak. Jesli uzywasz innoDB to wogole to powinien byc klucz obcy

Cytat
na nazwę miasta
Jesli nie bedziesz wyszukiwal po nazwie miasta to nie ma sensu. Jesli zas bedziesz wyszukiwał - to jest to bardzo wskazane
kosma
Ale czy
  1. enum('K','M')

będzie bardziej wydajne od
  1. tinyint

z zakresem 0 i 1?
nospor
Są sobie rownoważne. Enum to tak naprawde tinyint tyle ze z dodatkową informacją ze 0 to K a 1 to M
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.