Primärschlüssel aus zwei Spalten

Primärschlüssel aus zwei Spalten

am 18.11.2007 15:23:20 von steffen horst

Guten Tag,

ich habe eine Tabelle, welche Daten verschiedener Benutzergruppen
speichert. Alle Daten, die in die Tabellen eingetragen werden, lassen
sich immer eindeutig einer Benutzergruppe zuordnen.

Definition:

CREATE TABLE `data` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`group_id` mediumint(8) unsigned NOT NULL,
...
PRIMARY KEY (`id`)
)

Bei jedem Zugriff auf die Tabelle kommt im WHERE die group_id vor, da
alle Daten nur von den jeweiligen Gruppen gelesen werden dürfen, also
sowohl beim INSERT wie auch beim Löschen:

DELETE FROM `data`
WHERE `group_id` = ...
AND `id` = ...

Die Datensätze werden den Nutzern angezeigt. Nun ist es so, dass die
id auch mit angezeigt wird (und auch angezeigt werden soll), aber
diese alles andere als halbwegs durchgängig ist und auch ziemlich
schnell recht groß wird, z.B.

id group_id data
1 1 ...
2 1 ...
3 2 ...
4 3 ...
5 1 ...

Das stört ein bisschen. Eine Möglichkeit ist es also, den
Primärschlüssel aus id und group_id zu erzeugen. Das Beispiel sähe
dann so aus:

id group_id data
1 1 ...
2 1 ...
1 2 ...
1 3 ...
3 1 ...

Gibt es etwas dabei zu beachten, wenn ich den Primärschlüssel aus
group_id und id zusammensetze und wie funktioniert das dann mit
AUTO_INCREMENT? Hat das irgendwelche Nachteile?

Danke sehr, schöne Grüße, steffen

Re: Primärschlüssel aus zwei Spalten

am 18.11.2007 16:11:31 von petsch

On 18 Nov., 15:23, steffen horst wrote:
>
> id group_id data
> 1 1 ...
> 2 1 ...
> 1 2 ...
> 1 3 ...
> 3 1 ...
>
> Gibt es etwas dabei zu beachten, wenn ich den Primärschlüssel aus
> group_id und id zusammensetze und wie funktioniert das dann mit
> AUTO_INCREMENT?

Wenn Du beim INSERT einen Wert für id vorgibst, wird dieser (bei
deiner Tabel-Def) genommen und der Datensatz eingefügt - sofern der
zwei-spaltige Primary nicht doppelt ist.

Wenn Du id *nicht* angibtst, wird der nächste freie AUTO_INCREMENT-
Wert für id genommen. Dann ist der Primary auf keinen Fall doppelt.

Bitte erlaube die Frage, was das soll:

- Entweder Du weißt welchen Wert Du in id einfügen willst;
dann brauchst Du Auto-Inc nicht.

- Oder Du weißt es nicht und läßt Auto-Inc die Arbeit machen;
dann ist der doppelte Primary sinnlos, weil schon id allein
eindeutig ist.

Peter

Re: Primärschlüssel aus zwei Spalten

am 18.11.2007 17:56:52 von steffen horst

Peter Schleif wrote:
>On 18 Nov., 15:23, steffen horst wrote:
>Wenn Du id *nicht* angibtst, wird der nächste freie AUTO_INCREMENT-
>Wert für id genommen. Dann ist der Primary auf keinen Fall doppelt.
>
>Bitte erlaube die Frage, was das soll:
>
> - Entweder Du weißt welchen Wert Du in id einfügen willst;
> dann brauchst Du Auto-Inc nicht.
>
> - Oder Du weißt es nicht und läßt Auto-Inc die Arbeit machen;
> dann ist der doppelte Primary sinnlos, weil schon id allein
>eindeutig ist.

Eben darum geht es ja, allerdings drehst Du die Motivation um. Der
zusammengesetzte Primärschlüssel ist nicht sinnlos, weil ich damit
(aus Sicht des Nutzers) verständliche IDs erhalte. Solange keine
Position gelöscht wird, steigen sie eben kontinuierlich abhänging von
der group_id. Es geht nicht darum, dass die IDs zwecks irgendeiner
Nummerierung oder Ordnung kontinuierlich sein sollen. Doch wenn der
Nutzer Datensatz-IDs wie (1,2,3,4,6,7,8) statt (1,15,16,134,210) zu
sehen bekommt, kann er mit den IDs mehr anfangen. Deshalb sollen die
IDs abhängig von der group_id hochgezählt werden. Also statt

id group_id data
--------========------------
1 1 ...
2 1 ...
3 1 ...
4 1 ...
5 2 ...
6 2 ...
7 3 ...
....

möchte ich

id group_id data
--------========------------
1 1 ...
2 1 ...
3 1 ...
4 1 ...
1 2 ...
2 2 ...
3 3 ...
....

Den einzufügenden Wert von id kenne ich also nicht, wohl aber die
Datenbank. Es ist das Ergebnis von SELECT MAX(id)+1 FROM data WHERE
group_id = n oder eben SELECT COUNT(id)+1 FROM data WHERE group_id =
n.

Also nochmal die Fragen dazu: Gibt es etwas dabei zu beachten, wenn
ich den Primärschlüssel aus group_id und id zusammensetze und wie
funktioniert das dann mit AUTO_INCREMENT? Hat das irgendwelche
Nachteile?

schöne grüße, steffen

Re: Primärschlüsselaus zwei Spalten

am 18.11.2007 18:36:25 von Harald Fuchs

In article <7jo0k3hr8ir4gbhmjf5963rdtqrccvar4v@4ax.com>,
steffen horst writes:

> Also nochmal die Fragen dazu: Gibt es etwas dabei zu beachten, wenn
> ich den Primärschlüssel aus group_id und id zusammensetze und wie
> funktioniert das dann mit AUTO_INCREMENT? Hat das irgendwelche
> Nachteile?

Ein kurzer Blick ins Handbuch, Kapitel "3.6.9 Using `AUTO_INCREMENT'",
hätte Dir folgendes gesagt:

