Ponieważ wydaje się, że MySQL nie ma żadnego typu danych „boolowskich”, jaki typ danych „nadużywasz” do przechowywania prawdziwych / fałszywych informacji w MySQL?
Zwłaszcza w kontekście pisania i czytania ze skryptu PHP.
Z czasem wykorzystałem i widziałem kilka podejść:
- tinyint, pola varchar zawierające wartości 0/1,
- pola varchar zawierające ciągi „0” / „1” lub „true” / „false”
- i na koniec wylicza pola zawierające dwie opcje „prawda” / „fałsz”.
Żadne z powyższych nie wydaje się optymalne. Wolę wariant maleint 0/1, ponieważ automatyczna konwersja typów w PHP daje mi raczej wartości logiczne.
Jakiego typu danych używasz? Czy istnieje typ zaprojektowany dla wartości boolowskich, które przeoczyłem? Czy widzisz jakieś zalety / wady wynikające z używania takiego czy innego rodzaju?
mysql
boolean
sqldatatypes
Peter Mortensen
źródło
źródło
bit(1)
jest trochę ** do zaimportowania do Excela. Przejście dotinyint(1)
prac.Odpowiedzi:
W przypadku MySQL 5.0.3 i nowszych można użyć
BIT
. Instrukcja mówi:W przeciwnym razie, zgodnie z instrukcją MySQL, możesz użyć bool i boolean, które są w tej chwili aliasami tinyint (1):
MySQL stwierdza również, że:
Odnośniki: http://dev.mysql.com/doc/refman/5.5/en/numeric-type-overview.html
źródło
!$boolean
który nigdy nie oceni poprawnie bez dalszego przetwarzania.auto_increment
w kolumnie reprezentującej wartość logiczną?BOOL
iBOOLEAN
są synonimamiTINYINT(1)
. Zero jestfalse
, wszystko inne jesttrue
. Więcej informacji tutaj .źródło
(1)
robi nic więcej, jak określić sposób wyświetlania wartości, jeśli jesteś świadomy wielkości pamięci, toBIT
zamiast tego chcesz użyćBIT(1)
iTINYINT(1)
oba wykorzystają jeden bajt pamięci. Aż do MySQL 5.0.3BIT
był właściwie synonimemTINYINT
. Późniejsze wersje MySQL zmieniły implementację BIT. Ale nawet przy zmianie implementacji, nadal nie ma korzyści dlaBIT
typu danych „wielkości pamięci” (przynajmniej w przypadku InnoDB i MyISAM; inne silniki pamięci, np. NDB, mogą mieć pewną optymalizację pamięci dla wielu deklaracji kolumn BIT.) Większy problem polega na tym, że niektórzy klienci biblioteki nie rozpoznają ani nie obsługują zwracanychBIT
kolumn typu danych.TINYINT
Lepiej działa.true
” nie jest prawdziwe.SELECT 'foo' AS bar FROM dual WHERE -7
. Wyrażenie -7 jest oceniane w kontekście logicznym, a zapytanie zwraca wiersz. Możemy przetestować za pomocą 0 lub dowolnego wyrażenia, którego wynikiem jest liczba całkowita 0, i żaden wiersz nie jest zwracany. Jeśli wyrażenie w klauzuli WHERE ma wartość inną niż zero, całkowitą wartość inną niż zero, wyrażenie ma wartość PRAWDA. (Uważam, że wartości dziesiętne i zmiennoprzecinkowe są „zaokrąglane” do liczb całkowitych, np.WHERE 1/3
Ocenia naWHERE 0
. Otrzymujemy ten sam wynik zWHERE 'foo'
, ponieważ łańcuch'foo'
równieżTo eleganckie rozwiązanie, które doceniam, ponieważ wykorzystuje zero bajtów danych:
Aby ustawić wartość true, ustaw
some_flag = ''
i ustaw wartość false, ustawsome_flag = NULL
.Następnie, aby sprawdzić, czy jest prawda, sprawdź, czy jakaś_flaga
IS NOT NULL
, i aby sprawdzić, czy jest jakaś_faga, sprawdź, czy jakaś_flagaIS NULL
.(Ta metoda została opisana w „High Performance MySQL: Optymalizacja, kopie zapasowe, replikacja i więcej” Jon Warren Lentz, Baron Schwartz i Arjen Lentz.)
źródło
COMMENT
definicji w kolumnie, któraNULL
wskazuje na fałsz i''
wskazuje na prawdę, może pójść w bardzo niewielkim stopniu w kierunku ułatwienia przyszłego zrozumienia.Jeśli używasz typu BOOLEAN, jest on aliasowany do TINYINT (1). Jest to najlepsze, jeśli chcesz używać standardowego SQL i nie przejmuj się, że pole może zawierać wartość spoza zakresu (w zasadzie wszystko, co nie jest równe 0, będzie „prawdziwe”).
ENUM („Fałsz”, „Prawda”) pozwoli ci używać ciągów w twoim SQL, a MySQL zapisze pole wewnętrznie jako liczbę całkowitą, gdzie „Fałsz” = 0 i „Prawda” = 1 w oparciu o kolejność określania Enum .
W MySQL 5+ możesz użyć pola BIT (1), aby wskazać 1-bitowy typ liczbowy. Nie sądzę, że faktycznie zajmuje to mniej miejsca w pamięci, ale znowu pozwala ograniczyć możliwe wartości do 1 lub 0.
Wszystkie powyższe zużyją mniej więcej tyle samo miejsca, więc najlepiej wybrać ten, który jest dla Ciebie najłatwiejszy do pracy.
źródło
Odpowiedzi na to pytanie, ale pomyślałem, że wrzucę moje 0,02 $. Często używam
CHAR(0)
, gdzie'' == true and NULL == false
.Z mysql docs :
źródło
''
inull
są wartościami falsy.Używam TINYINT (1) do przechowywania wartości logicznych w Mysql.
Nie wiem, czy jest jakaś korzyść z korzystania z tego ... Ale jeśli się nie mylę, mysql może przechowywać wartości logiczne (BOOL) i przechowuje je jako tinyint (1)
http://dev.mysql.com/doc/refman/5.0/en/other-vendor-data-types.html
źródło
Bit ma przewagę nad różnymi opcjami bajtów (tinyint, enum, char (1)), jeśli masz dużo pól boolowskich. Jedno pole bitowe nadal zajmuje pełny bajt. Dwa pola bitowe pasują do tego samego bajtu. Trzy, cztery, pięć, sześć, siedem, osiem. Następnie zaczynają wypełniać następny bajt. Ostatecznie oszczędności są tak małe, że istnieją tysiące innych optymalizacji, na których powinieneś się skupić. O ile nie masz do czynienia z ogromną ilością danych, te kilka bajtów nie zsumuje się zbyt wiele. Jeśli używasz bitów z PHP, musisz typować rzut wartości wchodzących i wychodzących.
źródło
Dopóki MySQL nie zaimplementuje bitowego typu danych, jeśli twoje przetwarzanie jest naprawdę naciskane na przestrzeń i / lub czas, na przykład przy transakcjach o dużej objętości, utwórz pole TINYINT wywoływane
bit_flags
dla wszystkich zmiennych boolowskich i zamaskuj i przesuwaj bit boolowski, którego potrzebujesz w SQL pytanie.Na przykład, jeśli twój najbardziej lewy bit reprezentuje twoje pole bool, a 7 prawych bitów nic nie reprezentuje, wtedy twoje
bit_flags
pole będzie równe 128 (binarne 10000000). Zamaskuj (ukryj) siedem bitów po prawej stronie (używając operatora bitowego&
) i przesuń 8 bitów siedem spacji w prawo, kończąc na 00000001. Teraz cała liczba (która w tym przypadku wynosi 1) jest twoją wartością.Podczas testowania możesz uruchamiać takie instrukcje
itp.
Ponieważ masz 8 bitów, potencjalnie masz 8 zmiennych boolowskich z jednego bajtu. Pewien przyszły programista niezmiennie używa następnych siedmiu bitów, więc musisz maskować. Nie zmieniaj się, bo w przyszłości stworzysz piekło dla siebie i innych. Upewnij się, że MySQL wykonuje maskowanie i przesuwanie - będzie to znacznie szybsze niż w przypadku języka skryptowego (PHP, ASP itp.). Upewnij się także, że umieścisz komentarz w polu komentarza MySQL dla swojego
bit_flags
pola.Te witryny będą przydatne podczas wdrażania tej metody:
źródło
VARCHAR
i wykonaj procedurę demaskowania w kodzie (nie musisz również ograniczać go do 8 pól) ...BIT
typ istnieje. Zobacz dev.mysql.com/doc/refman/8.0/en/bit-type.htmlMam dość próbowania zer, NULLS i „” dokładnego okrążenia pętli wartości PHP, MySql i POST, więc używam po prostu „Tak” i „Nie”.
Działa to bezbłędnie i nie wymaga specjalnego traktowania, które nie jest oczywiste i łatwe do zrobienia.
źródło
Nawiązując do tego linku typu danych logicznych w Mysql , zgodnie z zastosowaniem aplikacji, jeśli chce się przechowywać tylko 0 lub 1, bit (1) jest lepszym wyborem.
źródło
BIT(1)
zezwoli tylko na przechowywanie wartościb'0'
lubb'1'
. Największym problemem związanym zBIT
typem danych jest to, że różne biblioteki klienckie mają różne nieporęczne operacje na typie danych. Sprawdź zachowanie w różnych narzędziach SQL (SQLyog, TOAD for MySQL, SQL Developer), narzędziach do „odwrotnej inżynierii” modeli baz danych i różnych klientach, takich jak JDBC, PHP, Perl DBI, a dla pewności przetestuj kilka struktur ORM ( Hibernacja, Mybatis, JPA). Pod względem łatwości użytkowaniaTINYINT(1)
wyraźnym zwycięzcą jest kompatybilność narzędzia / frameworka / natywne wsparcie .BIT
iTINYINT
. Odwołaj się do klasy JdbcType MyBatis, mybatis.org/mybatis-3/apidocs/reference/org/apache/ibatis/type/…Ponieważ zarówno MySQL (8.0.16), jak i MariaDB (10.2.1) zaimplementowały ograniczenie CHECK, użyłbym teraz
Będzie można tylko do sklepu
0
,1
lubNULL
, jak również wartości, które mogą być przekształcone0
lub1
bez błędów, takich jak'1'
,0x00
,b'1'
lubTRUE
/FALSE
.Jeśli nie chcesz zezwalać na wartości NULL, dodaj
NOT NULL
opcjęZauważ, że nie ma praktycznie żadnej różnicy, jeśli używasz
TINYINT
,TINYINT(1)
lubTINYINT(123)
.Jeśli chcesz, aby Twój schemat był kompatybilny w górę, możesz także użyć
BOOL
lubBOOLEAN
db <> demo skrzypiec
źródło
ENUM
(musi byćenum('0', '1')
- uwaga: to są łańcuchy) nie jest dobrym pomysłem. Istnieje zbyt wiele problemów ze względu na to, jak jest przechowywany wewnętrznie i jak traktowane są wartości nie łańcuchowe. Na przykład.0
iFALSE
nie mogą być przechowywane.1
iTRUE
stać się'0'
. I2
staje się'1'
.Po przeczytaniu tutaj odpowiedzi postanowiłem użyć
bit(1)
i tak, jest to jakoś lepsze w czasoprzestrzeni, ALE po pewnym czasie zmieniłem zdanie i nigdy więcej go nie użyję. To bardzo skomplikowało mój rozwój, kiedy korzystałem z przygotowanych instrukcji, bibliotek itp. (Php).Od tego czasu zawsze używam
tinyint(1)
, wydaje się wystarczająco dobry.źródło
Możesz użyć typu danych BOOL, BOOLEAN do przechowywania wartości logicznych.
Jednak typ danych BIT (1) ma sens przechowywania wartości logicznej (prawda [1] lub fałsz [0]), ale łatwiej jest pracować z TINYINT (1), gdy wysyłasz dane, zapytania i tak dalej w celu osiągnięcia interoperacyjności między MySQL i innymi bazami danych. Możesz także sprawdzić tę odpowiedź lub wątek .
Ponadto przeczytaj dokumentację
źródło