Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno Databaze - mysql - zkusenosti s primarnim klicem

Zdravim, predem se omlouvam ze pisi bez diakritiky, nemam ceskou klavesnici.

Nema prosim vas nekdo zkusenosti s UUID v mysql databazi? Kdyz jsem prochazel ruzne stranky na internetu tak jsem nachazel ze pouziti auto_increment je rychlejsi. Ale taky jsem nasel nekolik clanku kde pisi ze UUID je v datovem typu binary(16) stejne rychle, neli rychlejsi. Konkretne treba zde.

Uvazuji ze udelam vlastni test. Dekuji predem za odpovedi.

iops.io

Předmět Autor Datum
Heled, nesetkal jsem se s nicim jinym nez u auto_increment. Osobne bych to na nem delal dal. Samo kd…
tomas.kulhanek 28.04.2014 13:11
tomas.kulhanek
Jeste jsem uvazoval nad PostgreSQL ale o tom jsem cetl taky tunu clanku s porovnanim na MySQL, ze js…
David963 28.04.2014 13:42
David963
Ktoré lepšie riešenie máš na mysli? SEQUENCE, IDENTITY alebo SERIAL? :-)
los 28.04.2014 13:58
los
Ak potrebuješ mať ako primárny kľúč UUID, tak jednoznačne použi dátový typ BINARY(16). Pre konverziu…
los 28.04.2014 13:56
los
Tak v tom odkaze co jsem psal vyse se UUID pouziva jako primarni klic. A bylo toho vic. Ale spis me…
David963 28.04.2014 14:13
David963
V tom odkaze bol len benchmark rôznych spôsobov ukladania UUID do databázy. Prvý spôsob ako CHAR(36)…
los 28.04.2014 14:42
los
Moje chyba, tady auto_increment neni. Ale bud jsem to videl v jinem clanku nebo jeste autor tohoto o…
David963 28.04.2014 14:56
David963
CREATE TABLE ai( ID INT UNSIGNED NOT NULL AUTO_INCREMENT, NAME VARCHAR(16), PRIMARY KEY(ID) ) ENGINE…
David963 28.04.2014 15:01
David963
Rozdiely sú zanedbateľné, takže predpokladám, že si použil veľmi malú vzorku testovacích dát. Ak to…
los 28.04.2014 15:17
los
Az budu mit vice casu to otestovat tak to vyzkousim s mnohem vetsim poctem dat a pridam tam i indexy…
David963 28.04.2014 15:32
David963
INT má tiež pevnú dĺžku, takže v tomto rozdiel nebude. V prípade číselného identifikátora (AUTO_INC… poslední
los 28.04.2014 15:51
los

Jeste jsem uvazoval nad PostgreSQL ale o tom jsem cetl taky tunu clanku s porovnanim na MySQL, ze jsou si dost podobne. Popripade na caste data cassandru a v relacni db uz bych se spokojil s auto_increment. Kazdopadne UUID bych rad pouzival uz jen k tomu ze ho muzu vygenerovat a neptat se mysql na last insert id.

Ak potrebuješ mať ako primárny kľúč UUID, tak jednoznačne použi dátový typ BINARY(16). Pre konverziu z reťazca do binárneho tvaru môžeš použiť funkciu UNHEX (opačne potom HEX) na strane MySQL. Vyhneš sa tak problémom, na ktoré by si mohol naraziť pri konverzii na strane PHP, kde niektoré funkcie vrátia rôzne hodnoty pre 32-bit/64-bit verziu.

Druhá vec je, že použiť UUID ako primárny kľúč je dosť neštandardné. Takže pokiaľ k tomu nemáš pádny dôvod, tak pre umelý kľúč použi obyčajné číslo.

V tom odkaze bol len benchmark rôznych spôsobov ukladania UUID do databázy. Prvý spôsob ako CHAR(36), druhý ako 6x INT a tretí ako BINARY(16). Akože chápem, že niektorí ľudia nemajú čo robiť, ale stačí trochu porozmýšľať a rýchlo prídeš na to, že robiť takýto benchmark nemá zmysel.

Ukladať UUID ako 6x INT je úplný nezmysel. Nerieši to ani jednoduchosť čítania/zápisu a používať takéto zverstvo ako cudzí kľúč neprichádza do úvahy. Takže na výber máš medzi CHAR(36) a BINARY(16). Už len rozdiel vo veľkosti napovie, ktoré z nich sa lepšie indexuje.

Samotný benchmark o ničom nevypovedá (chýba aj základná informácia o tom, aký bol použitý HW). Na rýchlosť vkladania riadkov majú podstatnejší vplyv iné faktory než to, či je identifikátor UUID alebo INT. Neviem, kde tam vidíš, že čítanie a zápis sú pre UUID rýchlejšie ako AUTO_INCREMENT - očakával by som presne opačný výsledok.

Moje chyba, tady auto_increment neni. Ale bud jsem to videl v jinem clanku nebo jeste autor tohoto otestoval i pro AI. Kazdopadne jsem to ted testoval ja. Zkousel jsem 1000 insertu a selectu jak pro INT (auto_increment) tak pro UUID (binary(16)) a dostal jsem tyto casy.

1000x
insert/auto_increment - done in 49889 ms
insert/uuid - done in 48831 ms

select/auto_increment - done in 140 ms
select/uuid - done in 137 ms

Zkousel jsem to nekolikrat. A vzdy na tom UUID vychazelo lepe. Select se provadel s nahodnym id/uuid v jave. Stroj na kterem to testuji sice neni server ale pro oba zpusobu jsou stejne podminky. Nebo ne? Zkouset to davat do separatnich INTu nebo CHAR(36) me nenapadlo, neboj. :)

