Autor | Zpráva | ||
---|---|---|---|
Ugo Profil |
#1 · Zasláno: 3. 1. 2012, 08:37:55
Zdravím, není nějak pěkně možné udělat unikátní ID skrze všechny tabulky (jak má třeba FB)? Zkoušel sem jestli by náhodou nemoh něco udělat cizí klíč k tabulce id, ale samozřejmě se mu nic dělat nechce :D (a komu jo že)
|
||
Tori Profil |
#2 · Zasláno: 3. 1. 2012, 08:42:59 · Upravil/a: Tori
Ugo:
Přidala bych jednu tabulku jako číselník: bude obsahovat jen sloupec ID (int, auto increment). Přidáte do ní řádek, zjistíte last_insert_id a použijete jinde. edit: až teď jsem si všimla, že chcete sqlite - snad to tam jde taky, nemám s ní zkušenosti. ↓ možná umí, moje znalosti jsou omezené. |
||
Ugo Profil |
#3 · Zasláno: 3. 1. 2012, 09:07:19
tabulku mám, jen se mi nelíbí to last_id , škoda že tohle db nějak hezky neumí. Díky za radu
|
||
Joker Profil |
#4 · Zasláno: 3. 1. 2012, 10:14:06
Ugo:
FB má nějaké ID unikátní přes všechny tabulky v DB? Jaké a jak to víte? A k čemu je to dobré? Jinak vytvořit identifikátor unikátní v celé databázi samozřejmě lze: 1. Každá relační databáze to obsahuje už z principu: Kombinace názvu tabulky a hodnoty primárního klíče je unikátní v rámci databáze (vyplývá z 3. Coddova pravidla, pravidla přístupu) 2. GUID |
||
Ugo Profil |
#5 · Zasláno: 3. 1. 2012, 10:41:42 · Upravil/a: Ugo
Joker:
z názvu ano, bohužel číselný už se moc nehodí. U FB má každá položka absolutní unikátní ID, už jsem to viděl u více webů. Výhodou je, že když například máš tabulku která přiřazuje vlastnosti nebo akce, tak nemusíš řešit typ objektu, jen se dotážeš na unikátní ID a tak to lze prostoupit celým systémem. Zatím jsem to tedy veřešil omezením funkčnosti, vzhledem k tomu že to co dělám se stejně nikdy nepoužije tak je to fuk, ale je dobré vědět jaké možnosti jsou. Zatím tedy manuální řešení ID a nebo kombinovaná textová ID (či jakýkoliv jiný unikátní string) |
||
Joker Profil |
#6 · Zasláno: 3. 1. 2012, 11:59:17
Ugo:
Aha, hm. Tady mi přijde, že v drtivé většině případů ty objekty budou nějak podobné, pak stačí je dát do stejné tabulky a je to vyřešené. Ale varianta je přidělovat identifikátory z globální číselné řady. Nejjednodušší implementace je začínat identifikátory v každé tabulce od nějakého čísla (třeba ID je typu UNSIGNED BIGINT, tabulka A začíná od 1, tabulka B od 1 000 000 000 000 001, tabulka C od 2 000 000 000 000 001, atd.) Nevýhoda je asi zřejmá, teoreticky jediná ochrana proti „přetečení“ nějaké tabulky do rozsahu určeného pro následující tabulku je přidělení daleko většího rozsahu IDček, než by měla tabulka potřebovat. To by šlo řešit tak, že ID v tabulce bude normálně 1,2,3,…, tabulka bude mít svůj číselný identifikátor a globální ID se bude vypočítávat (třeba ID tabulky * 1 000 000 000 000 000 + hodnota PK), což ale komplikuje dotazy prohledávající to globální ID. Anebo to co naznačila Tori, mít univerzální tabulku-číselník. Což zase komplikuje přidávání nových záznamů (při přidání nového záznamu musím nejdřív z číselníku získat ID a pak vložit záznam už s vyplněným ID; Přitom získání hodnoty z číselníku musí být atomické, aby nebylo možné se zeptat na ID přesně ve chvíli, kdy číselník už vybral ID jinému záznamu, ale ještě ho nezneplatnil v tabulce). |
||
ninja Profil |
#7 · Zasláno: 3. 1. 2012, 13:39:34
Ugo: Velmi pravděpodobně všechny příspěvky jsou v jedná tabulce. Unikátní vlastnosti jednotlivých typů příspěvků se pak načítájí z jednotlivých připojených tabulek.
|
||
Tori Profil |
#8 · Zasláno: 3. 1. 2012, 21:05:14
Joker:
„Přitom získání hodnoty z číselníku musí být atomické, aby nebylo možné se zeptat na ID přesně ve chvíli, kdy číselník už vybral ID jinému záznamu, ale ještě ho nezneplatnil v tabulce).“ Tohle mě zaujalo. Kdy může nastat taková situace? Předpokládám-li např. (zjednodušeně) takovouhle fci/metodu, může vzniknout problém (když last_insert_id() funguje per connection)? function foo($data) { dibi::query("INSERT INTO `ciselnik` SET `id` = NULL"); $data['id%i'] = dibi::getInsertId(); return dibi::query("INSERT INTO `tabulka`", $data); } |
||
Časová prodleva: 12 let
|
0