For `MyISAM' and `BDB' tables you can specify `AUTO_INCREMENT' on a
secondary column in a multiple-column index. In this case, the generated
value for the `AUTO_INCREMENT' column is calculated as
`MAX(AUTO_INCREMENT_COLUMN) + 1 WHERE prefix=GIVEN-PREFIX'.

Dieser Hack funktioniert also nur bei bestimmten Tabellentypen.

> Eben darum geht es ja, allerdings drehst Du die Motivation um. Der
> zusammengesetzte Primärschlüssel ist nicht sinnlos, weil ich damit
> (aus Sicht des Nutzers) verständliche IDs erhalte. Solange keine
> Position gelöscht wird, steigen sie eben kontinuierlich abhänging von
> der group_id. Es geht nicht darum, dass die IDs zwecks irgendeiner
> Nummerierung oder Ordnung kontinuierlich sein sollen. Doch wenn der
> Nutzer Datensatz-IDs wie (1,2,3,4,6,7,8) statt (1,15,16,134,210) zu
> sehen bekommt, kann er mit den IDs mehr anfangen.

Dann mußt Du ziemlich seltsame "Nutzer" haben, für die "2" irgendwie
mehr bedeutet als "15".

Re: Primaerschluessel aus zwei Spalten

am 19.11.2007 00:01:07 von Axel Schwenke

steffen horst wrote:

