---
# System prepended metadata

title: Datovy typ primarniho klice -- popis a porovnani typu

---


# Datovy typ primarniho klice -- popis a porovnani typu

## Popisy jednotlivych skumanych typov 

### UUID (+GUID) 

Universally Unique IDentifier je znacka pouzivana na jednozcnacnu identifikaciu lubovolnych veci v pocitacovych systemoch. Sklada sa z 128 bitov a bol definovany v RFC 4122. Hodnoty tohto identifikatoru nie su garantovane unikatne, ale pravdepodobnost kolizie je statisticky zanedbatelna. Pouzivaju sa napriklad v suborovych systemoch, ale jednym z vyuziti je ako unikatny kluc v databazovych tabulkach. V nami skumanom databazovom systeme PostgreSQL specialny datovy typ pre UUID a tiez od verzie 13 priama podpora pre generovanie UUID. Vyhodou pouzitia UUID oproti sekvencne generovanym klucom je ich globalna unikatnost. Casto ich preto najdeme napriklad v distribuovanych systemoch, kde nam nestaci unikatnost v ramci jednej tabulky. GUID je implementacia UUID v mnohych systemoch od Microsoftu, preto sa s nim stretneme vo vela produktoch od tejto firmy, napriklad v operacnom systeme Windows. V PostrgreSQL nie su podporovane a preto sa nimi zaoberat nebudeme. 

  

#### Pouzitie v PostgreSQL a verzie 

  

- datovy typ `uuid` ulozeny ako binarne 128 bitove cislo, nie ako string 

- priklad v standardnej forme: `a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11` 

- rozne verzie UUID su podporovane ako third-party modul `uuid-ossp`, ktory poskytuje funkcie `uuid_generate_vX` 

- format je vo verziach vzdy rovnaky, rozny je algoritmus a data pouzite na generaciu 

- napriklad verzia 1 pouziva kombinaciu aktualnej MAC adresy, casovej znamky a nahodnej hodnoty 

- v sucasnosti najviac pouzivana verzia 4 je tvorena cisto na zaklade nahodnych cisel 

- priklad DDL s uuid typom: 

```sql 

CREATE TABLE contacts ( 

    contact_id uuid DEFAULT uuid_generate_v4 (), 

    first_name VARCHAR NOT NULL, 

    last_name VARCHAR NOT NULL, 

    email VARCHAR NOT NULL, 

    phone VARCHAR, 

    PRIMARY KEY (contact_id) 

); 

``` 

- v PostgreSQL verzie 13+ pomocou funckie `gen_random_uuid()`, tvori UUIDv4 a nie je treba ziadne externe moduly 


### Network address

- Jedna z moznosti je pouzit textove typy a do nich ulozit textovu reprezentaciu adresy
- PostgreSQL dokumentacia odporuca pouzivat specialne typy **inet**, **cidr** a **macaddr** na pracu s adresami kvoli dodatocnym input error checkom a specializovanym funkciam a operatorom (toto moze mat performance overhead)
- Mohlo by byt zaujimave porovnat rychlost stringu a inet pre vkladanie a search
- Dalej sa da sledovat velkost, aku jednotlive typy zaberaju na disku

#### inet and cidr

- 7 alebo 19 bajtov
- inet drzi adresu, pripadne jej podsiet
- cidr drzi adresu siete
- definicia:

```c=
typedef struct
{
 unsigned char family;       /* PGSQL_AF_INET or PGSQL_AF_INET6 */
 unsigned char bits;         /* number of bits in netmask */
 unsigned char ipaddr[16];   /* up to 128 bits of address */
} inet_struct;

typedef struct
{
 char        vl_len_[4];     /* Do not touch this field directly! */
 inet_struct inet_data;
} inet;
```

#### macaddr

- Uklada MAC adresy zname napr. z hardwerovych adres eternetovych kart
- Standardne formaty zapisu:

```
'08:00:2b:01:02:03'
'08-00-2b-01-02-03'
```

- Alternativa by opat mohol byt varchar

### Geometricke typy

- zakladny geometricky typ **point** je bod v dvojrozmernom priestore
- uklada sa ako dvojica (x, y) kde x a y su typu float a dokopy zaberaju 16 bajtov
- tento typ ako primarny kluc by default pouzit nejde lebo postgres ho nevie indexovat bez pouzitia custom operator class (co je task na ktori sa bezni uzivatelia postgres neodhodlaju)
- geometrickym bodom sa teda z hladiska vykonnosti dalej zaoberat nebudeme

### Cela cisla (int, bigint)

#### Int a Bigint

