Autor Zpráva
Ugo
Profil
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
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
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
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
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
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
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
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);
}

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0