# HSQLDB 2xPK + AutoInc



## DaKu (13. Sep 2006)

Hallo.

Bezugnehmend auf dieses Thema aber mit neuen Schwierigkeiten  :bahnhof:  :bahnhof:  :bahnhof: 

und zwar habe ich es mit den 2 PK's hinbekommen

```
CREATE TABLE zutaten (namIndex INT NOT NULL,  zutIndex INT NOT NULL, ... , PRIMARY KEY (namIndex, zutIndex));
```

nun soll aber die "zutIndex" automatisch hochgezählt werden, was ja bei bei nur einem PK automatisch mit IDENTITY gemacht wird.

Weiss einer wie das geht?

Danke und gute Nacht erstmal  :wink:


----------



## DaKu (24. Sep 2006)

Für die, die das gleiche Problem haben, mit HSQLDB geht es nicht, habe da nach ewigen suchen und probieren aufgegeben.

MfG

DaKu


----------



## bronks (25. Sep 2006)

Ich habe dieses Thema auf beobachten gesetzt, wie es noch frisch war, um mögliche Antworten abzuwarten ...

Es könnte möglich sein, daß irgendeine andere DB das vielleicht machen kann, aber es ist so und so Unfug. Überhaupt wundert man sich wofür AutoInc immer zweckentfremdet wird ... ... . Im eBankTutorial von Sun steht, wie man es richtig macht.


----------



## DaKu (25. Sep 2006)

wofür ist denn AutoInc sonst gut, wenn nicht zum hochzählen, wenn es diese Option gibt, warum sollte man sie denn dann nicht nutzen?
Könntest du mal ein Link zu diesem Tutorial geben?

Danke


----------



## bronks (25. Sep 2006)

Den AutoInc sollte man nur als RowId verwenden, wenn man diese braucht. 

In dem Tut von Sun steht das nicht mehr so ausführlich beschrieben, wie ich in Erinnerung hatte. Hier ist ein nett beschriebenes Beispiel eines einfachen UID-Generators: http://www2.sys-con.com/ITSG/virtualcd/Java/archives/0512/Westra/index.html


----------



## DaKu (26. Sep 2006)

aber ich benötige es doch als RowID, warum zweckentfremde ich es Deiner meinung nach?
Hättest du eine bessere Idee?


----------



## bronks (26. Sep 2006)

DaKu hat gesagt.:
			
		

> aber ich benötige es doch als RowID, warum zweckentfremde ich es Deiner meinung nach?
> Hättest du eine bessere Idee?


Beschreibe bitte, was die Daten im PrimaryKey und des Datensatzes darstellen und was das Programm damit machen wird. Eine Lösung wird sich bestimmt finden.


----------



## DaKu (27. Sep 2006)

Also in der DB habe ich 2 Tabellen
1. Tabelle: InxN(PK), name, ...
2. Tabelle: InxN(FK), InxZ(PK), zutaten, masse, ...

in der 2. Tabelle sollen InxN der Femdschlüssel zum PK von Tabelle 1 sein.
und im Endeffekt haben wir eine 1:n Beziehung, weil zu einem Namen mehrere Zutaten gehören und deswegen habe ich jedem Namen und jeder Zutat eine Zahl zugeordnet, die sich bei Eingabe eines neuen Namens, bzw, einer neuen Zutat automat erhöhen soll, damit es keine Lücken gibt.
Deswegen InxN+InxZ soll Unique sein.
Ein weiteres ist, das in der 2. Tabelle bei Eingabe eines neuen Namens, InxZ nicht weiter gezählt werden, sondern wieder bei 0 angefangen werden soll. 
Hm, was macht das Programm damit, die Daten auslesen und ausgeben, oder neue hinzufügen.
und das alles über den Inx (Index) der 2 Tabellen.

Hoffe, ich habe es nicht zu wirr erklärt  :wink:


----------



## AlArenal (27. Sep 2006)

@DaKu:

Und was soll das?

