sql >> Databáze >  >> RDS >> Mysql

Schéma databáze pro knihy, autory, vydavatele a uživatele s policemi

Mezi books budete potřebovat propojení N:M a authors , protože kniha může mít více autorů a každý autor může napsat více než jednu knihu. V RDBMS to znamená, že budete potřebovat written_by tabulka.

Spojení mezi books a publishers je však jiný. Každá daná kniha může mít pouze jednoho vydavatele (pokud ve vašem systému nejsou různá vydání knihy považována za stejnou knihu). Takže vše, co zde potřebujete, je publisher_id cizí klíč v books

A konečně, a to nejdůležitější, díváte se na čtenáře/uživatele. A jejich vztah ke knihám. Přirozeně jde také o N:M vztah. Pevně ​​doufám, že lidé čtou více než jednu knihu (všichni víme, co se stane, když přečtete jen jednu...) a určitě knihu čte více lidí. To vyžaduje book_users spojovací stůl. Skutečnou otázkou je, jak to navrhnout. Existují tři základní provedení.

  1. Oddělte tabulky podle typu vztahu . (jak nastínil @just_somebody ) Výhody:Máte pouze VLOŽENÍ a VYMAZÁNÍ, nikoli AKTUALIZACE. I když to vypadá úhledně a trochu to pomáhá s optimalizací dotazů, většinou to neslouží žádnému skutečnému účelu kromě předvádění velkého databázového grafu.

  2. Jedna tabulka se status indikátor . (jak nastínil @Hardcoded) Výhody:Máte pouze jeden stůl. Nevýhody:Budete mít INSERTS, UPDATES a DELETE - něco, co RDBMS snadno zvládne, ale co má z různých důvodů své nedostatky (o tom později) Také jeden status pole znamená, že jeden čtenář může mít ke knize vždy pouze jedno připojení, což znamená, že může být pouze v plan_to_read , is_reading nebo has_read stav v libovolném okamžiku a předpokládá objednávku v době, kdy k tomu dojde. Pokud by si to ten člověk někdy plánoval přečíst znovu , nebo pauza, pak znovu číst od začátku atd., taková jednoduchá série stavových indikátorů může snadno selhat, protože najednou ten člověk is_reading nyní, ale také has_read věc. Pro většinu aplikací je to stále rozumný přístup a obvykle existují způsoby, jak navrhnout stavová pole tak, aby se vzájemně vylučovala.

  3. Protokol . Každý stav VLOŽTE jako nový řádek v tabulce – stejná kombinace knihy a čtečky se objeví více než jednou. První řádek VLOŽTE pomocí plan_to_read a časové razítko. Další s is_reading . Pak další s has_read . Výhody:Budete muset vždy pouze VLOŽIT řádky a získáte přehlednou chronologii věcí, které se staly. Nevýhody:Křížová spojení tabulek se nyní musí vypořádat s mnohem více daty (a být složitější) než v jednodušších přístupech výše.

Můžete se ptát sami sebe, proč je v jakém scénáři kladen důraz na to, zda INSERT, UPDATE nebo DELETE? Stručně řečeno, kdykoli spustíte příkaz UPDATE nebo DELETE, je velmi pravděpodobné, že ve skutečnosti ztratíte data. V tu chvíli se musíte zastavit v procesu navrhování a přemýšlet:"Co tady ztrácím?" V tomto případě ztratíte chronologické pořadí událostí. Pokud je to, co uživatelé dělají se svými knihami, středem vaší aplikace, možná budete chtít shromáždit co nejvíce dat. I když na tom právě teď nezáleží, je to typ dat, který vám později umožní „kouzlit“. Mohli byste zjistit, jak rychle někdo čte, kolik pokusů potřebuje k dokončení knihy atd. To vše, aniž byste uživatele žádali o jakýkoli další vstup.

Takže moje poslední odpověď je vlastně otázka:

Upravit

Protože nemusí být jasné, jak by protokol vypadal a jak by fungoval, zde je příklad takové tabulky:

CREATE TABLE users_reading_log (
  user_id INT,
  book_id INT,
  status ENUM('plans_to_read', 'is_reading', 'has_read'),
  ts TIMESTAMP DEFAULT NOW()
)

Nyní namísto aktualizace tabulky „user_read“ ve vámi navrženém schématu, kdykoli se stav knihy změní, nyní VLOŽTE stejná data do protokolu, který se nyní plní chronologií informací:

INSERT INTO users_reading_log SET 
  user_id=1,
  book_id=1,
  status='plans_to_read';

Když tato osoba skutečně začne číst, provedete další vložení:

INSERT INTO users_reading_log SET 
  user_id=1,
  book_id=1,
  status='is_reading';

a tak dále. Nyní máte databázi „událostí“ a protože se sloupec časového razítka automaticky plní, můžete nyní říci, co se kdy stalo. Upozorňujeme, že tento systém nezaručuje, že pro konkrétní pár uživatel-kniha existuje pouze jeden „is_reading“. Někdo může přestat číst a později pokračovat. Vaše spojení s tím budou muset počítat.



  1. Vlastník databáze postgresql nemá přístup k databázi - Nebyly nalezeny žádné vztahy.

  2. Oracle jako řešení mutujících tabulek

  3. Jak vytvořit dotaz bez ohledu na velikost písmen v Postgresql?

  4. podmíněné jedinečné omezení