Datovy typ celych cisel. Rozidl mezi bigint a int je v poctu bajtu pouzitych pro ulozeni hodnoty. Integer pouziva 4 bajty a bigint pouziva 8 bajtu. Tedy integer ma rozsah od -2 147 483 648 do +2 147 483 647 a bigint ma rozsah od -9 223 372 036 854 775 808 to +9 223 372 036 854 775 807. Pri preteceni vyhodi postgreSQL error.

Cela cisla jsou dobre vybalancovane v ramci vyhledavani v rozmezi, velikosti a rychlosti. 

#### Serial a bigserial

Jedna se o odnoze celych cisel s rozsahem od 1 do 2 147 483 647 pro serial a od 1 do 9 223 372 036 854 775 807 pro bigserial. Da se rict, ze se jedna o celocisleny typ, ktery je navic zabaleny spolecne s `AUTO_INCREMENT` funkci. Chovaji se tedy stejne jako cela cisla.

#### Pripady uziti celych cisel jako primarni klic

- Telefonni cisla -- vhodna pro ulozeni dat o cisle u operatoru
- Rodne cislo -- pro ulozeni zamestnance 

#### Priklad pouziti integer jako primarniho klice

```sql=
CREATE TABLE meal (
	meal_id SERIAL PRIMARY KEY, -- integer with autoincrement
	cook_name VARCHAR(20),
	description TEXT
);
```

#### Vyhody a nevyhody pouziti celych cisel jako primarni klic

| vyhody               | nevyhody |
| -------------------- | -------- |
| Jednoduche         | V url adresach je velmi jednoduche id rozpoznat. Pokud nema web dobre osetrene prava, muze se uzivel dostat tam, kam by nemel. |
| Zabiraji malo pameti | Casto bez pridane informace (arbitralni cislo) |
| Jednoducha citelnost |          |
| Rychle |          |

#### Reference

- https://www.postgresql.org/docs/current/datatype-numeric.html
- https://exceptionnotfound.net/integers-vs-guids-the-great-primary-key-debate/
- https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-primary-key/

### Textové typy (char, varchar, text)

#### Char(n), varchar(n)
Char(n) je dátový typ, ktorý ukladá presne n znakov. Pokiaľ je počet znakov menší ako n doplní medzery. Char bez n je rovný Char(1).
Varchar(n) je dátový typ, do ktorého je možné uložiť maximálne n znakov.
V oboch prípadoch pokus o uloženie viac ako n znakov vyústi v chybu.


#### Varchar, text
Varchar bez n ukladá stringy hocijakej veľkosti.
Text ukladá stringy hocijakej veľkosti.

varchar a text by mali mať rovnaký výkon (otestovať v praxi?)

### Veľkosť

Veľkosť záznamu je pre krátke stringy (do 126B) 1B + veľkosť stringu v B. Pre väčšie stringy je 4B + veľkosť stringu. Maximálna veľkosť stringu je 1GB.

#### Tip
There is no performance difference among these three types, apart from increased storage space when using the blank-padded type, and a few extra CPU cycles to check the length when storing into a length-constrained column. While character(n) has performance advantages in some other database systems, there is no such advantage in PostgreSQL; in fact character(n) is usually the slowest of the three because of its additional storage costs. In most situations text or character varying should be used instead.

Generovanie IDs tip:
https://stackoverflow.com/questions/19530736/how-can-i-generate-a-unique-string-per-record-in-a-table-in-postgres

#### References

- https://www.postgresql.org/docs/current/datatype-character.html
- https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-char-varchar-text/

## Vzajemne porovnani

| Cela cisla                                        | Text                                             | UUID (GUID)                                                                                          | inet a cidr                                                   |
| ------------------------------------------------- |:------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| + Jednoduche                                      | + možno vkladať náhodné hodnoty                  | + globalna unikatnost                                                                                | - umoznuje rozne dotazy specificke pre adresy "is in network", nerovnost... |
| + Zabiraji malo pameti                            | + uložená informácia môže mať informačnú hodnotu | - potencialne kolizie (velmi mala sanca)                                                             | - dokazu ulozit konkretnu adresu aj siet                      |
| + Jednoducha citelnost                            | - netrivialné vytváranie kľúča                   | - az 128 bitov                                                                                       |                                                                     |
| + Rychle                                          | - zložité indexovanie                            | + nativna podpora v Postgre                                                                          |                                                                     |
| - Citelne uzivatelem --> mozne bezpecnosti riziko | - zaberá veľa miesta                             | + v novych verziach pouzitie modernych algoritmov na generaciu nahodnych cisiel, rychle a spolahlive |                                                                     |
| - Casto bez pridane informace (arbitralni cislo)  |                                                  |                                                                                                      |                                                                     |




| inet                                | varchar                          |
|-----------------------------------  | -------------------------------- |
| - obsahuje dotazy na rovnost/rozsah | - da sa dotazovat len na rovnost |
| - velkost 19B                       | - velkost = pocet znakov adresy (masky)    |