> CREATE TABLE `data` (
> `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
> `group_id` mediumint(8) unsigned NOT NULL,
> ...
> PRIMARY KEY (`id`)
> )
>
> Bei jedem Zugriff auf die Tabelle kommt im WHERE die group_id vor, da
> alle Daten nur von den jeweiligen Gruppen gelesen werden dürfen, also
> sowohl beim INSERT wie auch beim Löschen:
>
> DELETE FROM `data`
> WHERE `group_id` = ...
> AND `id` = ...
>
> Die Datensätze werden den Nutzern angezeigt. Nun ist es so, dass die
> id auch mit angezeigt wird (und auch angezeigt werden soll), aber
> diese alles andere als halbwegs durchgängig ist und auch ziemlich
> schnell recht groß wird

....

> Das stört ein bisschen.

Wieso stört das? Und wieso wird die ID angezeigt? Idealerweise ist
das ein strikt internes Feld, das den Nutzer gar nicht interessiert.

> Eine Möglichkeit ist es also, den
> Primärschlüssel aus id und group_id zu erzeugen. Das Beispiel sähe
> dann so aus:
>
> id group_id data
> 1 1 ...
> 2 1 ...
> 1 2 ...
> 1 3 ...
> 3 1 ...
>
> Gibt es etwas dabei zu beachten, wenn ich den Primärschlüssel aus
> group_id und id zusammensetze und wie funktioniert das dann mit
> AUTO_INCREMENT?

Das funktioniert so, wie es im Handbuch steht:
http://dev.mysql.com/doc/refman/5.0/en/example-auto-incremen t.html

> Hat das irgendwelche Nachteile?

Es hat keinen (für mich erkennbaren) Vorteil. Es könnte Nachteile
haben, wenn das eine InnoDB-Tabelle ist - aber da funktioniert
AUTO_INCREMENT für composite PKs ohnehin nicht.


XL

Re: Primaerschluessel aus zwei Spalten

am 19.11.2007 13:05:19 von steffen horst

Axel Schwenke wrote:
>steffen horst wrote:
>> Die Datensätze werden den Nutzern angezeigt. Nun ist es so, dass die
>> id auch mit angezeigt wird (und auch angezeigt werden soll), aber
>> diese alles andere als halbwegs durchgängig ist und auch ziemlich
>> schnell recht groß wird
>> Das stört ein bisschen.
>Wieso stört das? Und wieso wird die ID angezeigt? Idealerweise ist
>das ein strikt internes Feld, das den Nutzer gar nicht interessiert.

Statt die ID anzuzeigen, könnte ich alternativ das, wie Du sagst,
strikt interne Feld verstecken und die angezeigten Datensätze selbst
durchnummerieren. Dann ergäben sich jedoch für dieselben Datensätze
ständig unterschiedliche Nummern (z.B. wenn gelöscht / gefiltert
wird). Das ist irreführend und vor allem nicht nutzerfreundlich. Ein
Nutzer muss die Datensätze eindeutig benennen können. Diese Funktion
wird konsistent und nachvollziehbar durch die IDs aus der Datenbank
erfüllt.

>> Hat das irgendwelche Nachteile?
>Es hat keinen (für mich erkennbaren) Vorteil. Es könnte Nachteile
>haben, wenn das eine InnoDB-Tabelle ist - aber da funktioniert
>AUTO_INCREMENT für composite PKs ohnehin nicht.

Tabellen mit Fremdschlüssel müssen diesen um die zweite Spalte
erweitern. Das ist leider im Gegenzug etwas unschön (die
Assoziationstabelle hat dann drei Spalten), aber ein wohl akzeptabler
Kompromiss.

Schöne Grüße, Steffen

Re: Primärschlüssel aus zwei Spalten

am 19.11.2007 13:15:00 von steffen horst

Harald Fuchs wrote:
>steffen horst writes:
>> Also nochmal die Fragen dazu: Gibt es etwas dabei zu beachten, wenn
>> ich den Primärschlüssel aus group_id und id zusammensetze und wie
>> funktioniert das dann mit AUTO_INCREMENT? Hat das irgendwelche
>> Nachteile?
>[...]
>Dieser Hack funktioniert also nur bei bestimmten Tabellentypen.

Wenn Du Hack schreibst, nehme ich an, Du würdest es niemals benutzen?
Wie würdest Du dann diese Anforderung umsetzen?

>> Eben darum geht es ja, allerdings drehst Du die Motivation um. Der
>> zusammengesetzte Primärschlüssel ist nicht sinnlos, weil ich damit
>> (aus Sicht des Nutzers) verständliche IDs erhalte. Solange keine
>> Position gelöscht wird, steigen sie eben kontinuierlich abhänging von
>> der group_id. Es geht nicht darum, dass die IDs zwecks irgendeiner
>> Nummerierung oder Ordnung kontinuierlich sein sollen. Doch wenn der
>> Nutzer Datensatz-IDs wie (1,2,3,4,6,7,8) statt (1,15,16,134,210) zu
>> sehen bekommt, kann er mit den IDs mehr anfangen.
>Dann mußt Du ziemlich seltsame "Nutzer" haben, für die "2" irgendwie
>mehr bedeutet als "15".

Es ist ja nicht die 15, die einem nicht unmittelbar klar wird, sondern
der Kontext der 15. Es kann durchaus auch vorkommen, dass nach einem
Datensatz anhand einer ID gesucht wird. Du wirst kaum betreiten
wollen, dass ein Datensatz in einer nahezu durchgängigen Liste von IDs
weitaus schneller gefunden wird, als wenn ungleichmäßig große Lücken
zwischen den IDs auftauchen.

Schöne Grüße, Steffen

Re: Primaerschluessel aus zwei Spalten

am 19.11.2007 13:22:17 von Christian Kirsch

steffen horst schrieb:
> Axel Schwenke wrote:
>> steffen horst wrote:
>>> Die Datensätze werden den Nutzern angezeigt. Nun ist es so, dass die
>>> id auch mit angezeigt wird (und auch angezeigt werden soll), aber
>>> diese alles andere als halbwegs durchgängig ist und auch ziemlich
>>> schnell recht groß wird
>>> Das stört ein bisschen.
>> Wieso stört das? Und wieso wird die ID angezeigt? Idealerweise ist
>> das ein strikt internes Feld, das den Nutzer gar nicht interessiert.
>
> Statt die ID anzuzeigen, könnte ich alternativ das, wie Du sagst,
> strikt interne Feld verstecken und die angezeigten Datensätze selbst
> durchnummerieren. Dann ergäben sich jedoch für dieselben Datensätze
> ständig unterschiedliche Nummern (z.B. wenn gelöscht / gefiltert
> wird). Das ist irreführend und vor allem nicht nutzerfreundlich. Ein
> Nutzer muss die Datensätze eindeutig benennen können.

Anhand von Zahlen? Meinst Du da menschliche oder maschinelle Benutzer?
Ich kann mir praktisch keine Anwender vorstellen, die Zahlen als
Identifikationsmerkmal "nutzerfreundlich" finden. Was spricht dagegen,
Gruppen- und/oder Benutzernamen anzuzeigen?

> Diese Funktion
> wird konsistent und nachvollziehbar durch die IDs aus der Datenbank
> erfüllt.
>

wohlweislich fehlen da "intuitiv", "mnemonisch" etc.

Re: Primaerschluessel aus zwei Spalten

am 19.11.2007 14:02:14 von Axel Schwenke

steffen horst wrote:
> Axel Schwenke wrote:
>>steffen horst wrote:
>>> Die Datensätze werden den Nutzern angezeigt. Nun ist es so, dass die
>>> id auch mit angezeigt wird (und auch angezeigt werden soll), aber
>>> diese alles andere als halbwegs durchgängig ist und auch ziemlich
>>> schnell recht groß wird
>>> Das stört ein bisschen.
>>Wieso stört das? Und wieso wird die ID angezeigt? Idealerweise ist
>>das ein strikt internes Feld, das den Nutzer gar nicht interessiert.
>
> Statt die ID anzuzeigen, könnte ich alternativ das, wie Du sagst,
> strikt interne Feld verstecken und die angezeigten Datensätze selbst
> durchnummerieren.

Wenn dein UI nicht ohnehin für jeden Datensatz eine Checkbox vorsieht
und einen Button [Ausgewählte Datensätze] ...
dann könnte das tatsächlich eine sinnvolle Lösung sein. Zumindest haben
vor der Verbreitung von GUIs Programme so funktioniert, daß sie eine
numerierte Liste an Wahlmöglichkeiten anzeigten und dann fragten was es
denn sein darf.

Auf jeden Fall indentifizieren *Nutzer* Datensätzer wohl selten anhand
einer generierten ID sondern eher anhand des sonstigen Inhalts: "alle
Rechnungen von Firma X vom letzten Monat".

> Dann ergäben sich jedoch für dieselben Datensätze
> ständig unterschiedliche Nummern (z.B. wenn gelöscht / gefiltert
> wird). Das ist irreführend und vor allem nicht nutzerfreundlich. Ein
> Nutzer muss die Datensätze eindeutig benennen können.

Typischerweise hat man dazu einen Filter-Dialog, den der Nutzer aus-
füllt. Dann zeigt man die Trefferliste an und läßt den Nutzer auswählen.

> Diese Funktion
> wird konsistent und nachvollziehbar durch die IDs aus der Datenbank
> erfüllt.

Keine Frage. Deine Applikation sollte auch diese IDs verwenden.
Nur muß man das nicht dem Nutzer zeigen.

>>Es hat keinen (für mich erkennbaren) Vorteil. Es könnte Nachteile
>>haben, wenn das eine InnoDB-Tabelle ist - aber da funktioniert
>>AUTO_INCREMENT für composite PKs ohnehin nicht.
>
> Tabellen mit Fremdschlüssel müssen diesen um die zweite Spalte
> erweitern. Das ist leider im Gegenzug etwas unschön (die
> Assoziationstabelle hat dann drei Spalten), aber ein wohl akzeptabler
> Kompromiss.

Nicht für mich. Ein PK ist idealerweise numerisch und hängt nicht von
externen Daten ab. Man *kann* von dieser Regel abweichen, wenn es gute
Gründe gibt. Du hast keinen genannt.


XL

Re: Primärschlüssel aus zwei Spalten

am 19.11.2007 14:11:45 von Christian Kirsch

steffen horst schrieb:
>
> Es ist ja nicht die 15, die einem nicht unmittelbar klar wird, sondern
> der Kontext der 15. Es kann durchaus auch vorkommen, dass nach einem
> Datensatz anhand einer ID gesucht wird. Du wirst kaum betreiten
> wollen, dass ein Datensatz in einer nahezu durchgängigen Liste von IDs
> weitaus schneller gefunden wird, als wenn ungleichmäßig große Lücken
> zwischen den IDs auftauchen.
>

Ach, die Segnungen des Passiv. "Es wird gesucht" und "es wird gefunden"
.... Wenn dieses Es (was ich naheliegend finde) eine Maschine ist, dann
findet die doch alles gleichschnell (hoffe ich, sonst muss ich mich von
allen Datensätzen mit der ID 15 eben trennen). Wenn es sich um einen
Menschen handelt, frage ich mich, wieso man ihn überhaupt mit sowas
unmenschlichem wie Zahlen (und der Frage, ob zwischen denen Lücken
liegen) behelligen möchte.

Re: Primaerschluessel aus zwei Spalten

am 19.11.2007 15:06:50 von Axel Schwenke

steffen horst wrote:

> Es kann durchaus auch vorkommen, dass nach einem
> Datensatz anhand einer ID gesucht wird. Du wirst kaum betreiten
> wollen, dass ein Datensatz in einer nahezu durchgängigen Liste von IDs
> weitaus schneller gefunden wird, als wenn ungleichmäßig große Lücken
> zwischen den IDs auftauchen.

Das bestreite ich allerdings. Wenn das Feld indiziert ist
dann hängt der Aufwand zum Finden einer ID ausschließlich
von der Anzahl der Datensätze ab.


XL

Re: Primaerschluessel aus zwei Spalten

am 19.11.2007 15:26:29 von steffen horst

Christian Kirsch wrote:
>steffen horst schrieb:
>> Axel Schwenke wrote:
>>> steffen horst wrote:
>>>> Die Datensätze werden den Nutzern angezeigt. Nun ist es so, dass die
>>>> id auch mit angezeigt wird (und auch angezeigt werden soll), aber
>>>> diese alles andere als halbwegs durchgängig ist und auch ziemlich
>>>> schnell recht groß wird
>>>> Das stört ein bisschen.
>>> Wieso stört das? Und wieso wird die ID angezeigt? Idealerweise ist
>>> das ein strikt internes Feld, das den Nutzer gar nicht interessiert.
>> Statt die ID anzuzeigen, könnte ich alternativ das, wie Du sagst,
>> strikt interne Feld verstecken und die angezeigten Datensätze selbst
>> durchnummerieren. Dann ergäben sich jedoch für dieselben Datensätze
>> ständig unterschiedliche Nummern (z.B. wenn gelöscht / gefiltert
>> wird). Das ist irreführend und vor allem nicht nutzerfreundlich. Ein
>> Nutzer muss die Datensätze eindeutig benennen können.
>Anhand von Zahlen? Meinst Du da menschliche oder maschinelle Benutzer?
>Ich kann mir praktisch keine Anwender vorstellen, die Zahlen als
>Identifikationsmerkmal "nutzerfreundlich" finden. Was spricht dagegen,
>Gruppen- und/oder Benutzernamen anzuzeigen?

Die Datensätze enthalten Gruppen- und Benutzernamen, aber gleiche /
ähnliche Datensätze können häufiger oder auch regelmäßig auftauchen.
Es kann sein, dass Mitglieder von Benutzergruppen über bestimmte
Datensätze sprechen. Dazu ist dann eine eindeutige Nummer das beste
Identifizierungsmerkmal.

Aber ich muss gestehen, ich kann mir auch vorstellen, dass es nur
wenigen so geht und dass andere beispielsweise das Datum und die
Uhrzeit zur Identifizierung bevorzugen würden. Mir persönlich wäre der
Zeitpunkt einfach zu aufwändig. Leichter ist einfach "Schau mal,
Datensatz #313, da ist ein Fehler!" Und diesen zu suchen ist bei einer
einigermaßen lückenfreien Nummerierung einfacher, als bei Datumswerten
- welche ja keine konstanten Abstände haben. Ich mache mir dazu
nochmal Gedanken.

Schöne Grüße, Steffen

Re: Primärschlüssel aus zwei Spalten

am 19.11.2007 17:15:22 von steffen horst

Christian Kirsch wrote:
>steffen horst schrieb:
>> Es ist ja nicht die 15, die einem nicht unmittelbar klar wird, sondern
>> der Kontext der 15. Es kann durchaus auch vorkommen, dass nach einem
>> Datensatz anhand einer ID gesucht wird. Du wirst kaum betreiten
>> wollen, dass ein Datensatz in einer nahezu durchgängigen Liste von IDs
>> weitaus schneller gefunden wird, als wenn ungleichmäßig große Lücken
>> zwischen den IDs auftauchen.
>Ach, die Segnungen des Passiv. "Es wird gesucht" und "es wird gefunden"
>... Wenn dieses Es (was ich naheliegend finde) eine Maschine ist, dann
>findet die doch alles gleichschnell (hoffe ich, sonst muss ich mich von
>allen Datensätzen mit der ID 15 eben trennen).

Ich sehe, dass Dir die Passivsätze schwer fallen, denn Du hast
offensichtlich meinen Standpunkt nicht verstanden. Du kannst
meinetwegen sinnfrei schreiben: "...hoffe ich, sonst muss ich
sicherstellen, dass die IDs meiner Datensätze nicht ungleichmäßig
große Lücken enthalten."

>Wenn es sich um einen
>Menschen handelt, frage ich mich, wieso man ihn überhaupt mit sowas
>unmenschlichem wie Zahlen (und der Frage, ob zwischen denen Lücken
>liegen) behelligen möchte.

Gut, wenn ich also annehmen kann, dass Deine Webseiten ohne Zahlen
auskommen (Du möchtest den Nutzer ja nicht mit Zahlen behelligen),
kann ich Dir keine Argumente mehr entgegenbringen. Ich halte Zahlen
btw. weder für unmenschlich noch für unzweckmäßig.

Welches Datum ist heute?

schöne grüße, steffen

Re: Primärschlüssel aus zwei Spalten

am 19.11.2007 17:24:57 von Christian Kirsch

steffen horst schrieb:

> Gut, wenn ich also annehmen kann, dass Deine Webseiten ohne Zahlen
> auskommen (Du möchtest den Nutzer ja nicht mit Zahlen behelligen),

Du kannst annehmen, dass ich die mit meinen Anwendungen arbeitenden
nicht mit internen Merkmalen wie IDs behellige - ja. Ob jemand die Nr.
998 oder 989 hat, lässt sich nämlich wesentlich schlechter zuverlässig
verarbeiten (für ein normales Hirn) als die Information, dass der erste
Müller und der zweite Schulze heißt.

Es geht hier *nur* um die Repräsentation für den Benutzer, nicht darum,
was innen drin passiert.

> kann ich Dir keine Argumente mehr entgegenbringen. Ich halte Zahlen
> btw. weder für unmenschlich noch für unzweckmäßig.
>
> Welches Datum ist heute?

Hm. Den Unterschied zwischen "Zahlen" und "Datum" kennst Du aber schon,
oder?

Re: Primaerschluessel aus zwei Spalten

am 19.11.2007 17:32:48 von Christian Kirsch

steffen horst schrieb:

> Aber ich muss gestehen, ich kann mir auch vorstellen, dass es nur
> wenigen so geht und dass andere beispielsweise das Datum und die
> Uhrzeit zur Identifizierung bevorzugen würden. Mir persönlich wäre der
> Zeitpunkt einfach zu aufwändig. Leichter ist einfach "Schau mal,
> Datensatz #313, da ist ein Fehler!" Und diesen zu suchen ist bei einer
> einigermaßen lückenfreien Nummerierung einfacher, als bei Datumswerten
> - welche ja keine konstanten Abstände haben. Ich mache mir dazu
> nochmal Gedanken.

Wenn Du etwas präziser formulieren würdest, wäre die Unterhaltung
leichter. Man weiß nie so recht, ob Du von einem Rechner oder von
Menschen redest, wenn Du z.B. von "suchen" sprichst.

Aus dem Zusammenhang vermute ich mal, es geht Dir hier um Menschen, die
vor einer Liste mit Datensätzen sitzen. Einer von ihnen (Menschen) sieht
einen Fehler in einem Datensatz, findet dessen Nummer heraus und gibt
diese Nummer an jemand anders weiter (offenbar nicht per IT, sondern
akustisch?). Dieser zweite Mensch nun will denselben Datensatz in
(derselben?) Liste lokalisieren.

Um sich zu vergewissern, dass da wirklich ein Fehler drin steckt? Warum
schickt ihm der erste Mensch nicht einfach einen Link auf eine Website,
die genau *diesen* Datensatz öffnet? Weil in dieser Umgebung lieber
Nummern durch die Gegend gerufen werden? So ein Verfahren ließe sich
jedenfalls simpel implementieren, ohne dass *irgendjemand* eine Nummer
überhaupt nur sehen müsste.

Abgesehen davon bezweifle ich, dass Lücken in der Nummerierung einen
großen Einfluß auf die Suchgeschwindigkeit haben. Üblicherweise werden
Leute mit Intervallschachtelung suchen. Namen in Telefonbüchern sind ja
auch durchaus lückenhaft, und trotzdem findet man dadrin alles schnell
genug. Nicht mal bei linearer Suche ist eine Lücke relevant, denke ich.

Re: Primaerschluessel aus zwei Spalten

am 19.11.2007 17:40:11 von steffen horst

Axel Schwenke wrote:
>steffen horst wrote:
>> Statt die ID anzuzeigen, könnte ich alternativ das, wie Du sagst,
>> strikt interne Feld verstecken und die angezeigten Datensätze selbst
>> durchnummerieren.
>Wenn dein UI nicht ohnehin für jeden Datensatz eine Checkbox vorsieht
>und einen Button [Ausgewählte Datensätze] ...

Mit ausgewählten Datensätzen gäbe es nichts zu tun, deshalb würde eine
Checkbox am Anfang jeder Zeile den Benutzer unnötig verwirren.


>dann könnte das tatsächlich eine sinnvolle Lösung sein. Zumindest haben
>vor der Verbreitung von GUIs Programme so funktioniert, daß sie eine
>numerierte Liste an Wahlmöglichkeiten anzeigten und dann fragten was es
>denn sein darf.

Unangebrachte Reminiszenzen - wüsste nicht, was eine nummerierte
Auswahlliste als UI-Element mit ... sagen wir einer laufenden
Rechnungsnummer zu tun hätte.


>Auf jeden Fall indentifizieren *Nutzer* Datensätzer wohl selten anhand
>einer generierten ID sondern eher anhand des sonstigen Inhalts: "alle
>Rechnungen von Firma X vom letzten Monat".

Das mag für viele Anwendungsfälle so stimmen. Aber hier geht es
beispielsweise um Kommunikation zweier Mitarbeiter. Ich müsste mich
entscheiden, was besser ist:

"An Datensatz #57 ist etwas falsch" oder
"Am Datensatz vom 1. Januar 2001 um 13:24 ist etwas falsch"

In meinem Fall gibt es, abgesehen davon Datensätze intern hinterfragen
zu können, keine Identifizierungsnotwendigkeit. Insofern könnte es
tatsächlich ausreichen, das Datum anzugeben.


>>>Es hat keinen (für mich erkennbaren) Vorteil. Es könnte Nachteile
>>>haben, wenn das eine InnoDB-Tabelle ist - aber da funktioniert
>>>AUTO_INCREMENT für composite PKs ohnehin nicht.
>> Tabellen mit Fremdschlüssel müssen diesen um die zweite Spalte
>> erweitern. Das ist leider im Gegenzug etwas unschön (die
>> Assoziationstabelle hat dann drei Spalten), aber ein wohl akzeptabler
>> Kompromiss.
>Nicht für mich. Ein PK ist idealerweise numerisch und hängt nicht von
>externen Daten ab. Man *kann* von dieser Regel abweichen, wenn es gute
>Gründe gibt. Du hast keinen genannt.

Wozu auch?

Mein Primary Key ist nummerisch und nicht von externen Daten abhängig,
insofern kann ich Deine Antwort nicht ganz nachvollziehen.

Schöne Grüße, Steffen

Re: Primaerschluessel aus zwei Spalten

am 19.11.2007 17:56:19 von steffen horst

Christian Kirsch wrote:
>steffen horst schrieb:
>> Aber ich muss gestehen, ich kann mir auch vorstellen, dass es nur
>> wenigen so geht und dass andere beispielsweise das Datum und die
>> Uhrzeit zur Identifizierung bevorzugen würden. Mir persönlich wäre der
>> Zeitpunkt einfach zu aufwändig. Leichter ist einfach "Schau mal,
>> Datensatz #313, da ist ein Fehler!" Und diesen zu suchen ist bei einer
>> einigermaßen lückenfreien Nummerierung einfacher, als bei Datumswerten
>> - welche ja keine konstanten Abstände haben. Ich mache mir dazu
>> nochmal Gedanken.
>Wenn Du etwas präziser formulieren würdest, wäre die Unterhaltung
>leichter. Man weiß nie so recht, ob Du von einem Rechner oder von
>Menschen redest, wenn Du z.B. von "suchen" sprichst.

OK. Es geht selbstverständlich um den Menschen, denn ein Computer
kümmert sich meines Wissens nicht um die Abstände zwischen
Datumswerten. Nein, im Ernst: Datensätze anhand eines Primärschlüssels
(unabhängig davon, ob der nun aus einer oder zwei Spalten besteht)
findet ein Rechner ausreichend schnell, darum kann es also nicht
gehen. Tut mir leid, falls das tatsächlich unklar war.


>Aus dem Zusammenhang vermute ich mal, es geht Dir hier um Menschen, die
>vor einer Liste mit Datensätzen sitzen. Einer von ihnen (Menschen) sieht
>einen Fehler in einem Datensatz, findet dessen Nummer heraus und gibt
>diese Nummer an jemand anders weiter (offenbar nicht per IT, sondern
>akustisch?). Dieser zweite Mensch nun will denselben Datensatz in
>(derselben?) Liste lokalisieren.

Exakt, wobei es natürlich nicht akkustisch sein muss, sondern auch
IT-gestützt sein kann.

Also ich sehe es ein, dass Nummerierungen scheinbar gar nicht so
üblich sind, wie angenommen. Ich ändere das, stelle das Datum nach
vorne, sortiere fortan nach Datum und überlege, ob mir das
einfacher/ausreichend vorkommt.

Schöne Grüße, Steffen

Re: Primärschlüsselaus zwei Spalten

am 19.11.2007 19:40:30 von Harald Fuchs

In article ,
steffen horst writes:

> Gut, wenn ich also annehmen kann, dass Deine Webseiten ohne Zahlen
> auskommen (Du möchtest den Nutzer ja nicht mit Zahlen behelligen),
> kann ich Dir keine Argumente mehr entgegenbringen. Ich halte Zahlen
> btw. weder für unmenschlich noch für unzweckmäßig.

Ich dachte, nur die 15 sei unmenschlich, die 2 aber nicht?

Spaß beiseite: Zahlen an sich bedeuten gar nichts. Anscheinend willst
Du mit diesen Zahlen irgendwas ausdrücken, aber ich habe nicht
begriffen, was genau...

Re: Primärschlüssel aus zwei Spalten

am 19.11.2007 19:52:33 von steffen horst

Harald Fuchs wrote:
>steffen horst writes:
>> Gut, wenn ich also annehmen kann, dass Deine Webseiten ohne Zahlen
>> auskommen (Du möchtest den Nutzer ja nicht mit Zahlen behelligen),
>> kann ich Dir keine Argumente mehr entgegenbringen. Ich halte Zahlen
>> btw. weder für unmenschlich noch für unzweckmäßig.
>Ich dachte, nur die 15 sei unmenschlich, die 2 aber nicht?
>Spaß beiseite: Zahlen an sich bedeuten gar nichts. Anscheinend willst
>Du mit diesen Zahlen irgendwas ausdrücken, aber ich habe nicht
>begriffen, was genau...

Die "laufende Nummer", wie man sie oft findet. Ursprünglich ging es
eben darum, diese auch tatsächlich 'laufend' zu haben und nicht
springend oder rennend.

schöne grüße, steffen

Re: Primaerschluessel aus zwei Spalten

am 20.11.2007 08:13:45 von petsch

On 19 Nov., 17:56, steffen horst wrote:
>
> Also ich sehe es ein, dass Nummerierungen scheinbar gar nicht so
> üblich sind, wie angenommen. Ich ändere das, stelle das Datum nach
> vorne, sortiere fortan nach Datum und überlege, ob mir das
> einfacher/ausreichend vorkommt.

Nun wollte ich dich gerade in deinem ursprünglichen Vorhaben
unterstützen und da wirfst Du die Flinte ins Korn. tss, tss. :-)

Ich habe in meinen Listen die die User zu sehen bekommen auch fast
überall laufende Nummern. Tatsächlich ist es schneller jemand am
Telefon die Nummer eines fehlerhaften Datensatzes mitzuteilen, als den
Datensatz anhand diverser anderer Kriterien zu beschreiben. Die User
mögen die Nummern; also sollen Sie sie auch haben.

Allerdings musst Du dich dann weitgehend selbst um die fortlaufende
Nummerierung kümmern. Mit Mitteln wie Auto_Inc kommst Du in diesem
Fall nicht weit, wie Du ja sicher inzwischen bemerkt hast. Aber so
dramatisch ist das auch nicht:

- PRIMARY nur auf `id` (falls Du die id dann überhaupt noch brauchst)
- Ein zusätzliches Feld `lfd_nr` anlegen
- UNIQUE-Index auf `group_id` und `lfd_nr` (Eindeutigkeit)
- INDEX auf `lfd_nr` (Geschwindigkeit)

SELECT MAX(lfd_nr)+1 FROM ... WHERE group_id=3D...

Und dann die neue höchste Nummer in das zusätzliche Feld `lfd_nr`
schreiben. Beim Einfügen an beliebiger Stelle der Liste wird es dann
natürlich ein bisschen aufwendiger; doch IMHO lohnt sich der Aufwand.
Und was tut man nicht alles um die User glücklich zu machen...

Peter

Re: Primaerschluessel aus zwei Spalten

am 20.11.2007 10:50:17 von Axel Schwenke

Peter Schleif wrote:
> On 19 Nov., 17:56, steffen horst wrote:
>>
> Nun wollte ich dich gerade in deinem ursprünglichen Vorhaben
> unterstützen und da wirfst Du die Flinte ins Korn. tss, tss. :-)

> Allerdings musst Du dich dann weitgehend selbst um die fortlaufende
> Nummerierung kümmern. Mit Mitteln wie Auto_Inc kommst Du in diesem
> Fall nicht weit, wie Du ja sicher inzwischen bemerkt hast. Aber so
> dramatisch ist das auch nicht:
>
> - PRIMARY nur auf `id` (falls Du die id dann überhaupt noch brauchst)
> - Ein zusätzliches Feld `lfd_nr` anlegen
> - UNIQUE-Index auf `group_id` und `lfd_nr` (Eindeutigkeit)
> - INDEX auf `lfd_nr` (Geschwindigkeit)

Wozu das? SELECT ... WHERE lfd_nr=... ist dann ja nicht eindeutig.
Und für SELECT ... WHERE group_id=... AND lfd_nr=... wird ohnehin
der UNIQUE Index genommen (und ist auch die bessere Wahl).

> SELECT MAX(lfd_nr)+1 FROM ... WHERE group_id=...
> Und dann die neue höchste Nummer in das zusätzliche Feld `lfd_nr`
> schreiben.

Und jetzt denken wir noch mal kurz über race-conditions nach.
Was passiert, wenn zwischen dem SELECT und dem INSERT jemand
anders einen Datensatz einfügt?

Ich sehe auch *immer* noch nicht den Vorteil gegenüber einer
globalen AUTO_INCREMENT id. Ja, die Nummern werden potentiell
kleiner. Und?

Hingegen sehe ich die Möglichkeit einer weiteren race-condition
(diesmal außerhalb der Datenbank):
Nutzer A sieht fehlerhaften Datensatz X für Gruppe Y und ruft
Nutzer B an. Mittlerweile hat aber Nutzer C diesen Datensatz schon
gelöscht und Nutzer D hat einen neuen Datensatz X/Y angelegt.
Da deine "Lösung" die id innerhalb der Gruppen wiederverwendet,
kann Nutzer B das nicht erkennen. Er bräuchte Zusatzinformationen
um zu prüfen ob das auch wirklich der richtige Datensatz ist.


XL

Re: Primaerschluessel aus zwei Spalten

am 20.11.2007 11:52:22 von steffen horst

Peter Schleif wrote:
>On 19 Nov., 17:56, steffen horst wrote:
>> Also ich sehe es ein, dass Nummerierungen scheinbar gar nicht so
>> üblich sind, wie angenommen. Ich ändere das, stelle das Datum nach
>> vorne, sortiere fortan nach Datum und überlege, ob mir das
>> einfacher/ausreichend vorkommt.
>Nun wollte ich dich gerade in deinem ursprünglichen Vorhaben
>unterstützen und da wirfst Du die Flinte ins Korn. tss, tss. :-)

Tja bei soviel geballtem Gegendruck und keiner Unterstützung meines
Standpunktes wäre es töricht, es nicht zumindest auszuprobieren, die
Nummern wegzulassen.

>Ich habe in meinen Listen die die User zu sehen bekommen auch fast
>überall laufende Nummern. Tatsächlich ist es schneller jemand am
>Telefon die Nummer eines fehlerhaften Datensatzes mitzuteilen, als den
>Datensatz anhand diverser anderer Kriterien zu beschreiben. Die User
>mögen die Nummern; also sollen Sie sie auch haben.

Wie steht's dann mit einem Datum aus? Das ist auch in jedem Datensatz
dabei. Reicht das Deiner Meinung nach nicht aus?

>Allerdings musst Du dich dann weitgehend selbst um die fortlaufende
>Nummerierung kümmern. Mit Mitteln wie Auto_Inc kommst Du in diesem
>Fall nicht weit, wie Du ja sicher inzwischen bemerkt hast. Aber so
>dramatisch ist das auch nicht:

Nein, Deine Anforderungen entscheiden sich von meinen. Du möchtest
eine fortlaufende Nummerierung haben. Diese Bedingung gibt's bei mir
nicht. Bei den seltenen Fällen eines Löschvorgangs wäre eine Lücke in
der Nummerierung unerheblich. Auch werden keine Datensätze eingefügt.
Insofern wäre die Lösung in meinem Fall tatsächlich AUTO_INCREMENT:

PRIMARY KEY auf groupid und id. AUTO_INCREMENT auf id. Beim Einfügen
wird die groupid angegeben und id automatisch gruppenspezifisch
fortlaufend erhöht.

Schöne Grüße, Steffen

Re: Primaerschluessel aus zwei Spalten

am 20.11.2007 14:04:13 von petsch

On 20 Nov., 10:50, Axel Schwenke wrote:
>
> Was passiert, wenn zwischen dem SELECT und dem INSERT jemand
> anders einen Datensatz einfügt?

START TRANSACTION?

Re: Primaerschluessel aus zwei Spalten

am 20.11.2007 14:15:29 von petsch

On 20 Nov., 11:52, steffen horst wrote:
>
> Wie steht's dann mit einem Datum aus? Das ist auch in jedem Datensatz
> dabei. Reicht das Deiner Meinung nach nicht aus?

Das musst Du schon selbst entscheiden. Die Datensätze meiner Listen
werden häufig erst durch die Kombination mehrerer/vieler Spalten
eindeutig. Die User finden es halt einfacher eine laufende Nummer
vorzulesen, als eine ganze Reihe von Kriterien.

Die interne id (auto_inc) geht sie aber nichts an und ist bei langen
Tabellen manchmal auch recht groß. Sie finden es halt am einfachsten
eine relativ kleine laufende Nummer vorzulesen, die innerhalb einer
Gruppe selten größer wird als 100.

>
> Nein, Deine Anforderungen entscheiden sich von meinen.

ACK.

Bei mir kommt es zum Umsortieren und Einfügen mitten in den Listen.
Das scheint bei dir nicht der Fall zu sein.

Peter

Re: Primaerschluessel aus zwei Spalten

am 21.11.2007 15:09:30 von Siegfried Schmidt

Hallo Peter,

>> Was passiert, wenn zwischen dem SELECT und dem INSERT jemand
>> anders einen Datensatz einfügt?
>
> START TRANSACTION?

Ein insert scheitert am Index, gleich ob mit oder ohne Transaktion.


Siegfried
--
http://www.schmidt.ath.cx

Re: Primaerschluessel aus zwei Spalten

am 21.11.2007 20:10:06 von petsch

On 21 Nov., 15:09, Siegfried Schmidt wrote:
>
> Ein insert scheitert am Index, gleich ob mit oder ohne Transaktion.

Häh?

An welchen (von mir vorgeschlagenen) Index sollte das scheiten? Ich
habe als Primary eine id mit Auto-Inc empfohlen und einen UNIQUE auf
group_id und lfd_nr. Diese beiden unterliegen beim Insert der
Kontrolle des Programmierers. Also keine Probleme.

Peter

Re: Primaerschluessel aus zwei Spalten

am 21.11.2007 21:47:14 von Siegfried Schmidt

Hallo Peter,

> An welchen (von mir vorgeschlagenen) Index sollte das scheiten?

Wenn zwei Datensätze gleichzeitig angelegt werden dann am zweiten Index,
was ja die Frage war.

> Diese beiden unterliegen beim Insert der
> Kontrolle des Programmierers. Also keine Probleme.

Häh? Was für eine Kontrolle soll ein Programmierer beim Insert über einen
Index haben?



Siegfried
--
http://www.schmidt.ath.cx

Re: Primaerschluessel aus zwei Spalten

am 22.11.2007 07:22:14 von petsch

On 21 Nov., 21:47, Siegfried Schmidt wrote:
> Hallo Peter,
>
> > An welchen (von mir vorgeschlagenen) Index sollte das scheiten?
>
> Wenn zwei Datensätze gleichzeitig angelegt werden dann am zweiten Index,=

> was ja die Frage war.

Er werden ja nicht zwei Datensätze gleichzeitig angelegt. Wenn das
zweite Insert kommt, wurde lfd_nr ja schon erhöht und MAX(lfd_nr)+1
liefert die nächste freie Nummer.

>
> Häh? Was für eine Kontrolle soll ein Programmierer beim Insert über =
einen
> Index haben?

Natürlich nicht über den Index, sondern darüber *welche* Zahl er als
nächstes in das Feld lfd_nr einfügt - nämlich: MAX(lfd_nr)+1

Re: Primaerschluessel aus zwei Spalten

am 22.11.2007 08:17:36 von Siegfried Schmidt

Hallo Peter,

> Er werden ja nicht zwei Datensätze gleichzeitig angelegt. Wenn das
> zweite Insert kommt, wurde lfd_nr ja schon erhöht und MAX(lfd_nr)+1
> liefert die nächste freie Nummer.

Es ist durch nichts garantiert, daß zwei Abfragen des Maxwertes zum Zweck
des Einfügens eines neuen Satzes unterschiedliche Ergebnisse liefern. Wenn
es das wäre, könnte man den ganzen Aufwand für Autoincrements und Zähler
komplett einsparen.

> Natürlich nicht über den Index, sondern darüber *welche* Zahl er als
> nächstes in das Feld lfd_nr einfügt - nämlich: MAX(lfd_nr)+1

Den neuen Wert vor dem Einfügen zusätzlich auch noch über den Client zu
geschleusen damit er sichtbar wird ändert am obigen auch nichts.


Siegfried
--
http://www.schmidt.ath.cx

Re: Primaerschluessel aus zwei Spalten

am 22.11.2007 08:25:39 von Axel Schwenke

Peter Schleif wrote:
> On 21 Nov., 15:09, Siegfried Schmidt wrote:
>>
>> Ein insert scheitert am Index, gleich ob mit oder ohne Transaktion.
>
> Häh?
>
> An welchen (von mir vorgeschlagenen) Index sollte das scheiten? Ich
> habe als Primary eine id mit Auto-Inc empfohlen und einen UNIQUE auf
> group_id und lfd_nr. Diese beiden unterliegen beim Insert der
> Kontrolle des Programmierers. Also keine Probleme.

Weder der Index noch die Verwendung von Transaktionen verhindert die
race-condition. Wenn zwei Leute gleichzeitig versuchen einen Datensatz
anzulegen, bekommen sie von SELECT MAX(lfd_nr)+1 ... die gleiche
Nummer, aber nur ein INSERT geht durch. Das andere wird wegen
Verletzung des UNIQUE Constraints abgewiesen.

Wenn man die Applikation jetzt so umschreibt, daß sie diesen Fehler
auffängt und die ganze Aktion im Fehlerfall so lange wiederholt bis
das INSERT durchgeht, endet man mit einem Programm, das formal eine
Endlosschleife enthält. Die Alternative wäre Locking.
Beides nicht schön. Und bei Verwendung von AUTO_INCREMENT nicht nötig.

Wenn man unbedingt eine Sequenz pro Gruppe haben will, kann man das
a'la http://forge.mysql.com/snippets/view.php?id=7 lösen.


XL