2013-02-23 13 views
8

Tak więc mam stworzyć ten schemat schematu + relacje dokładnie w taki sposób, w jaki przedstawia to ERD. Tutaj pokazuję tylko te tabele, które mam problemy z:Tworzenie tabel PostgreSQL + relacje - PROBLEMY z relacjami - JEDEN TO JEDEN

I am supposed to have ONE TO ONE but I get ONE TO MANY

Więc staram się że jest to jeden do jednego, ale z jakiegoś powodu, bez względu na to, co mogę zmienić, mam jeden do wielu na cokolwiek tabela ma klucz obcy.

To jest mój sql dla tych dwóch tabel.

 CREATE TABLE lab4.factory(

      factory_id  INTEGER   UNIQUE, 
      address   VARCHAR(100) NOT NULL, 
      PRIMARY KEY (factory_id) 

     ); 

     CREATE TABLE lab4.employee(

      employee_id  INTEGER   UNIQUE, 
      employee_name VARCHAR(100) NOT NULL, 
      factory_id  INTEGER   REFERENCES  lab4.factory(factory_id), 
      PRIMARY KEY (employee_id) 

     ); 

Tutaj dostaję to samo. Nie dostaję relacji jeden do jednego, ale jednego do wielu. Invoiceline to słaba jednostka.

it needs to be ONE TO ONE

I tu jest mój kodu dla drugiego obrazu.

 CREATE TABLE lab4.product(

      product_id  INTEGER  PRIMARY KEY, 
      product_name INTEGER  NOT NULL 

     ); 


     CREATE TABLE lab4.invoiceLine(

      line_number  INTEGER  NOT NULL, 
      quantity  INTEGER  NOT NULL, 
      curr_price  INTEGER  NOT NULL, 
      inv_no   INTEGER  REFERENCES  invoice, 
      product_id  INTEGER  REFERENCES  lab4.product(product_id), 
      PRIMARY KEY (inv_no, line_number) 

     ); 

Byłbym wdzięczny za każdą pomoc. Dzięki.

+1

Jak można się spodziewać modelowania relacji 1: 1? Z ograniczeniem "UNIQUE" w kolumnie klucza obcego? Z odwrotnym ograniczeniem klucza obcego? –

+0

@CraigRinger, chciałbym mieć bazę wiedzy, aby odpowiedzieć na twoje pytanie, ale jestem po prostu kilkoma wykładami w mojej pierwszej klasie DB. Moje pytania są następujące: Jak utworzyć relację jeden do jednego? Z jakiegoś powodu rozmawialiśmy głównie o wielu do wielu i jednym do wielu –

Odpowiedz

22

Jeden-do-jednego nie jest dobrze reprezentowany jako pierwszorzędny typ relacji w standardowym SQL. Podobnie jak wiele-do-wielu, co osiąga się za pomocą tabeli złącz i dwóch relacji jeden-do-wielu, nie ma prawdziwego "jeden do jednego" w SQL.

Istnieje kilka opcji:

  • Załóż zwyczajne ograniczenie klucza obcego („jeden do wielu” stylu), a następnie dodać UNIQUE presję na krajowy kolumnie FK. Oznacza to, że nie więcej niż jedna z przywołanych wartości może pojawić się w kolumnie odsyłającej, co czyni ją jednoosobową opcjonalną. Jest to dość proste i dość wyrozumiałe podejście, które działa dobrze.

  • Stosuj normalną relację FK, która może modelować 1: m, i pozwól aplikacji upewnić się, że w praktyce jest zawsze 1: 1. Nie polecam tego, zmniejszenie wydajności zapisu jest niewielkie tylko przy dodawaniu unikalnego indeksu FK i pomaga zapewnić poprawność danych, znaleźć błędy aplikacji i uniknąć pomylenia kogoś, kto musi później zmodyfikować schemat.

  • Utwórz wzajemne klucze obce - możliwe tylko wtedy, gdy twoja baza danych obsługuje odroczone ograniczenia klucza obcego. Jest to nieco bardziej skomplikowane w kodowaniu, ale pozwala implementować relacje obowiązkowe jeden-do-jednego. Każda jednostka ma klucz obcy odnoszący się do PK innych w unikalnej kolumnie. Jedno lub oba ograniczenia muszą być DEFERRABLE i INITIALLY DEFERRED lub używane z połączeniem SET CONSTRAINTS, ponieważ należy odroczyć jedną z kontroli ograniczenia, aby ustawić zależność cykliczną. Jest to dość zaawansowana technika, która nie jest konieczna w przypadku większości zastosowań.

  • Użyj pre-commit triggers, jeśli twoja baza danych je obsługuje, więc możesz zweryfikować, że gdy jednostka A jest wstawiona, to wstawia się również jedną jednostkę B i odwrotnie, z odpowiednimi sprawdzeniami dla aktualizacji i usuwania. Może to być powolne i zwykle nie jest konieczne, a wiele systemów baz danych nie obsługuje wyzwalaczy poprzedzających zatwierdzenie.

+0

, więc w moim przypadku factory_id będzie musiał być UNIQUE, ponieważ mam to REFERENCE przez tabeli pracownika? –

+0

@GeorgiAngelov Tak, 'lab4.employee.factory_id' * strona odsyłająca * może być oznaczona jako" UNIQUE ". Pomyśl o tym: kolumna FK, która jest unikalna, może pomieścić najwyżej jedną z każdej wartości kolumny o którym mowa w PK. Powiedzenie "factory_id", gdy używasz tej nazwy w więcej niż jednym miejscu, brzmi trochę jak powiedzenie "dostań się samolotem Quantas" na lotnisku - * który samolot? * Zauważ, że tworzy to relację, która jest * opcjonalna * po stronie odsyłającej ; * co najwyżej * jeden pracownik może zarządzać fabryką, ale nie ma wymogu, aby dana fabryka miała menedżera. –

+0

dzięki. To naprawdę wyjaśnia rzeczy. Doceniam twoją pomoc. –