CREATE TABLE ai(
	ID 				INT UNSIGNED NOT NULL AUTO_INCREMENT,
	NAME			VARCHAR(16),
		PRIMARY KEY(ID)
) ENGINE = InnoDB;

DROP TABLE IF EXISTS uid;

CREATE TABLE uid(
	UID 			BINARY(16),
	NAME			VARCHAR(16),
		PRIMARY KEY(UID)
) ENGINE = InnoDB;

DELIMITER //
CREATE TRIGGER UUID_TEST BEFORE INSERT ON uid FOR EACH ROW
BEGIN
  	SET NEW.UID = UNHEX(REPLACE(UUID(), "-", ""));
END//
DELIMITER ;

Kdyztak dokladam i tabulky.

Rozdiely sú zanedbateľné, takže predpokladám, že si použil veľmi malú vzorku testovacích dát. Ak to myslíš s benchmarkovaním vážne, tak tá Java by tam nemala čo robiť.

V reálnom prostredí (viac dát) by som pri vkladaní riadkov očakával najvyšší rozdiel v réžii na úpravu indexu, čo je pri AUTO_INCREMENT jednoduchšie ako pri náhodnom UUID. Ďalšia vec je, že v praxi sa nestretneš s tabuľkou, do ktorej by si tak často vkladal riadky cez obyčajný INSERT.

Pri čítaní tam teraz nemáš prakticky žiaden rozdiel. Opäť, pri väčšom počte riadkov by som očakával, že sa prejaví rozdiel v indexovaní 16-bajtového poľa oproti 4-bajtovému (prípadne 8-bajtovému).

Hlavný dôvod, prečo nepoužiť UUID, je to, že je to veľmi nepraktické.

Az budu mit vice casu to otestovat tak to vyzkousim s mnohem vetsim poctem dat a pridam tam i indexy popripade nejake relace. Ale nekde jsem cetl, myslim na stackoverflow ze pevna delka tedy se indexuje daleko lepe nez promena delka. Ale verim ze auto_increment ma neco dosebe vzhledem k popularite.

A muzu se jen zeptat co nepraktickeho?

INT má tiež pevnú dĺžku, takže v tomto rozdiel nebude.

V prípade číselného identifikátora (AUTO_INCREMENT) vieš hneď povedať, v akom poradí jednotlivé riadky vznikli. Máš lepšiu predstavu o tom, koľko dát máš v tabuľke a s ako starým záznamom pracuješ. Číselný identifikátor môžeš použiť ako pole, pomocou ktorého konzistentne usporiadaš riadky. V malých tabuľkách máš také čísla, ktoré si schopný si aj zapamätať. Jednoduchšie označíš číslo, keď ho potrebuješ skopírovať (dvojitý klik, Ctrl+Shift+šípka). Odpadávajú problémy s generovaním UUID.

Zpět do poradny Odpovědět na původní otázku Nahoru