4000 reči i 20 ručno crtanih ilustracija — uz praktični projekat Jishupai potpuno savladaj MySQL tipove podataka
U prethodnom poglavlju naučili smo o osnovnim operacijama nad MySQL tabelama i saznali da se tabela sastoji od kolona različitih tipova podataka, u koje se zatim red po red upisuju podaci.
Kada kreiramo tabelu, na osnovu poslovnih potreba biramo odgovarajuće tipove podataka. Na primer, u praktičnom projektu Jishupai, tabela članaka definisana je sledećim poljima različitih tipova podataka.

Trenutno se koriste tipovi podataka poput bigint, tinyint, varchar, int, timestamp itd. Kako odabrati pravi tip? Prethodno moramo dobro razumeti koje tipove podataka MySQL uopšte podržava i kakve su osobine svakog od njih.
Celobrojni tipovi
bigint, tinyint i int pomenuti iznad svi su celobrojni tipovi. MySQL podržava sledeće celobrojne tipove:
| Ime tipa | Prostor za skladištenje | Opseg |
|---|---|---|
| tinyint | 1 bajt | -128 do 127 ili 0 do 255 |
| smallint | 2 bajtova | -32768 do 32767 ili 0 do 65535 |
| mediuint | 3 bajta | -8388608 do 8388607 ili 0 do 16777215 |
| int | 4 bajta | -2147483648 do 2147483647 ili 0 do 4294967295 |
| bigint | 8 bajtova | -9223372036854775808 do 9223372036854775807 ili 0 do 18446744073709551615 |
smallint i mediuint se retko koriste; najčešće koristimo tinyint, int i bigint.
Na primer, u projektu Jishupai polje article_type (tip članka) u tabeli article definisano je kao tinyint, jer tip članka ima samo dve vrednosti — 1 (blog post) i 2 (pitanje i odgovor) — pa je tinyint sasvim dovoljan.
Isto važi za polje status, takođe definisano kao tinyint, jer status ima samo dve vrednosti — 0 (neobjavljeno) i 1 (objavljeno).
I polje deleted je definisano kao tinyint, jer status brisanja obično ima samo dve vrednosti — 0 (nije obrisano) i 1 (obrisano).
Tip int se obično koristi za korisničke godine, količinu na zalihama, broj komentara, broj lajkova i sl.
U projektu Jishupai, polja offical_stat (zvanično preporučeno), topping_stat (zalepljeno na vrh) i cream_stat (isticano) u tabeli article koriste tip int, što zapravo nije sasvim razumno — tinyint bi bio sasvim dovoljan. Za sada to nisam menjao.
bigint koristimo za primarni ključ tabele, što je prilično uobičajena praksa, naročito kada se očekuje da količina premaši maksimalnu vrednost tipa int (2,1 milijarde). Međutim, s obzirom na trenutnu količinu podataka u projektu Jishupai, int je sasvim dovoljan.
Ranije, radeći narudžbine za trgovinu terminskim ugovorima robe, ispočetka sam koristio int, ali je vrednost zaista premašila opseg int-a, pa sam prešao na bigint.
Maksimalna vrednost bigint-a je 9223372036854775807, odnosno oko 922 triliona. Broj je izuzetno velik; pri tom obimu obično se već prelazi na particionisanje baze i tabela (sharding).
Inače, izbor tipa podataka za primarni ključ zavisi od poslovnog scenarija. Ako je potrebno garantovati jedinstvenost kroz više baza ili sistema, prikladniji će biti UUID ili ID generisan Snowflake algoritmom.
UUID se ne oslanja na automatsko uvećanje baze, što ga čini pogodnim za distribuirane sisteme, ali zauzima više prostora za skladištenje (CHAR(36) ili VARCHAR(36)) i nije rastući, što dovodi do pada performansi indeksa.
Označeni i neoznačeni (signed/unsigned)
Celobrojni tipovi mogu biti označeni (signed) i neoznačeni (unsigned). Označeni mogu da skladište i pozitivne i negativne brojeve, dok neoznačeni skladište samo pozitivne. Podrazumevano je označeno, tj. ne mora se izričito navoditi.
Na primer, za tip int: ako je označen, opseg je od -2147483648 do 2147483647; ako je neoznačen, opseg je od 0 do 4294967295.

U neoznačenom slučaju, posebno obratite pažnju na mapiranje na Java tipove podataka.
Znamo da je opseg int-a u Javi od -2147483648 do 2147483647. Ako MySQL int bude neoznačen, njegov opseg prelazi opseg Java tipa int.
Da bismo izbegli nekompatibilnost, u Javi treba izabrati tip long. Naravno, u entitetu baze (POJO) koristi se omotački tip Long.

Auto-inkrementalni ID je sigurno neoznačen, pa ga pri definisanju označavamo sa unsigned, kao u tabeli article u projektu Jishupai.

int(10) i int
Obratite pažnju: na gornjoj slici, prilikom definisanja id, postavljeni tip podataka je int(10). Koja je razlika u odnosu na int?
Ovo je zapravo dobro pitanje za intervju — na primer, intervjuer vas može pitati koja je razlika između int(10) i int(11).
Ako ranije o tome niste razmišljali, možete se naći u nedoumici. Zapravo, ovo nema veze sa prostorom za skladištenje, već samo određuje širinu prikaza.
Hajde da kreiramo takvu test tabelu sa četiri polja: primarni ključ ID, int(10), int(11) i običan int.
CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`int10` int(10) NOT NULL,
`int11` int(11) NOT NULL,
`int` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;Ovde se znak „backtick" ` koristi da bi se izbegao sukob sa ključnim rečima.

Zatim ubacimo jedan red podataka i pogledajmo rezultat.
INSERT INTO `test` (`int10`, `int11`, `int`) VALUES (1234567890, 1234567890, 1234567890);Upitimo — izgleda da nema razlike.

Pogledajmo zvanično MySQL objašnjenje za int(M).
M indicates the maximum display width for integer types.
.....
