Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wybór optymalnego typu danych
Forum PHP.pl > Forum > Bazy danych > MySQL
MySQL
Problem jest taki:

Mam tabelę z kilkoma polami. Większość z tych pól będzie przechowywać informacje tylko ze zbioru dwuelementowego. Niech to będzie: {"T", "N"} ale rownie dobrze moga to być wartości {0, 1} (nie dopuszczam wartości NULL!). Jakie to będa wartości to już małoistotne, gdyż nie będa one uczestniczyły w klauzulach SELECT. To będa informacje tylko dla administratora. I takich pól jest kilka/kilkanaście (co chwile jakieś nowe powstają w projekcie).

I teraz właśnie zasadnicze pytanie: Czy przy tworzeniu tabeli użyć dla kazdej takiej flagi pola typu ENUM i wowczas niech kazde pole zajmuje po 1 bajt. Czy też może użyć typu jednego pola typu SMALLINT i kazda flaga byłaby reprezentowana przez jeden bit na odpowiednim miejscu w tym typie liczbowym, ktory zajmuje 3 bajty (ewentualnie dam większy jezeli flag jeszcze przybędzie).

Jak juz napisałem wcześniej te pola binarne mają po prostu tylko być w tabeli. Nie posłużą one do zapytan warunkowych.
Skrypt PHP jak odbierze rekord przetworzy te pola (albo wyłuska odpowiednie bity z liczby) i wyświetli odpowienie rzeczy na ekranie. Tak to ma działać.

Jak więc radzicie. Czy zaoszczędzić na pojemności tabeli i użyć typu liczbowego czy jednak każda flaga to osobne pole w tabelce? Jakie jest Wasze zdanie? Jaka jest Wasza praktyka? Ja osobiście skłaniam się aby był to typ liczbowy.
sowiq
Jest jeszcze takie pole jak BIT. Wtedy wiadomo - 1 lub 0, a zajmuje jeden bit.
vsemak
można też skorzystać z TINYINT(1) to jest to samo rozwiązanie z tą różnicą, że możesz używać wszystkich 10 cyfr.
Optymalnym rozwiązaniem będzie VARCHAR(1) czyli jedno znakowe pole, wspomniałeś, że niektóre będą zawierać litery T lub N, wtedy tylko takie rozwiązanie, choć przyznam, że nie powinieneś stosować znaków T i N do określenia stanu pola. Z reguły wykorzystuje się bit 1 i 0.
MySQL
Tylko ze wolalbym aby to nie byl typ BIT, ktory wystepuje w MySQL bo jak trzeba bedzie przeniesc baze n ainny serwer bazodanowy to moze okazac sie ze juz typu BIT tam nie ma :-/
sowiq
http://troels.arvin.dk/db/rdbms/ -> The BOOLEAN type
phpion
Cytat(sowiq @ 6.03.2009, 16:33:15 ) *

W MySQL BOOLEAN = TINYINT(1)
http://dev.mysql.com/doc/refman/5.0/en/num...e-overview.html
sowiq
Na stronie, którą podałem napisali podobnie:
Cytat
MySQL offers a non-conforming BOOLEAN type. MySQL's BOOLEAN is one of many aliases to its TINYINT(1) type.

To teraz rodzi się pytanie - po co w takim razie w bazach zmienne typu BIT? Bo tak na prawdę są to zmienne typu boolean: true/false.

[edit]
już wiem:
Cytat
MySQL has a BIT type which may be interesting for people with enormous amounts of boolean-type data.
jarek_bolo
A może wykorzystaj jedno pole na przechowywanie wartości tych właściwości pod postacią liczby systemu dziesiętnego. Następnie stwórz drugą tabele w której każdy rekord to będzie nazwa nowej właściwości oraz jej miejsce w szeregu wszystkich tych właściwości. Z tego co piszesz tych właściwości jest coraz więcej więc co trochę zmienia Ci się struktura tabeli.

I teraz powiedzmy masz trzy właściwości: pachnie; słodkie; kocha;
Chcąc zapisać np. pachnie = 1, słodkie = 0, kocha = 1 użyjesz wartości dziesiętnej 5, bo 5 dziesiętne po prze konwertowaniu na binarne da Ci 101.

Mam nadzieję, że zrozumiesz co mam na myśli smile.gif
MySQL
jareb_bolo to jest dobre rozwiązanie. O takim nie pomyślałem :)

Jednakże skoro i tak ta wartość dziesietna byłaby w tabeli zasadniczej to wyciągnięciem z niej wartości odpowiednich bitów zająłby się skrypt PHP poprzez operacje przesuwania bitowego oraz &. Dlatego jednak wolałbym zrezygnować z tej dodatkowej tabeli choć sam pomysł wydaje mi się bardzo elokwentny.

Rzeczywiście właściwości przybywa ale nawet jeżeli wykorzystałbym Twój pomysł z drugą tabelą, to zauważ że gdybym w zasadniczej tabeli na tą przechowywaną wartość przeznaczył pole UNSIGNED BIGINT i cieszył się, że mogę zapisać aż 264 różnych wartości, to i tak w drugiej tabeli musiałbym użyć tego samego typu jako klucz główny. Czyli takie rozwiązanie nie przestaje mnie ograniczać na ilość wartości przechowywanych. Wszystkich flag mógłbym mieć tylko (a w tym projekcie można użyć słowa AŻ!) 64.

Oczywiście teraz tych flag jest 15 i chyba na tym się skończy.

I właśnie dlatego wołałbym odpowiedzi na moje pierwotne pytanie: Czy każde pole oddzielnie typu ENUM czy jedno pole liczbowe. Oczywiście wasze odpowiedzi są super i za wszystkie dziękuję.

Jednakże za użyciem pola liczbowego przemawiają trzy rzeczy:

1. jeżeli użyję kilkunastu pól typu ENUM, to automatycznie jestem ograniczony na ilość flag. Gdyby nowa kiedyś miała powstać to trzeba by było zrobić jedną dodatkowa tabelę i robić złączenia. Używając typu liczbowego odpowiednio dużegu, nawet BIGINT mam jeszcze nie jedno ale aż 49 dodatkowych miejść na flagi. Dodam od razu, że gdyby tabela miała jeszcze "urosnąć" to maksymalnie o 1 - 2 flagi. Zatem miejsc jest wystarczająco dużo. Oczywiście, że zawsze można dodać kolunmę do schematu tabeli ale powiedzmy, że wolałbym tego nie robić. Ustalić tabelę raz i koniec.

2. Użycie typu liczbowego (nawet niech będzie to BIGINT) to użycie tylko 8 bajtów, użycie nawet 15 pól ENUM to użycie 15 bajtów.

3. Operacje na liczbach w bazach danych są szybsze niż na łańcuchach znaków.
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.