2011-09-05 11 views
6

Witam mam krótkie pytanie dotyczące projektu bazy danych. Próbowałem również wyszukiwania, ale nie mogę znaleźć tego, czego szukam. Więc tutaj jest moje pytanie:1: Relacja N gdzie N musi być co najmniej jednym wpisem

Mam dwie tabele bazy danych Idea i mediów (1: N). Zasadniczo oznacza to, że jedna idea nie może mieć żadnego, jednego lub kilku mediów. ALE zadałem sobie pytanie, czy można zdefiniować tabelę, w której każdy pomysł musi zawierać co najmniej jeden nośnik. Jeśli jest to możliwe, w jaki sposób mogę to osiągnąć z MS SQL Server 2008?

Mam nadzieję, że ktoś może mi pomóc.

Thx dużo za pomoc

UPDATE: jest to, jak to wygląda w tej chwili:

enter image description here

+2

Nie jestem pewien, w jaki sposób można to zrobić, przechowując 'Media' w oddzielnej tabeli: w jaki sposób wstawi się dane? Musisz wstawić najpierw do jednej tabeli, a potem do drugiej. Możesz spróbować umieścić pierwsze "Media" w "Idea" (de-normalizacji) i zadeklarować pola jako 'not null' - ale nie poleciłbym tego. Możesz być lepiej z jakąś logiką w kodzie zamiast bazy danych. –

+0

Zgadzam się z Aleks. Myślę, że jest to reguła biznesowa, która należy gdzieś do warstwy pośredniej, a nie do bazy danych. – David

+0

@Aleks dołączanie FK NOT NULL z Idea to Media nie jest rzadkością. To proste, i tak, będzie musiał najpierw wypełnić Media. – vol7ron

Odpowiedz

2

Po pierwsze, istnieje reguła projektowa, w której tabela modeluje jeden typ obiektu lub relację między typami jednostek, ale nie oba. Dlatego wyobrażam sobie trzy tabele: Media (podmiot), Idea (podmiot) i IdeasMedia (relacja). p.s. wiesz, że liczba pojedyncza "mediów" jest "średnia", prawda? :)

Oto niektóre standardowe SQL DDL-92, która skupia się wyłącznie na klucze:

CREATE TABLE Media (MediaID INTEGER NOT NULL UNIQUE); 
CREATE TABLE Idea (IdeaID INTEGER NOT NULL UNIQUE); 
CREATE TABLE IdeasMedia 
(
MediaID INTEGER NOT NULL REFERENCES Media (MediaID), 
IdeaID INTEGER NOT NULL REFERENCES Idea (IdeaID) 
); 
CREATE ASSERTION Idea_must_have_media DEFERRABLE 
    CHECK (
      NOT EXISTS (
         SELECT * 
         FROM Idea AS i 
         WHERE NOT EXISTS (
             SELECT * 
              FROM IdeasMedia AS im 
              WHERE im.MediaID = i.IdeaID 
             ) 
        ) 
     ); 

Jest „jajka i kury” scenariusz tutaj: nie można utworzyć pomysł z bez odwoływania IdeasMedia ale może Stwórz IdeasMedia bez tworzenia Idea!

Idealnym (opartym na ustawieniach) rozwiązaniem byłoby SQL Standard do obsługi wielu zadań, np.

INSERT INTO Media (MediaID) VALUES (22), 
    INSERT INTO Idea (IdeaID) VALUES (55), 
    INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (22, 55); 

gdzie średnik wskazuje SQL oświadczenie granicę, przy której są zaznaczone ograniczenia punkt i przecinki oznaczający podrzędne oświadczenia.

Niestety, nie ma planów dodania tego opartego na zestawie paradygmatu do standardu SQL.

SQL-92 (proceduralne) Rozwiązaniem tego problemu jest następujący:

