Seite 2 von 5 ErsteErste 1234 ... LetzteLetzte
Ergebnis 11 bis 20 von 45

Thema: Datenbankprojekt

  1. #11
    andetsa ist offline Neuer Benutzer
    Registriert seit
    21.02.2010
    Beiträge
    18

    Standard

    Zitat Zitat von akretschmer Beitrag anzeigen
    Du hast eine Reihe von Tabellen, die untereinander via FK-Beziehungen verknüpft sind. Das sind diese Zeilen, hier mal ein Beispiel:

    Code:
    ALTER TABLE ONLY rel_person_artikel
        ADD CONSTRAINT fk_person_id FOREIGN KEY (fk_person_id) REFERENCES person(person_id);
    Genau, und das ist auch richtig so, oder? Vielleicht sollten wir zunächst klarstellen, ob das ERM sowie die psql DB so korrekt angelegt sind?! Ich hoffe doch das ist der Fall?

    Damit kannst Du nur Werte für fk_person_id in der Tabelle rel_person_artikel eintragen, für die vorher in der Tabelle person ein Eintrag mit der gleichen person_id gemacht wurde.

    Andreas
    Genau und ich stehe jetzt vor dem Problem wie ich die Daten in die DB einfüge, sofern die DB so überhaupt richtig ist. Geht das mit case Ausdrücken oder wie stellt man das in der Regel an eine solche DB mit Daten zu befüllen?

    Danke!

  2. #12
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von andetsa Beitrag anzeigen
    Genau, und das ist auch richtig so, oder? Vielleicht sollten wir zunächst klarstellen, ob das ERM sowie die psql DB so korrekt angelegt sind?! Ich hoffe doch das ist der Fall?
    Auf den ersten Blick schaut es gut aus, also die Tabellenstruktur.

    Genau und ich stehe jetzt vor dem Problem wie ich die Daten in die DB einfüge, sofern die DB so überhaupt richtig ist. Geht das mit case Ausdrücken oder wie stellt man das in der Regel an eine solche DB mit Daten zu befüllen?

    Danke!
    Nun, man füllt zuerst die Tabellen, auf die später referenziert wird. Oder man stellt die Constraints deferred. Damit kann ich auch erst einmal Daten in die Tabelle mit dem FK eingeben:

    Code:
    test=# create table master (id serial primary key );
    NOTICE:  CREATE TABLE will create implicit sequence "master_id_seq" for serial column "master.id"
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "master_pkey" for table "master"
    CREATE TABLE
    test=*# create table slave (master_id int references master deferrable initially deferred);
    CREATE TABLE
    test=*# insert into slave values(1);
    INSERT 0 1
    Oder man wartet auf Release 9.1, welche dann hoffentlich writeable CTE drin hat. Dann kannst Du viele Tabellen mit einem einzigen Insert befüllen:

    my blog: writeable CTE - a short performance test

    Leider kommt das nicht schon in 9.0, sehr sehr schade...


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  3. #13
    andetsa ist offline Neuer Benutzer
    Registriert seit
    21.02.2010
    Beiträge
    18

    Standard

    Zitat Zitat von akretschmer Beitrag anzeigen
    Nun, man füllt zuerst die Tabellen, auf die später referenziert wird.
    Ok, das heißt in meinem Fall, ich fülle zunächst die "Nichtrelationstabellen" artikel, ausgabe, keywords, person und zeitschrift.

    Das hat soweit alles geklappt, knapp 9000 Artikel sind jetzt in der Datenbank. Und jetzt weiß ich nicht weiter. Wie stelle ich jetzt die Referenzen her?

    Bspw. muss der Tabelle artikel die ausgabe_id der Tabelle ausgabe als FK hinzugefügt werden, der Tabelle ausgabe die zeitschrift_id der Tabelle zeitschrift etc.

    Bei der Tabelle rel_person_artikel muss die person_id und die artikel_id verknüpft eingefügt werden.

    Das ist jetzt für mein Hirn nicht mehr ganz so trivial

    Wie muss ich vorgehen?

  4. #14
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von andetsa Beitrag anzeigen
    Ok, das heißt in meinem Fall, ich fülle zunächst die "Nichtrelationstabellen" artikel, ausgabe, keywords, person und zeitschrift.

    Das hat soweit alles geklappt, knapp 9000 Artikel sind jetzt in der Datenbank. Und jetzt weiß ich nicht weiter. Wie stelle ich jetzt die Referenzen her?

    Bspw. muss der Tabelle artikel die ausgabe_id der Tabelle ausgabe als FK hinzugefügt werden, der Tabelle ausgabe die zeitschrift_id der Tabelle zeitschrift etc.

    Bei der Tabelle rel_person_artikel muss die person_id und die artikel_id verknüpft eingefügt werden.

    Das ist jetzt für mein Hirn nicht mehr ganz so trivial

    Wie muss ich vorgehen?
    Ahhh, nun weiß ich erst einmal, wo Dein Problem ist.

    Nun, der Weg ist eigentlich wie folgt:

    - Insert in die Haupttabelle. Dabei wird ein neuer Wert für die SERIAL-Spalte generiert.
    - Dann Eingabe der Detaildaten. Dazu nutzt man die Funktion currval(), um an den Wert der Sequence zu gelangen.

    Kurzdemo:

    Code:
    test=# create table master (id serial primary key, name text);
    NOTICE:  CREATE TABLE will create implicit sequence "master_id_seq" for serial column "master.id"
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "master_pkey" for table "master"
    CREATE TABLE
    test=*# create table detail (id_master int references master, detail int);
    CREATE TABLE
    test=*# insert into master (name) values ('Andreas');
    INSERT 0 1
    test=*# insert into detail (id_master, detail) values (currval('master_id_seq'), 10);
    INSERT 0 1
    test=*# select * from master;
     id |  name
    ----+---------
      1 | Andreas
    (1 row)
    
    test=*# select * from detail ;
     id_master | detail
    -----------+--------
             1 |     10
    (1 row)
    Du könntest Dir auch den Link von mir ansehen, da habe ich mittels plpgsql-Script einige tausend Datensätze in ein solches Schema eingefügt.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  5. #15
    ads
    ads ist offline Super-Moderator
    Registriert seit
    08.02.2006
    Ort
    MD
    Beiträge
    4.020

    Standard

    Statt currval() könnte man auch INSERT ... RETURNING nutzen.
    Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören

    Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

    PostgreSQL Service & Support

  6. #16
    flhe ist offline Neuer Benutzer
    Registriert seit
    20.01.2010
    Beiträge
    15

    Standard

    Zitat Zitat von akretschmer Beitrag anzeigen
    Ahhh, nun weiß ich erst einmal, wo Dein Problem ist.

    Nun, der Weg ist eigentlich wie folgt:

    - Insert in die Haupttabelle. Dabei wird ein neuer Wert für die SERIAL-Spalte generiert.
    - Dann Eingabe der Detaildaten. Dazu nutzt man die Funktion currval(), um an den Wert der Sequence zu gelangen.

    Andreas
    Danke, das hat mir jetzt sehr geholfen - nun hab ich das Konzept verstanden. Und das ist also die Standard-Herangehensweise beim Referenzieren von Tabellen?

    Ich habe das ganze für einen Datensatz (meiner 9000) durchgeführt und es hat geklappt, INNER JOINS funktionieren einwandfrei. Um sicherzustellen, dass meine Vorgehensweise korrekt war hier ein Codebeispiel:

    Code:
    -- Referenzierung der Tabellen zeitschrift, ausgabe und artikel
    
    INSERT INTO zeitschrift (name,kurzname,issn)
    VALUES ('Journal B','JB','0000-1111');
    
    INSERT INTO ausgabe (fk_zeitschrift_id,heft_nr,jahr,jahrgang)
    VALUES (currval('zeitschrift_zeitschrift_id_seq'),'12','1989','4');
    
    INSERT INTO artikel (fk_ausgabe_id,dok_nr,titel,inhalt,anfangsseite,endseite,erfassungsdatum,korrekturdatum)
    VALUES (currval('ausgabe_ausgabe_id_seq'),'1','Ein Titel','Ein Inhalt','22','28','1980-12-12','1981-04-12');
    usw. bis man alle Tabellen durch hat.

    Jetzt stellt sich mir natürlich die Frage was passiert wenn der Datensatz mit der keyword_id=1 das keyword='Heuchler' und 100 Datensätze später kommt der Datensatz keyword_id=101 der auch das keyword='Heuchler' hat? Oder bei Personen, die mehrmals vorkommen, da sie mehrere Artikel verfasst haben?

    Wie geht man hier vor?

    Gruß

  7. #17
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von flhe Beitrag anzeigen

    Jetzt stellt sich mir natürlich die Frage was passiert wenn der Datensatz mit der keyword_id=1 das keyword='Heuchler' und 100 Datensätze später kommt der Datensatz keyword_id=101 der auch das keyword='Heuchler' hat? Oder bei Personen, die mehrmals vorkommen, da sie mehrere Artikel verfasst haben?

    Wie geht man hier vor?

    Gruß
    Bahnhof. Sorry.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  8. #18
    flhe ist offline Neuer Benutzer
    Registriert seit
    20.01.2010
    Beiträge
    15

    Standard

    Etwas bescheiden formuliert, sorry. Also:

    Dieses currval()-Konzept setzt ja voraus, dass jeder Datensatz einzeln eingepflegt werden muss, denn der Wert der Sequenz (der currrent value) darf sich beim Einfügen des Datensatzes ja nicht ändern.

    Das führte nun zu der Frage was passiert wenn folgendes eintritt.

    Ich habe 9000 Datensätze. Da kann es ja durchaus vorkommen, dass ein Keyword z.B. das Keyword "Heuchler" in mehreren Datensätzen vorkommt.

    Bspw. in Datensatz 1:

    keyword_id=1
    keyword='Heuchler'

    und später in Datensatz 400:

    keyword_id=400
    keyword='Heuchler'

    Das wäre ja nicht im Sinne des Erfinders wenn das so in der Tabelle keywords stehen würde, richtig?

    Hoffe du hast meine Frage verstanden!

  9. #19
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von flhe Beitrag anzeigen
    Etwas bescheiden formuliert, sorry. Also:

    Dieses currval()-Konzept setzt ja voraus, dass jeder Datensatz einzeln eingepflegt werden muss, denn der Wert der Sequenz (der currrent value) darf sich beim Einfügen des Datensatzes ja nicht ändern.

    Das führte nun zu der Frage was passiert wenn folgendes eintritt.

    Ich habe 9000 Datensätze. Da kann es ja durchaus vorkommen, dass ein Keyword z.B. das Keyword "Heuchler" in mehreren Datensätzen vorkommt.

    Bspw. in Datensatz 1:

    keyword_id=1
    keyword='Heuchler'

    und später in Datensatz 400:

    keyword_id=400
    keyword='Heuchler'

    Das wäre ja nicht im Sinne des Erfinders wenn das so in der Tabelle keywords stehen würde, richtig?

    Hoffe du hast meine Frage verstanden!
    Ja.

    Dann fragt man die ID halt ab:

    Code:
    test=*# create table master (id serial primary key, name text);
    NOTICE:  CREATE TABLE will create implicit sequence "master_id_seq" for serial column "master.id"
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "master_pkey" for table "master"
    CREATE TABLE
    Time: 4.693 ms
    test=*# create table slave (id_master int references master, name text);
    CREATE TABLE
    Time: 5.796 ms
    test=*# insert into master (id, name) values (default, 'master1');
    INSERT 0 1
    Time: 0.805 ms
    test=*# insert into master (id, name) values (default, 'master2');
    INSERT 0 1
    Time: 0.317 ms
    test=*# insert into master (id, name) values (default, 'master3');
    INSERT 0 1
    Time: 0.299 ms
    test=*# insert into slave (id_master, name) values((select id from master where name ='master1'), 'slave1');
    INSERT 0 1
    Time: 0.800 ms
    test=*# insert into slave (id_master, name) values((select id from master where name ='master3'), 'slave3');
    INSERT 0 1
    Time: 0.419 ms
    test=*# insert into slave (id_master, name) values((select id from master where name ='master1'), 'slave1');
    INSERT 0 1
    Time: 0.466 ms
    test=*#
    test=*# select * from master;
     id |  name
    ----+---------
      1 | master1
      2 | master2
      3 | master3
    (3 rows)
    
    Time: 0.276 ms
    test=*# select * from slave;
     id_master |  name
    -----------+--------
             1 | slave1
             3 | slave3
             1 | slave1
    (3 rows)
    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  10. #20
    flhe ist offline Neuer Benutzer
    Registriert seit
    20.01.2010
    Beiträge
    15

    Standard

    Also mir ist schon klar, was du machst allerdings kann ich dein Beispiel nicht auf mein Problem übertragen.

    Angenommen das erste Dokument, das ich in meine DB schreibe hat 3 Keywords (Heuchler,Affe,Hund). Sie bekommen die keyword_ids 1,2 und 3.

    Dann würden meine Statement so aussehen (korrigiere mich wenn ich falsch liege):

    Code:
    INSERT INTO keywords (keywords)
    VALUES ('Heuchler');
    
    INSERT INTO rel_keywords_artikel (fk_artikel_id, fk_keywords_id)
    VALUES (currval('artikel_artikel_id_seq'), currval('keywords_keywords_id_seq'));
    
    INSERT INTO keywords (keywords)
    VALUES ('Affe');
    
    INSERT INTO rel_keywords_artikel (fk_artikel_id, fk_keywords_id)
    VALUES (currval('artikel_artikel_id_seq'), currval('keywords_keywords_id_seq'));
    
    INSERT INTO keywords (keywords)
    VALUES ('Hund');
    
    INSERT INTO rel_keywords_artikel (fk_artikel_id, fk_keywords_id)
    VALUES (currval('artikel_artikel_id_seq'), currval('keywords_keywords_id_seq'));
    Jetzt füge ich das zweite Dokument in die DB ein:

    Code:
    INSERT INTO keywords (keywords)
    VALUES ('Stadt');
    
    INSERT INTO rel_keywords_artikel (fk_artikel_id, fk_keywords_id)
    VALUES (currval('artikel_artikel_id_seq'), currval('keywords_keywords_id_seq'));
    
    INSERT INTO keywords (keywords)
    VALUES ('Affe');
    
    INSERT INTO rel_keywords_artikel (fk_artikel_id, fk_keywords_id)
    VALUES (currval('artikel_artikel_id_seq'), currval('keywords_keywords_id_seq'));
    Affe käme zum zweiten Mal vor und hätte unterschiedliche IDs. Um das zu verhindern muss ich ja überprüfen, ob der Wert schon in der Tabelle keyword vorhanden ist. Dazu muss ich doch aber den currval() überprüfen, den ich gerade eintrage?

    Wie sähe das in meinem konkreten Beispiel aus?

    Danke! Gruß

Seite 2 von 5 ErsteErste 1234 ... LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum