SQL: 2x ID und auto_increment

Txxxxs

Grand Admiral Special
Mitglied seit
26.07.2004
Beiträge
2.421
Renomée
32
Hallo,

ich arbeite momentan im Rahmen einer Projektarbeit an einem kleinen Ticket-System, wobei es mehrere Projekte gibt und zu jedem wird ein solches System angeboten.
Zum Einsatz kommt MySQL.

Folgende Tabelle:
Code:
CREATE TABLE tickets (
  	TicketID 	INT UNSIGNED NOT NULL AUTO_INCREMENT,
  	ProjectID 	INT UNSIGNED NOT NULL,
  	...
  	PRIMARY KEY (TicketID, ProjectID) ,
  	FOREIGN KEY (ProjectID) REFERENCES projects (ProjectId),    
  	...
);

Das Ticket-System wurde bisher so implementiert, dass die TicketID projektübergreifend gezählt wird, d. h., legt ein Nutzer im Projekt A ein neues Ticket an, bekommt dieses z. B. die ID 1, wird dann im Projekt B ein neues Ticket erstellt, erhält dieses die ID 2. Meiner Meinung nach sollte die Zählung aber pro Projekt stattfinden, sodass es vielleicht so aussieht:
(TicketID, ProjectID)
(1, 1)
(2, 1)
(1, 2)
(2, 2)
(3, 2)

Beim Erstellen eines Tickets wird die ProjectID mit eingetragen, die TicketID bisher nicht explizit, weil sie ja für jeden neuen Datensatz automatisch von der Datenbank erstellt wird. Wenn man das Ganze im Quelltext (PHP wird verwendet) manuell bearbeiten würde, also die ID extra setzen, auslesen, inkrementieren, jeweils passend zur ProjectID, ist das sicherlich kein Problem. Gibt es aber eine Möglichkeit, sowas über SQL zu bestimmen? Also dass die Datenbank vielleicht erkennt, es wird ein Ticket zum Projekt mit der ID 1 abgespeichert und die TicketID in diesem Zusammenhang per auto_increment erhöht bzw. automatisch setzt, und bei weiteren neuen Tickets zum gleichen Projekt analog?
 
Zuletzt bearbeitet:
Hi
Solche ein Funktion kenne ich weder bei MS (SQL Server/Access) noch bei Oracle.
Machs manuell

hand

Kali
 
Ja, ich habe auf einer anderen Seiten auch gefragt und dort wurde mir ebenfalls geschrieben, dass es so eine Funktion offenbar nicht gibt.
Dort wurde mir sogar empfohlen, statt jedes Mal alle Datensätze pro ProjectID abzufragen, zu zählen, oder mit irgendwelchen Funktionen (max(), usw.) an die jeweilige TicketID zu kommen, einfach ein Feld NextTicketID in die Tabelle projects einzufügen, das dann die jeweils neue TicketID passend zum Projekt hält. Allerdings sollte man wohl in allen diesen Fällen/Möglichkeiten sämtliche Aktionen in einem SQL-Statement durchführen, damit die Aktion atomar ist. Und das geht in meinem Fall nicht - ich nutze ein (PHP-)Framework, das für Datenbankaktionen Funktionen vorgibt, und diese kann man (bisher) nicht verschachteln.
Durch Zufall kam ich dann auf Trigger, habe viele Stunden herumprobiert, aber auch das wollte nicht so recht funktionieren, obwohl der Trigger ansich korrekt gewesen sein sollte (vielleicht hing auch das wiederum mit dem Framework zusammen).

Letztendlich habe ich mich entschieden, die TicketID wie bisher zu zählen, also global. Ich denke, das ist der schnellste und einfachste Weg, außerdem kann mir dann die Datenbank die TicketID automatisch anlegen. :)
 
"atomar"? ... hört sich gefährlich an ;-)
Denn Ausdruck habe ich noch nie gehört.

Beherrscht das Framework Transaktionen?
 
http://de.wikipedia.org/wiki/Atomar#Informatik

Wenn man das Ganze nicht in einem SQL-Statement durchführt, sondern z. B. das Auslesen/Bestimmen der TicketID extra macht, und im gleichen Moment ein anderer Nutzer ein Ticket anlegt, kann es wohl passieren, dass es zu einem Konflikt kommt, weil vielleicht beide die gleiche ID erhalten und man am Ende zwei Tickets mit genau dem gleichen Primärschlüssel hätte, was ja dann nicht mehr eindeutig ist. Und damit die Berechnung der nächsten TicketID im gleichen Zug wie das Eintragen des neuen Tickets geschieht, sollten alle diese Aktionen in einem SQL-Statement stattfinden, dann wäre es auch atomar. :)

Ja, das Framework bietet die Funktionen MakeDelete(), MakeUpdate(), MakeInsert() und MakeSelect(), jedoch lassen sie sich leider nicht verschachteln bzw. lassen sich damit, soweit ich gesehen habe, keine komplexeren Statements realisieren.
Aber gut, da ich die TicketID jetzt eh weiterhin global zählen lasse und es sich nur um eine Projektarbeit fürs Studium handelt, werde und will ich da nicht noch mehr Zeit reinstecken. ;)
 
genau dem gleichen Primärschlüssel hätte

Lässt die DB ja nicht zu, deswegen ja PKs ;)

Wenn Du die Tabelle vorher lock'st, dann mit max()+1 die nächste TicketID ermittelst, den Datensatz schreibst, dann sollte Multiuserzugriff auch bei hohem aufkommen klappen.
Ein gewisser Timeout ist ja vorhanden, das der (eine nanosekunde spätere) 2. DB Zugriff nicht sofort auf die Bretter geht.

Wieviele Anwender werden auf die DB zugreifen (in Spitzenzeiten)?
 
Wieviele Anwender werden auf die DB zugreifen (in Spitzenzeiten)?
Das weiß ich ehrlich gesagt gar nicht. Das Ticketsystem ist Teil eines Systems von Studenten für Studenten, damit können bzw. sollen später (studentische) Projekte verwaltet werden. Und da die Hochschule, an der ich momentan noch bin, nicht allzu groß ist, denke ich, werden selten mehr als vielleicht 50 Leute gleichzeitig das System benutzen.
 
bei 50 User gleichzeitig auf dem System würde ich mir keine Sorgen machen.
Es besteht nur die theoretische Gefahr.

Kali
 
Zurück
Oben Unten