Wie ein Key von der DB gezählt und inkrementiert wird sollte programmseitig in der Implementierung völlig egal sein. Und was deine Struktur angeht:
Sinnigerweise packt man Rezepte, Zutaten und 'Rohstoffe' in jeweils eine Tabelle, wobei Zutaten die Verknüpfung übernimmt (n:m und nicht 1:n). Die Zutat eines Rezepts ist nichts weiter als ein Rohstoff mit Mengenangabe und Verbindung zum Rezept.


----------



## hupfdule (27. Sep 2006)

> damit es keine Lücken gibt



Das ist bereits eine falsche Annahme. Mit einem Autoincrement _wird_ es Lücken geben, sobald du einen Eintrag löschst. Es ist auch nicht Sinn der Sache, Lücken zu vermeiden. Autoincrement benutzt man, um eindeutige Schlüssel zu haben, die man nicht selbst vergeben will. Lass deine Anforderung fallen, dass InxZ immer wieder bei 0 beginnen soll und es läuft fein. 
Wenn du willst, dass es immer bei 0 beginnt, und du Lücken beim Löschen von Einträgen vermeiden willst, musst du den Schlüssel selbst setzen.


----------



## DaKu (27. Sep 2006)

Also Lücken soll es bei der Erstellung eines neuen Datensatzes nicht geben, später ist es klar, das es welche geben wird.
Aber es bringt mir nichts, nicht bei 0 anzufangen und das AutoInc fortlaufen zu lassen.
Deswegen mache ich es ja jetzt auch manuell, bleibt mir ja nix anderes übrig, nur da haben sich auch schon Leute gefragt, was da j++ macht :wink: .
Funktioniert ja auch nur in HSQLDB nicht, in MySQL und Oracle müsste es funktionieren.


----------



## AlArenal (27. Sep 2006)

DaKu hat gesagt.:
			
		

> Aber es bringt mir nichts, nicht bei 0 anzufangen und das AutoInc fortlaufen zu lassen.



Warum?


----------



## DaKu (27. Sep 2006)

Da ich bei der Eingabe der Daten in die 2. Tabelle die InxZ als Zeilennummer in einem JTable nehme.


----------



## AlArenal (27. Sep 2006)

Dann sind es Nutzdaten und keine Verwaltungsinfos der DB und damit bist du dafür zuständig, dass sie richtig gesetzt sind und nicht die DB. Da würde ich auch nicht mit Hackentricks versuchen das der DB aufzubürden.

Und Zeilennummer in einer JTable.. also dafür brauch ich kein Feld in der DB. Die Zeilennummern in Eclipse stehen auch nicht im Quellcode.


----------



## DaKu (27. Sep 2006)

OK, nicht zur nummerierung, sondern zur Positionierung.
Wenn mir die DB jedoch so einen Dienst anbietet, kann man ihn doch auch verwenden, ohne sich weiter eine Platte zu machen, wie man es sonst hinbekommen, oder?
Wenn etwas da ist, sollte man es nutzen.
Da es hier aber nicht geht, musste ich es anders machen, was ich auch gemacht habe.


----------



## DaKu (27. Sep 2006)

AlArenal hat gesagt.:
			
		

> @DaKu:
> 
> Und was soll das?
> 
> ...



Verstehe ich jetzt nicht so ganz
das Rezept hat einen Namen, also 1. Tabelle mit Namen, Bild, Beschreibung, ... , halt alles was einzeln ist.
aber das Rezept hat mehrere Zutaten, also 2. Tabelle, wo die ganzen Zutaten reinkommen mit Masse, Einheit und Zutatenname

also meiner Meinung nach eine 1:n Beziehung

oder noch eine extra Tabelle erstellen, wo die Zutatennamen aufgezählt werden und dann mit der 2. Tabelle verknüpft werden?


----------



## hupfdule (27. Sep 2006)

DaKu hat gesagt.:
			
		

> OK, nicht zur nummerierung, sondern zur Positionierung.