BEGIN TRANSACTION; 
INSERT INTO Media (MediaID) VALUES (22); 
SET CONSTRAINTS Idea_must_have_media DEFERRED; 
-- omit the above if the constraint was declared as INITIALLY DEFERRED. 
INSERT INTO Idea (IdeaID) VALUES (55); 
INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (55, 22); 
SET CONSTRAINTS Idea_must_have_media IMMEDIATE; 
-- above may be omitted: constraints are checked at commit anyhow. 
COMMIT TRANSACTION; 

Niestety, SQL Server nie obsługuje CREATE ASSERTION ani CHECK ograniczenia, które mogą odnosić się do innych tabel ani odroczeniu ograniczeń!

Osobiście bym sobie z tym poradzić w SQL Server w następujący sposób:

  • Tworzenie 'pomocnik' przechowywane procs dodawać, zmieniać i usuwać Ideas i ich odpowiednie IdeasMedia relacje.
  • Usuń uprawnienia aktualizacji z tabel, aby zmusić użytkowników do korzystania z procedur .
  • Możliwe jest użycie wyzwalaczy do obsługi scenariuszy podczas usuwania encji Media i Idea.

Z pewnością ta (ponownie proceduralna) implementacja jest daleko od idealnego podejścia opartego na zestawie, co prawdopodobnie tłumaczy, dlaczego większość programistów kodu SQL przymyka oko na wymóg relacji 1: 1.N, a zamiast tego załóżmy, że projektant miał na myśli 1: 0..N !!

+0

Hej onedaywhen dzięki za naprawdę świetną odpowiedź !!! Twoja odpowiedź jest bardzo obszerna i opisuje różne podejścia do osiągnięcia rozwiązania mojego problemu. Naprawdę to doceniam. Mimo to wszystkie rozwiązania są dość brzydkie. Postanowiłem sobie z tym poradzić w mojej logice biznesowej. I thx dla korekty gramatycznej;) – MUG4N

1

utworzeniu FK (klucz obcy) w Idea do PK (klucz podstawowy) w Media. W tym samym czasie zastosuj ograniczenie FK do NOT NULL.

Jeśli masz już dane w tabeli, see here


Aby zilustrować:

Media    Idea 
-----    ---- 
id | type   id | description  | media_id 
----+-----   ----+-------------------+---------- 
1 | TV    90 | advertise  | 2 
2 | Magazine  90 | advertise  | 1 
3 | Mail   91 | superbowl party | 1 
        91 | superbowl party | 3 

Nie mówię, że to jest wielki projekt, a ja na pewno nie wiem, co się tabele są przechowywane (wskazane przez mój słaby przykład), ale idea nie może istnieć bez wpisu Media, do którego ma prowadzić link. Nie ma powiązań tam iz powrotem, pytasz o 1: N, nie N: N, które możesz chcieć.

Kiedy myślimy o nazwach stołów, wygląda na to, że pomysł się cofa. Myślę, że masz 1: Media to N: Pomysły zamiast na odwrót.


CREATE TABLE idea (
    id  integer 
    , media_id integer NOT NULL REFERENCES media 
) 

--or-- 

CREATE TABLE idea (
    id   integer 
    , media_id NOT NULL 
    , FOREIGN KEY (media_id) REFERENCES media 
); 

Uwaga: To nie jest znormalizowany, więc będzie trzeba trzecią tabelę pasujące sprzężeń.

+1

Więc dwie tabele mają klucze do siebie nawzajem? Byłoby to trochę dziwne, nieprawdaż? A także cierpi na problem "kurze i jajo" określony przez Aleksa G. – David

+0

Oznacza to odsyłacz ... Słyszałem złe rzeczy na temat odsyłaczy. Czy jest to powszechna najlepsza praktyka? A może są jakieś najlepsze praktyki w tej sytuacji? – MUG4N

+0

@ David, co masz na myśli, dlaczego miałbyś mieć FK dla siebie nawzajem, jest tylko jeden sposób FK z Idea to Media – vol7ron

Powiązane problemy