Jarod
29.04.2005, 20:27:48
Mam w tabeli wartość pesel. Pesel zawsze składa się z 11 cyfer. Miałem ustawiony typ bigint, ale nie wiem czy nie będzie lepiej jak wybiorę varchar(11). Słyszałem, że typy mają wpływ na wydajność. Który typ doradzacie (bigint czy varchar)?
SongoQ
30.04.2005, 00:02:07
To zalezy do czego bedziesz konkretnie wykorzystywal: trzymanie danych przeszukiwanie itd.
Polecam uzyc varcha(11)
dr_bonzo
30.04.2005, 00:53:27
No ale pesel to same cyfry, a operacje na liczbach sa szybsze niz na stringach -- odpowiedz nasuwa sie sama *INT.
sobstel
30.04.2005, 07:22:00
poza tym BIGINT zajmie ci w pamieci 8 bajtow, a VARCHAR(11) 11 bajtow. polecam zdeklarowanie tego pola jako BIGINT(11) UNSIGNED
SongoQ
30.04.2005, 10:29:49
Widze ze sa rozne rozbierznosci tego. Tak jak pisalem to zalezy do czego bedziesz wykorzystywal, jesli bedziesz robil "operacje" na tym polu to typ bigint a jesli tylko ma byc skladowanie danych to jest to zupelnie obojetne i wtedy varchara mozesz uzyc.
Jarod
30.04.2005, 10:34:11
Pozwoliłem sobie zacytować odpowiedź jednego usera - nie z tego form
Cytat
TO zależy jakie inne typy masz też w tabeli.
Najlepiej będzie jeśli określisz jako char(11).
Dlatego że char zawsze zachowuje stałą długość
przechowywanych ciągów (a varchar nie).
Char zawsze zapełnia ciąg spacjami
na końcu do osiągnięcia łącznej długości 255 znaków
(bo takie jest maximum dla char). Dzięki temu
tabela nie ulega fragmentacji ("rozstrzeleniu" na dysku),
a co za tym nie wymaga wykonywania OPTIMIZE
po operacjach typu UPDATE itp.
Jednak jeśli w tabeli są też zdefiniowane typy
o zmiennej długości zachowawczej (np. blob, text, itp.)
to mysql i tak zmieni typy char (stałe długościowo) na
varchar (niestałe długościowo)...
Ponadto, typ danych musisz uwzględniać przy projektowaniu
bazy:
PESEL - same cyfry, OK, ale przecież nie będziesz
na tych liczbach wykonywał operacji arytmetycznych,
dlatego nie ma sensu dla tego pola dawać typu liczbowego.
Wygodniej dać typ ciągowy, czyli char. Wpłynie to znacznie
na wydajność, nie obciąży niepotrzebnie np. pamięci serwera itp.
Zachowa (większą) spójność bloków danych bazy na dysku itd.
No i już zgłupiałem. Jedni tak drudzy tak.. Nie będę wykonywał żadnych operacji na zmiennej PESEL. ALe nie wiem jak to będzie w przyszłości. Podobny problem mam ze zmienną NIP i REGON. Ale narazie dałem VARCHAR odpowiednio 11,9,10
sobstel
30.04.2005, 10:45:17
w MySQL jesli masz jakiekolwiek inne pola typu VARCHAR czy tez BLOB itp. to CHARy i tak sa automatycznie zmieniane na VARCHAR.
ja sie dlaej bede trzymal BIGINT(11) UNSIGNED, bowiem nawet jak nie dokonujesz bezposrednio zadnych opercacji na kolumnie z PESELEM to i tak nie jest to samo, bowiem jak napisalem wyzej BIGINT potrzebuje mniej miejsca niz VARCHAR(11)

!
nie mowiac juz o tym ze typ danych powinien jak najbardziej obrazowac rzeczywitsoc, a nie da sie ukryc ze PESEL jest typu numerycznego.
SongoQ
30.04.2005, 11:01:04
Bardzo pouczajacy post.
W pojektcie nad ktorym procowalem uzylismy typu varchar do NIPu, PESELU, REGONu. Dziala juz ponad pol roku, dzialaja na tym 2 firmy ktore maja spora liczbe klientow i jakos jeszcze nikt nie narzekal na wydajnosc bazy. Moze to dlatego ze to Postgres.
sobstel
30.04.2005, 11:52:03
@SongoQ, co nie znaczy ze nie da sie zrobic wydajniej. daj mi prosze argument na to ze zastosowanie VARCHAR(11) byloby w tym przypadku lepsze niz BIGINT(11) UNSIGNED. osobiscie nie widze, ale oczywiscie nikt nie jest wszystkowiedzacy.
SongoQ
30.04.2005, 12:08:18
@sopel Zawsze da sie zrobic wydajniej, kwestia tego jak podchodzisz do danego problemu i czy jest Ci to potrzebne.
Cytat
daj mi prosze argument na to ze zastosowanie VARCHAR(11) byloby w tym przypadku lepsze niz BIGINT(11) UNSIGNED. osobiscie nie widze, ale oczywiscie nikt nie jest wszystkowiedzacy.
Niestety nie mam