Ist aber doch auch nicht nötig. Du hast eine Liste von Zutaten. Ob die nun nummeriert sind oder nicht, ist doch wurscht. Du brauchst sie doch nur der Reihe nach hinzufügen.



> Wenn mir die DB jedoch so einen Dienst anbietet, kann man ihn doch auch verwenden, ohne sich weiter eine Platte zu machen, wie man es sonst hinbekommen, oder?
> Wenn etwas da ist, sollte man es nutzen.


Nur, wenn du es auch so benutzt, wie es gedacht ist. Sonst wird es eher zu unschönen Seiteneffekten kommen (selbst, wenn es zuvor den Anschein macht, es würde funktionieren).


----------



## DaKu (27. Sep 2006)

hm, na gut, da werde ich mein Programm nochmal überdenken müssen.

Danke trotzdem erstmal.


----------



## AlArenal (27. Sep 2006)

DaKu hat gesagt.:
			
		

> Verstehe ich jetzt nicht so ganz
> das Rezept hat einen Namen, also 1. Tabelle mit Namen, Bild, Beschreibung, ... , halt alles was einzeln ist.
> aber das Rezept hat mehrere Zutaten, also 2. Tabelle, wo die ganzen Zutaten reinkommen mit Masse, Einheit und Zutatenname
> 
> ...




```
REZEPT:
ID | NAME
---------
1  | Mutterkuchen
2  | Hot Chick
...

ZUTAT:
ID | NAME
---------
1  | Mehl
2  | Ei
3  | Wasser
4  | Zucker
5  | Geile Schnecke
...

REZEPT_ZUTAT:
REZEPT_ID | ZUTAT_ID | Menge | Einheit
--------------------------------------
1         | 1        | 600   | Gramm
...
```

Alternativ kann man die Ienheit auch in Zutat unterbringen, aber Salz braucht man eben mal nur "ne Prise" und mal eine gewisse Gramm-Menge....


----------



## DaKu (27. Sep 2006)

das war meine 1. Überlegung, wo es um die Aufteilung der Tabellen ging, nur ist es doch zwecks abfragen optimaler, nur in einer Tabelle die sachen zusammenzusuchen, als eine abfrage über x Tabellen, deswegen habe ich den Zutatenname mit in die andere Tabelle genommen, weil Zeilen lassen sich damit nicht einsparen, oder?


----------



## AlArenal (27. Sep 2006)

In diesem Beispiel mag es zunächst nicht relevant erscheinen und womöglich auch nie sein, aber nimm mal den Fall, dass du irgendwann festetellen möchtest in wievielen Rezepten "Zucker" vorkommt. Was darfst du in der einen Tabelle erstmal nach allen Einträgen suchen, die das Wort "Zucker" im Titel enthalten und mit der Liste machst du dann ein SELECT .. WHERE .. IN ([zutatenliste]) - das ist mitnichten performanter als ein Join von drei Tabellen mit ordentlichen Indexen.

Ich sehe auch nicht ein, egal ob es um DB-Design oder OO-Design geht, wider besseren Wissens Kompromisse einzugehen und Hackentricks anzuwenden. Saubere Strukturen von Beginn an erleichtern einem immer das Leben.

Darum wird bei mir von Beginn an ordentlich indiziert und normalisiert. Alle weiteren Fragen kann man sich mit EXPLAIN und praktischer Erfahrung selbst beantworten / herleiten.


----------



## AlArenal (27. Sep 2006)

P.S.:

Manchmal ist auch bei der Enticklung der erste Gedanke der richtige


----------



## DaKu (27. Sep 2006)

AlArenal hat gesagt.:
			
		

> Darum wird bei mir von Beginn an ordentlich indiziert und normalisiert. Alle weiteren Fragen kann man sich mit EXPLAIN und praktischer Erfahrung selbst beantworten / herleiten.



  Die praktische Erfahrung versuche ich mit diesem Programm, welches übrigens mein 1. in Java ist zu machen.


----------

