Zum Inhalt springen

mySQL/ Primary key über mehrere Tabellen?


Wuk

Empfohlene Beiträge

Hallo

Ich habe die Foren und die Zusammenstellungen durchsucht aber leider nicht gefunden was ich suchte. Vieleicht kann mir aber denoch jemand helfen.

Ich suche ein Möglichkeit in mehreren Tabellen Einträge mit keys zu versehen sodaß jeder Eintrag, egal in welcher Tabelle er gemacht wird, einzigartig (primary key) in allen diesen Tabellen ist. Ein Autoinkrement wäre dazu noch klasse.

Also wenn ich in tabelle1 einen Eintrag mache, dann bekommt der die ID 1, ein weiterer Eintrag die ID 2. Ein Eintrag in tabelle2 dann ID 3 (nicht 1) und ein weiterer in tabelle1 die ID 4 (nicht 3) usw.

Also eine Primary Key Spalte über mehrere Tabellen.

Ich möchte eine Tabelle erstellen (tabelleX) derren Fremdschlüssel eindeutig auf einen Eintrag in einer der anderen Tabellen verweist (tabelle1,tabelle2,..). Genauer gesagt, möchte ich mit Hilfe des Primärschlüssels in einer der Tabellen alle Einträge mit diesem Fremdschlüssel in TabelleX auslesen, was einfach ist. Das Anlegen der Einträge in den Tabellen(1,2,3,..) ist das Problem.

Ist so etwas automatisch möglich ohne das ich selber alle Tabellen nach dem größten Index befragen muss um selber den neuen Index zu errechnen wie zB ( max( MAX(tabelle1.ID) , MAX(tabelle2.ID) , MAX(tabelle3.ID) )+1 )?

Gruß Wuk

Link zu diesem Kommentar
Auf anderen Seiten teilen

Einen Primary Key kann man nur auf ein Feld einer Tabelle legen.

Was Du da beschreibst könnte nur auftretten, wenn Du eine 1:1 Beziehung auf 2 Tabellen aufgesplittet hast, denke ich. Ob das so den Sinn macht, dann in beiden Tabellen den gleichen Wert als Primary Key zu haben?

Ich würde da in der 2. Tabelle eher auch noch einen Foreign Key setzen und dann über JOINS gehen.

Aber ein Lösungsweg wäre vieleicht den Primary Key der 2. Tabelle nicht als auto_increment zu setzen sondern einfach nach dem Einfügen in der ersten Tabelle den zuletzt eingefügten auto_increment- Wert, nämlich den der ersten Tabelle, auszulesen und dann in die 2. Tabelle zu schreiben. In php in Verbindung zu MySQL gibt es da die Funktion mysql_insert_id().

http://www.php.net/manual/de/function.mysql-insert-id.php

Link zu diesem Kommentar
Auf anderen Seiten teilen

Einen Primary Key kann man nur auf ein Feld einer Tabelle legen.

So stimmt das nicht ganz... du kannst natürlich mehrere Primärschluessel in einer Tabelle haben.

"Der Primärschluessel" setzt sich dann aus diesen Feldern zusammen.

s.h. es darf dann. z.b. 2 mal die gleiche ID da sein wenn nicht auch die beiden anderen gleich sind ...

(Ich weiß sche**s beispiel aber mir fiel nix anderes ein ....)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich suche ein Möglichkeit in mehreren Tabellen Einträge mit keys zu versehen sodaß jeder Eintrag, egal in welcher Tabelle er gemacht wird, einzigartig (primary key) in allen diesen Tabellen ist. Ein Autoinkrement wäre dazu noch klasse.

unter oracle verwendet man dafür sequenzen, die mysql leider nicht hat. braucht man in dem fall auch gar nicht. entweder du erstellst in tabellex für jede tabelle ein eigenes feld oder verwendest eine m:n relation, um die pk den tabellen zuzuordnen.

-j

Link zu diesem Kommentar
Auf anderen Seiten teilen

So stimmt das nicht ganz... du kannst natürlich mehrere Primärschluessel in einer Tabelle haben.

machen wir es mal richtig:

jede tabelle hat genau einen primärschlüssel, der sich aus 1 bis n spalten der tabelle zusammen setzt und jede zeile der tabelle eindeutig identifiziert.

-j

Link zu diesem Kommentar
Auf anderen Seiten teilen

An die Möglichkeit hatte ich auch gar nicht mehr gedacht seid ich das letzte Mal soetwas in der Datenbank eines Browserspieles gefunden habe und dort Koordianten, die sich aus 3 Angaben - Feldern - zusammen gesetzt haben, einen Schlüssel bildeten. Für mich ergab das wenig Sinn und wurd nur schwerer im Programmcode zu handeln.

