none
Grundsätzlich zu Beziehungen RRS feed

  • Frage

  • Hallo,

    ich erstelle z.Zt. ein DatenbankModell.

    Beziehungen zwischen Tabellen kann ich ja im Entwurf  definieren oder bei der Datenauswertung per JOIN erreichen.

    Meine Fragen:

    Welche Beziehungen sind performanter?

    Wie werden die Beziehungen im Entwurf in die CREATE TABLE-Stored-Procedure eingebaut werden?

    Ich suche eine Anleitung wie 1:1, 1:N, N:M Beziehungen beschrieben werden und wie sie in die CREATE TABLE-Stored-Procedure eingebaut werden?

    Danke Michael

    Freitag, 15. Juli 2011 07:42

Antworten

  • Hallo Michael,

    mit Performanz (Geschwindigkeit) hat das überhaupt nichts zu tun.
    Und bei einem Entwurf eines Datenmodells steht hinten an.

    Zuerst gilt es die Datenmodell zu normalisieren.
    Die Fremdschlüssel sind das Mittel, um die dabei ermittelten Beziehungen
    zwischen den Entitäten (Tabellen) festzulegen - siehe Entity-Relationship-Modell.

    Fremdschlüssel, bei denen die referenzierte Spalte eindeutig ist - durch eine eindeutige Einschränkung (UNIQUE Constraint)
    oder einen eindeutigen Index, sind 1 : 1 Beziehungen, alle anderen 1 : N.
    Lässt die Fremdschlüssel-Spalte Nullwerte zu, so ist es eine 0 : 1/N Beziehung, 

    M : N Beziehungen lassen sich nur durch eine weitere Tabelle herstellen,
    die über zwei Fremdschlüsselbeziehungen verfügt, siehe Kardinalität.

    Erstellen kannst Du Fremdschlüssel direkt in der CREATE TABLE-Anweisung oder später über die ALTER TABLE Anweisung.

    Da die referenzierte Tabelle dazu jeweils vorhanden sein muss, wird man häufiger über ALTER TABLE arbeiten.

    Zur Geschwindigkeit:
    Ein Fremdschlüssel erzeugt keinen Index, so dass man für umfangreichere Tabellen
    einen Index für die Fremdschlüsselspalte(n) mit CREATE INDEX erstellen sollte.

    Zu beachten wäre, dass der SQL Server nur solche mit WITH CHECK als "vertrauenswürdig" einstuft,
    und dafür optimalere Abfragepläne erzeugen kann, da er "weiß", dass die Beziehung überprüft wurde.

    Dafür (sehr einfache) Beispiele in TRANSACT-SQL:

    USE tempdb;
    GO
    
    CREATE TABLE dbo.Auftrag
    (
    	AuftragID int NOT NULL,
    	CONSTRAINT PK_Auftrag PRIMARY KEY (AuftragID)
    );
    
    -- Artikel
    CREATE TABLE dbo.Artikel (
       ArtikelID int NOT NULL,
       CONSTRAINT PK_Artikel PRIMARY KEY (ArtikelID) );
    
    CREATE TABLE dbo.AuftragPosition
    (
    	AuftragPositionID int NOT NULL,
    	
    	AuftragID int NOT NULL,	-- Verweist auf Auftrag
    	ArtikelID int NOT NULL, -- Verweist auf Artikel (s. u.)
    	
    	CONSTRAINT PK_AuftragPosition PRIMARY KEY (AuftragPositionID),
    	
    	-- Fremdschlüssel Verweis dbo.Auftrag
      CONSTRAINT FK_AuftragPosition_Auftrag
    	   FOREIGN KEY (AuftragID)
    		 REFERENCES dbo.Auftrag (AuftragID) 
    );
    
    -- via ALTER TABLE für dbo.Artikel
    ALTER TABLE dbo.AuftragPosition WITH CHECK 
    ADD CONSTRAINT FK_AuftragPosition_Artikel 
        FOREIGN KEY (ArtikelID)
        REFERENCES dbo.Artikel (ArtikelID);
    GO
    -- Auftragposition: Indizes für schnellere Zugriffe
    CREATE INDEX IX_AuftragPosition_Auftrag ON dbo.AuftragPosition (AuftragID);
    CREATE INDEX IX_AuftragPosition_Artikel ON dbo.AuftragPosition (ArtikelID);
    GO
    
    -- Stückliste/Baugruppen-Beispiel für eine M : N Beziehung 
    -- Verweist zweimal auf Artikel
    CREATE TABLE dbo.Baugruppe
    (
    	BaugruppeArtikelID int NOT NULL
    		CONSTRAINT FK_Baugruppe_Artikel_Gruppe FOREIGN KEY 
    		REFERENCES dbo.Artikel (ArtikelID),
    	
    	TeilArtikelID int NOT NULL
    		CONSTRAINT FK_Baugruppe_Artikel_Teil FOREIGN KEY 
    		REFERENCES dbo.Artikel (ArtikelID),
    
    	Menge INT NOT NULL,
    	
    	CONSTRAINT PK_Baugruppe PRIMARY KEY (BaugruppeArtikelID, TeilArtikelID)
    );
    
    

    Gruß Elmar

    • Als Antwort markiert mimuel Freitag, 15. Juli 2011 10:53
    Freitag, 15. Juli 2011 09:31
    Beantworter

Alle Antworten

  • Ein im Entwurf definierte Beziehung (Deklarative Referentielle Integrität) ist eine Einschränkung (Constraint), welcher sicherstellt, das davon abweichende Werte erst gar nicht erfasst werden können. Sie sind grundlegender und notwendiger Bestandteil um Datenintegrität zu gewährleisten.

    Aufgrund deiner Frage solltest du dich mit den Grundlagen beschäfitgen, dafür kann ich als Einsteigerlektüre folgendes empfehlen:

    http://www.amazon.de/Relationale-Datenbanken-CD-ROM-aktualisierte-Auflage/dp/3827326567/ref=sr_1_2?s=books&ie=UTF8&qid=1310717397&sr=1-2

    Ansonsten: FOREIGN KEY-Einschränkungen

     

     


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Freitag, 15. Juli 2011 08:11
    Moderator
  • Hallo Michael,

    mit Performanz (Geschwindigkeit) hat das überhaupt nichts zu tun.
    Und bei einem Entwurf eines Datenmodells steht hinten an.

    Zuerst gilt es die Datenmodell zu normalisieren.
    Die Fremdschlüssel sind das Mittel, um die dabei ermittelten Beziehungen
    zwischen den Entitäten (Tabellen) festzulegen - siehe Entity-Relationship-Modell.

    Fremdschlüssel, bei denen die referenzierte Spalte eindeutig ist - durch eine eindeutige Einschränkung (UNIQUE Constraint)
    oder einen eindeutigen Index, sind 1 : 1 Beziehungen, alle anderen 1 : N.
    Lässt die Fremdschlüssel-Spalte Nullwerte zu, so ist es eine 0 : 1/N Beziehung, 

    M : N Beziehungen lassen sich nur durch eine weitere Tabelle herstellen,
    die über zwei Fremdschlüsselbeziehungen verfügt, siehe Kardinalität.

    Erstellen kannst Du Fremdschlüssel direkt in der CREATE TABLE-Anweisung oder später über die ALTER TABLE Anweisung.

    Da die referenzierte Tabelle dazu jeweils vorhanden sein muss, wird man häufiger über ALTER TABLE arbeiten.

    Zur Geschwindigkeit:
    Ein Fremdschlüssel erzeugt keinen Index, so dass man für umfangreichere Tabellen
    einen Index für die Fremdschlüsselspalte(n) mit CREATE INDEX erstellen sollte.

    Zu beachten wäre, dass der SQL Server nur solche mit WITH CHECK als "vertrauenswürdig" einstuft,
    und dafür optimalere Abfragepläne erzeugen kann, da er "weiß", dass die Beziehung überprüft wurde.

    Dafür (sehr einfache) Beispiele in TRANSACT-SQL:

    USE tempdb;
    GO
    
    CREATE TABLE dbo.Auftrag
    (
    	AuftragID int NOT NULL,
    	CONSTRAINT PK_Auftrag PRIMARY KEY (AuftragID)
    );
    
    -- Artikel
    CREATE TABLE dbo.Artikel (
       ArtikelID int NOT NULL,
       CONSTRAINT PK_Artikel PRIMARY KEY (ArtikelID) );
    
    CREATE TABLE dbo.AuftragPosition
    (
    	AuftragPositionID int NOT NULL,
    	
    	AuftragID int NOT NULL,	-- Verweist auf Auftrag
    	ArtikelID int NOT NULL, -- Verweist auf Artikel (s. u.)
    	
    	CONSTRAINT PK_AuftragPosition PRIMARY KEY (AuftragPositionID),
    	
    	-- Fremdschlüssel Verweis dbo.Auftrag
      CONSTRAINT FK_AuftragPosition_Auftrag
    	   FOREIGN KEY (AuftragID)
    		 REFERENCES dbo.Auftrag (AuftragID) 
    );
    
    -- via ALTER TABLE für dbo.Artikel
    ALTER TABLE dbo.AuftragPosition WITH CHECK 
    ADD CONSTRAINT FK_AuftragPosition_Artikel 
        FOREIGN KEY (ArtikelID)
        REFERENCES dbo.Artikel (ArtikelID);
    GO
    -- Auftragposition: Indizes für schnellere Zugriffe
    CREATE INDEX IX_AuftragPosition_Auftrag ON dbo.AuftragPosition (AuftragID);
    CREATE INDEX IX_AuftragPosition_Artikel ON dbo.AuftragPosition (ArtikelID);
    GO
    
    -- Stückliste/Baugruppen-Beispiel für eine M : N Beziehung 
    -- Verweist zweimal auf Artikel
    CREATE TABLE dbo.Baugruppe
    (
    	BaugruppeArtikelID int NOT NULL
    		CONSTRAINT FK_Baugruppe_Artikel_Gruppe FOREIGN KEY 
    		REFERENCES dbo.Artikel (ArtikelID),
    	
    	TeilArtikelID int NOT NULL
    		CONSTRAINT FK_Baugruppe_Artikel_Teil FOREIGN KEY 
    		REFERENCES dbo.Artikel (ArtikelID),
    
    	Menge INT NOT NULL,
    	
    	CONSTRAINT PK_Baugruppe PRIMARY KEY (BaugruppeArtikelID, TeilArtikelID)
    );
    
    

    Gruß Elmar

    • Als Antwort markiert mimuel Freitag, 15. Juli 2011 10:53
    Freitag, 15. Juli 2011 09:31
    Beantworter