Mysle ze sie dowiemy jak to naprawde jest jesli sie wdrozymy w zagadnienia teoretyczne budowy tabel, trzymania danych w tabelach i optymalizatora. Jak juz napisales nikt nie jest wszystkowiedzacy.
Jarod
30.04.2005, 12:20:16
Sam typ INT ma zakres od -2 147 483 648 do + 2 147 483 647. Gdybym zapisał INT UNSIGNED to zares będzie od 0 do 4294967295. Podobno jest to liczna 4-bajtowa. Ale składa się z 10 cyfer. Nie powinno być 1--bajtowa?
Skoro typ BIGINT składa się z 18 cyfer to nie powinien być 18-bajtowy?
Pozdrawiam
matid
30.04.2005, 12:39:09
Moje badania.
Tablica z polem varchar(11), jeden wpis, 1000 zapytań na skrypt, średnia z 10 wykonań:
0.307938457s
Tablica z polem bigint(11) unsigned, jeden wpis, 1000 zapytań na skrypt, średnia z 10 wykonań:
0.261060739s
Z tego wynika, że operacje na bigint wydają się szybsze.
Jarod
30.04.2005, 12:43:54
Cytat(matid @ 2005-04-30 11:39:09)
Tablica z polem bigint(11) unsigned, jeden wpis, 1000 zapytań na skrypt,
Dlaczeo piszesz bigint(11) a nie bigint?
Co miałeś na myśli pisząc "1000 zapytań na skrypt"??
SongoQ
30.04.2005, 13:23:29
@J4r0d
Cytat
Podobno jest to liczna 4-bajtowa. Ale składa się z 10 cyfer. Nie powinno być 1--bajtowa? Skoro typ BIGINT składa się z 18 cyfer to nie powinien być 18-bajtowy?
Wyjasnienie:
Typ int jest 4 bajtowy. Ma zakres np od -2 147 483 648 do + 2 147 483 647 lu od 0 do 4294967295.
Dlaczego 4 bajty?
4294967295 po zamianie na system binarny daje: 11111111 11111111 11111111 11111111, kazde 8 cyfr(bitów) to 1 bajt.
Z bigint jest tak samo, tylko ze ma 8 bajtw => 64 bitów czyli 64 jedynki.
@matid W tabeli bylo tylko pojedyncze pole z peselem? czy robiles rozne kombinacje? Az dla pewnosci sobie sam przetestuje.
matid
30.04.2005, 13:37:34
Cytat(J4r0d @ 2005-04-30 13:43:54)
Co miałeś na myśli pisząc "1000 zapytań na skrypt"??

1000 zapytań w pętli.
Test robiłem takim kodem:
<?php
function microtime_float()
{
list
($usec, $sec) = explode(\" \", microtime()); return ((float)$usec + (float)$sec);
}
$iStart = microtime_float();
for( $i = 0; $i < 1000; $i++ )
{
$rResult = mysql_query( 'SELECT * FROM pesel' . $_GET['pesel'] . ' LIMIT 1' ); echo $rRow->pesel . '<br />'; }
$iDuration = microtime_float() - $iStart;
?>
@SongoQ: Testowałem tylko na takich dwóch tabelach:
CREATE TABLE `pesel1` (
`pesel` varchar(11) NOT NULL DEFAULT ''
) TYPE=MyISAM;
oraz
CREATE TABLE `pesel2` (
`pesel` bigint(11) UNSIGNED NOT NULL DEFAULT '0'
) TYPE=MyISAM;
Jarod
30.04.2005, 21:17:20
@matid: Ok ale dlaczego piszesz BIGINT(11) a nie BIGINT. Co to 11 oznacza?
Pozdrawiam
asbator
5.02.2016, 09:35:35
Ponieważ często wyszukuje się osoby wg PESEL wypadało by założyć na to pole indeks (można pokusić się nawet o UNIQUE) i tu bigint zdecydowanie wygrywa.
mmmmmmm
5.02.2016, 21:25:25
Oprócz tego, że zasługujesz na złotą łopatę za wykopanie najstarszego postu, to zasada jest podstawowa:
używasz liczb, gdy potrzebujesz działań na liczbach (np. sumowanie, średnia itp)
Przy BIGINT gubisz zera wiodące i zaczyna ci się problem np. z obliczaniem poprawności. Wiem, że można użyć ZEROFILLa, ale ... tylko na MySQL i nie wiem, czy wtedy nadal MySQL traktuje to jako liczbę...
Pyton_000
5.02.2016, 23:03:23
PESEL? Zerofill? seriously ?

Tak na prawdę to nie ma najmniejszego znaczenia czy użyjesz varchar, bigint, char czy innego...
Co z tego że zajmuje 11 bajtów zamiast 8, aż tak na prawdę interesuje Cię wielkość BD?
OK jeśli baza będzie miała >10mln rekordów to tak, wtedy będzie różnica.
Nie ma co się czasami rozwodzić w takich przypadkach.
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.