Wann macht das eigentlich Sinn bzw. reicht es nicht manchmal einfach ein Unique auf entsprechende Felder zu setzen?

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Wuk

Mir ist super-unklar, was du willst - vor allem fachlich?!?

Er will seine einzelnen Keys global in der Datenbank eindeutig haben.

Das kann je nach Anwendungsfall durchaus Sinn machen.

Ich arbeite z.B. mit einer O/R Zwischenschicht. Da alle persistenten Objekte von einer Basisklasse erben, habe ich nur dort eine id. Alle Tabellen der Unterobjekte haben zwar auch eine Primary Key Spalte, aber der Wert ist dann identisch mit dem entsprechenden Eintrag in der BaseObject Tabelle und somit global eindeutig.

Ich hoffe das ist einigermaßen verständlich.

Von Hand würde ich das ebenso machen. Du nimmst eine DummyTabelle mit einer auto_increment Spalte als Pseudo Sequenz mit dieser erzeugst du deine Keys und trägst die Datensätze damit in die anderen Tabellen ein.

Gruß Jaraz

Link zu diesem Kommentar
Auf anderen Seiten teilen

[...]Koordianten, die sich aus 3 Angaben - Feldern - zusammen gesetzt haben, einen Schlüssel bildeten. Für mich ergab das wenig Sinn und wurd nur schwerer im Programmcode zu handeln.[...]

Wann macht das eigentlich Sinn bzw. reicht es nicht manchmal einfach ein Unique auf entsprechende Felder zu setzen?

es ist aber durchaus sinnvol und logisch:

du hast meinetwegen ein koordinatensystem, das sich aus x (länge), y (breite) und z (meinetwegen seehöhe) zusammensetzt. dadurch, dass diese 3 gemeinsam einen primärschlüssel in der tabelle bilden, kann kein zweiter datensatz diese drei gemeinsamen werte annehmen - sprich, kein objekt kann denselben platz im dreidimensionalen raum einnehmen.

zum problem vom originialposter:

Ich möchte eine Tabelle erstellen (tabelleX) derren Fremdschlüssel eindeutig auf einen Eintrag in einer der anderen Tabellen verweist (tabelle1,tabelle2,..). Genauer gesagt, möchte ich mit Hilfe des Primärschlüssels in einer der Tabellen alle Einträge mit diesem Fremdschlüssel in TabelleX auslesen, was einfach ist. Das Anlegen der Einträge in den Tabellen(1,2,3,..) ist das Problem.

du suchst vielleicht ON DELETE, ON UPDATE und CASCADE. wird ein datensatz geändert, der am fremdschlüssel diese optionen eingestellt hat, so wird auch in der fremdschlüsseltabelle der datensatz gelöscht. bzw. aktualisiert. mysql und oracle zumindest können das.

s'Amstel

Link zu diesem Kommentar
Auf anderen Seiten teilen

1. Zusammengesetzte Primärschlüssel sind bäh. Sie sind zwar "möglich", ohne die Datenbankstruktur zu gefährden. Aber das bedeutet das mann alle zusammengesetzten Keyfelder auch in anderen Tabellen als FK's haben muss. Ein unsinniger Datenaufwand, meiner Meinung nach.

Des weiteren, ich traue den meisten zu das sie den unterschied im Programmieraufwand zwischen 1 Keyfeld und [n] Keyfeldern erkennen ^^

Ich habe tabellen wo "nur" Fremdschlüssel drinstehen, die kriegen trotzdem ein Auto-Increment von mir, Weil: 1. Eindeutigkeit, 2. Programmieraufwand.

und nun zurück zum Thema

soweit ich das verstehe soll der Schlüssel unabhängig von Tabellen sein. Das Bedeutet das nicht die Datenbank den Schlüssel bestimmt, sondern das Programm. Dabei kann der Schlüssel irgendwo gespeichert werden. Was aber auch geht ist ein Zusammengesetzter String der an sich eindeutig ist. Z.B. "UserID_Timestamp_Random"

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ahja, ich merke schon, die leichte unverstädnlichkeit kommt nicht nur aus meinen windungen...

ich versuche mal das grafisch darzustellen, wie ich es mir vorstelle.


tabelle1

[U]spalte1[/U] | spalte2 | ...

1 | asdf | ...

2 | asdg | ...


tabelle2

[u]spalte1[/u] | spalte2 | ...

3 | qwertz | ...

4 | grütze | ...


tabelle 3

[u]spalte1[/u] | spalte2 | ...

5 | ...

6 | ...

also so stell ich mir das vo, wie es später aussehen soll.

da du mysql verwendest geh ich davon aus, das du auch php verwendest.

somit machst du einfach ne funktion "auto_increment()" oder so.

Die Funktion ließt nun eine Datei ein. In der Datei befindet sich eine Zahl (zB 1)

diese Zahl wird nun um 1 erhöht (jetzt 2)

diese neue Zahl wird in die Datei geschrieben (die datei mit 1 wird nun überschrieben und hat nun 2)

die funktion gibt die zahl zurück, diese wird dann im SQL Statement als wert für den PK verwendet.

ich hoffe es ist verständlich, sonst einfach nochmal nachfragen

Link zu diesem Kommentar
Auf anderen Seiten teilen

es ist aber durchaus sinnvol und logisch:

du hast meinetwegen ein koordinatensystem, das sich aus x (länge), y (breite) und z (meinetwegen seehöhe) zusammensetzt. dadurch, dass diese 3 gemeinsam einen primärschlüssel in der tabelle bilden, kann kein zweiter datensatz diese drei gemeinsamen werte annehmen - sprich, kein objekt kann denselben platz im dreidimensionalen raum einnehmen.

Da denke ich auch an den Aufwand bei den Foreign Keys und auch noch an die Performance der Datenbank. Ich denke, dass 1 Primary Key und 3 Unique Felder weniger Aufwand bedeuten als ein Primary Key über n Felder. Auch wenn Koordinaten eindeutig sein sollen, kann man das auch auf anderem Weg erreichen.

du suchst vielleicht ON DELETE, ON UPDATE und CASCADE. wird ein datensatz geändert, der am fremdschlüssel diese optionen eingestellt hat, so wird auch in der fremdschlüsseltabelle der datensatz gelöscht. bzw. aktualisiert. mysql und oracle zumindest können das.

s'Amstel

Das ist so nicht ganz richtig was MySQL betrifft. Dort wird das nur mit dem Tabellentyp INNO DB untersützt und der ist leider meist auf Webspaces deaktiviert, weil er zuviel Speicher beansprucht. Ich würde das gerne einsetzen um die Integrität der Daten schon auf Datenbankebene zu gewärleisten aber die meisten Hoster sehen das leider anders ,-(

da du mysql verwendest geh ich davon aus, das du auch php verwendest.

somit machst du einfach ne funktion "auto_increment()" oder so.

Die Funktion ließt nun eine Datei ein. In der Datei befindet sich eine Zahl (zB 1)

diese Zahl wird nun um 1 erhöht (jetzt 2)

diese neue Zahl wird in die Datei geschrieben (die datei mit 1 wird nun überschrieben und hat nun 2)

die funktion gibt die zahl zurück, diese wird dann im SQL Statement als wert für den PK verwendet.

Wenn wirklich php verwendet wird, so ist beim einfügen neuer Datensätze wohl doch die Funktion mysql_insert_id() die beste Wahl. Verstehe nur nicht warum Du eine Datei anlegen willst um einfach $Foo++ zurechnen?

Er will seine einzelnen Keys global in der Datenbank eindeutig haben.

Das kann je nach Anwendungsfall durchaus Sinn machen.

Ich arbeite z.B. mit einer O/R Zwischenschicht. Da alle persistenten Objekte von einer Basisklasse erben, habe ich nur dort eine id. Alle Tabellen der Unterobjekte haben zwar auch eine Primary Key Spalte, aber der Wert ist dann identisch mit dem entsprechenden Eintrag in der BaseObject Tabelle und somit global eindeutig.

Ich hoffe das ist einigermaßen verständlich.

Von Hand würde ich das ebenso machen. Du nimmst eine DummyTabelle mit einer auto_increment Spalte als Pseudo Sequenz mit dieser erzeugst du deine Keys und trägst die Datensätze damit in die anderen Tabellen ein.

Wäre denn der Foreign Key in den Tochtereinträgen, die mit dem Vatereintrag in Beziehung stehen, nicht eindeutig genug oder willst Du immer alle Einträge auch wenn sie nicht in Beziehung sondern nur den gleichen Primary Key haben. Also wohl doch wieder eine Beziehung besteht. Irgendwie verwirrt mich das einwenig. Vieleicht kann der Threadstarter nocheinmal erläutern wieso er das machen möchte. Vieleicht ist da nur was am Datenbankdesign nicht so ideal.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mich wundert etwas das hier vorschläge gemacht werden eine ID in einem FILE zu verwalten... Wie soll man den dann gewährleiste, das die ID nur einmal vergeben wird? (OK kann man vielleicht, aber mit welcher Perfomance, vorallem wenn alle Tabellen darauf warten sollen)

Dafür hat man doch die Datenbank, da kann man das notfalls mit Sperren sicherstellen.

Genauso, als wenn man mit max(ID) raussucht, welches der höchste Wert ist, um dann den nächsten als ID zu nehmen.

Wer sowas macht hat noch nie ein System gesehen, wo mehrere Hundert/Tausend User gleichzeitig dran arbeiten. Dann kann es schnell mal vorkommen, das mit sowas die IDs doppelt sind....

Link zu diesem Kommentar
Auf anderen Seiten teilen

ich wiederhole: eine eindeutige Folge von Umgebungsvariablen

UserID

TimeStamp

Random-Zahl

der gleiche User, so schnell er auch ist, kann nicht zum gleichen Zeitpunkt mehrere Aktionen ausführen. Es sei denn dein Script fügt automatisch mehrere Datensätze ein, in dem fall währe noch ein Counter angebracht, der hochzählt.

Die Random-Zahl soll zusätzlich Eindeutigkeit liefern, falls er es doch schafft mehrere Dinge gleichzeitig anzustoßen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also erst einmal Danke für die rege Diskussion und Hilfestellung. :)

Ich denke ich werde die mehrteiligen Schlüssel versuchen. Also in TabelleX einmal den Fremdschlüssel zu dem Eintrag in einer der Tabellen(1-n) speichern und einen weiteren der auf die Tabelle selber weist. Dann kann ich alle Tabellen mit auto_increment versehen. Dürfte zwar ein bischen mehr Aufwand in php und ein paar mehr mySQL Aufrufe sein, aber das hört sich ganz gut an.

Da nach einem Beispiel gefragt wurde: Ich möchte aus Spaß an der Freude und der Übung halber eine Art Forum-Nachrichten-Dingsbums programmieren. Dazu gibt es eine Tabelle 'forum' mit den Thread Köpfen, eine Tabelle 'news' mit den Nachrichten, ein 'Geschichten' tabelle, und so weiter. Alle können replys (antworten/kommentare/..) haben was dann die erwähtne TabelleX wäre die alle diese enthält.

Die Frage ob man mehrere Tabellen so verbinden kann das jeder Eintrag, egal in welcher dieser Listen, eine eindeutige ID hat, und diese nur aus einer Spalte besteht, hat mich schon fasziniert. Deshalb mein Post.

Also Danke vielmals.

Link zu diesem Kommentar
Auf anderen Seiten teilen

nochmal ich und als hätte ich es geahnt geht es um ein forum :)

ich schätze dein lösungsansatz ist nicht der eleganteste. ich würde die responses in die gleiche tabelle packen und vielleicht eine spalte einfügen mit der zugehörigkeits_id ...

wieso?, fragst du. ganz klar, um ein unterforum zu löschen brauchst du dann nur ein drop auf die betroffene tabelle machen und fertig, ansonsten musst du alle querverweise prüfen.

bei der thread darstellung hast du ein weiteres problem, du musst, verbindung zu min. 2 tabellen herstellen und dann mit 2 handle´s arbeiten, das macht die sache nur komplizierter und du möchtest ja weniger quellcode

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also Du bräuchtest:

Eine Resourcentabelle mit der Art des Kommentars

Eine Tabelle mit den Kommenataren

Eine Tabelle mit den Themen

evtl. auch noch eine Tabelle mit den Benutzern

Resourcentabelle:

ID, Art

1, Forum

2, News

3, Gästebuch

Thementabelle:

ID, ID oder Name des Benutzers als Threadstarter, ID aus der Resourcentabelle, Thementitel, Datum

Kommentartabelle:

ID, ID des Themas, ID oder Name des Benutzers als Poster, Kommentar

Mit INNER JOINS kann man dann die jeweiligen Datensätze auslesen. Somit brauch man keine zwei Handles sondern nur eins für die jeweilige Sektion - Forum, News, etc.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mmh hört sich gut an. Aber die extra recourcen Tabelle kann ich mir ja dann sparen.

CREATE TABLE forum

( ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT,

titel VARCHAR(80) NOT NULL,

ersteller INT NOT NULL DEFAULT 0

)

CREATE TABLE news

( ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT,

titel VARCHAR(80) NOT NULL DEFAULT '',

inhalt LONGTEXT NOT NULL DEFAULT ''

)

CREATE TABLE reply

( rID INT NOT NULL DEFAULT 0,

typ ENUM('forum','news'),

inhalt LONGTEXT NOT NULL DEFAULT '',

poster INT NOT NULL DEFAULT 0

)

--

auslesen:

SELECT reply.inhalt,reply.poster,forum.titel FROM reply,forum WHERE reply.rID = forum.ID AND reply.typ='forum'

Naja so in etwa. Das nennt man dann 2 fremdschlüssel in einer Tabelle, oder sehe ich das falsch? Jedenfalls kommt es meiner ersten Idee recht nahe, mit dem Unterschied das der Fremdschlüssel (rID) in reply nur mit Hilfe von der zweiten Spalte (typ) eindeutig ist.

Gruß Wuk

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...