UUID als Primärschlüssel

UUID als Primärschlüssel

am 08.07.2007 14:15:02 von jonas.a.schmidt

Hallo zusammen,

bisher habe ich hauptsächlich auf dem MSSQL-Server entwickelt. Dort
habe ich die Uniqueidentifier kennen und schätzen gelernt.

Jetzt entwickle ich eine Datenbankanwendung mit MySQL und möchte dort
auch gerne Uniqueidentifiers als Primärschlüssel verwenden. Jedoch bin
ich mir nicht sicher, ob das eine gute Idee ist. Deshalb einige
Fragen:

Es gibt ja keinen eigenen Datentyp, deshalb speichere ich die Werte in
einer Spalte vom Typ char(36). Ist das OK?

Wie kann ich erreichen, daß beim Einfügen einer Zeile automatisch eine
ID erzeugt wird? Laut Doku ist es ja nicht möglich, den Rückgabewert
einer Funktion als Standardwert in eine Spalte zu schreiben. Wie macht
man das? Trigger?

Die UUIDs, die MySQL erzeugt sehen nicht besonders eindeutig aus. Sie
unterscheiden sich nur im ersten Ziffernblock:

576d5708-7e9c-102a-8315-8315e22c3790
57f320e0-7e9c-102a-8315-8315e22c3790
584757dc-7e9c-102a-8315-8315e22c3790
6515b86e-7e9c-102a-8315-8315e22c3790

Ist das normal?

Und Grundsätzlich die Frage: Ist es eine gute Idee, UUIDs als
Primärschlüssel zu verwenden oder würdet Ihr mir eher abraten?

Vielen Dank!

Jonas

Re: UUID als Primärschlüssel

am 08.07.2007 14:49:23 von Christian Kirsch

jonas.a.schmidt@arcor.de schrieb:
> Hallo zusammen,
>
> bisher habe ich hauptsächlich auf dem MSSQL-Server entwickelt. Dort
> habe ich die Uniqueidentifier kennen und schätzen gelernt.
>

Für was? Kennt der SQL Server kein Serial?

> Jetzt entwickle ich eine Datenbankanwendung mit MySQL und möchte dort
> auch gerne Uniqueidentifiers als Primärschlüssel verwenden. Jedoch bin
> ich mir nicht sicher, ob das eine gute Idee ist. Deshalb einige
> Fragen:
>
> Es gibt ja keinen eigenen Datentyp, deshalb speichere ich die Werte in
> einer Spalte vom Typ char(36). Ist das OK?

Warum fragst Du? Bekommst Du denn eine Fehlermeldung oder kannst Du
irgendetwas nicht tun, das Du gerne tun würdest?

Falls es Dir um Performance gehen sollte: Vermutlich ist INT ein
günstigerer Datentyp für einen PK. Es dürfte ja schneller gehen, 4 Byte
zu vergleichen als 9.

>
> Wie kann ich erreichen, daß beim Einfügen einer Zeile automatisch eine
> ID erzeugt wird? Laut Doku ist es ja nicht möglich, den Rückgabewert
> einer Funktion als Standardwert in eine Spalte zu schreiben. Wie macht
> man das? Trigger?
>
> Die UUIDs, die MySQL erzeugt sehen nicht besonders eindeutig aus. Sie

Was stellst Du Dir denn unter "besonders eindeutig" vor? Ich habe mal
Mathe studiert, seitdem hänge ich der Vorstellung an, dass irgendwas
eindeutig ist oder eben nicht - von Abstufungen haben sie uns damals gar
nichts verraten.

>
> Und Grundsätzlich die Frage: Ist es eine gute Idee, UUIDs als
> Primärschlüssel zu verwenden oder würdet Ihr mir eher abraten?

Was genau spricht Deiner Meinung nach denn gegen die Verwendung einer
auto_increment-Spalte? Das ist doch genau das, was MySQL für diesen
Zweck bereitstellt, genau wie andere Datenbanken, wo ein ähnliches
Konzept "serial" heißt.

Re: UUID als Primärschlüssel

am 08.07.2007 15:37:14 von jonas.a.schmidt

On 8 Jul., 14:49, Christian Kirsch wrote:
> jonas.a.schm...@arcor.de schrieb:
> Für was? Kennt der SQL Server kein Serial?

Wenn serial heißt, daß eine Zahl als ID verwendet wird, die
fortlaufend erhöht wird, dann kann das der SQL Server natürlich auch.

> > Es gibt ja keinen eigenen Datentyp, deshalb speichere ich die Werte in
> > einer Spalte vom Typ char(36). Ist das OK?
> Warum fragst Du? Bekommst Du denn eine Fehlermeldung oder kannst Du
> irgendetwas nicht tun, das Du gerne tun würdest?

Auf den ersten Blick funktioniert es. Vorher hatte ich es mit
binary(16) getestet, das hat auch auf den ersten Blick funktioniert,
aber ich hatte dann Probleme beim Speichern mit Qt. Deshalb frage ich
lieber vorher.

> Falls es Dir um Performance gehen sollte: Vermutlich ist INT ein
> günstigerer Datentyp für einen PK. Es dürfte ja schneller gehen, 4 =
Byte
> zu vergleichen als 9.

Das ist wohl war, doch wenn MySQL die sauber organisiert (wovon ich
ausgehe), dann dürfte es nicht viel ausmachen. Habe es aber nicht
getestet. Meine Datenbank wird auch nur ein paar Tausend Datensätze
enthalten und es werden auch nicht so wahnsinnig viele Abfragen
kommen, so daß das kein Problem sein sollte.

> > Die UUIDs, die MySQL erzeugt sehen nicht besonders eindeutig aus. Sie
> Was stellst Du Dir denn unter "besonders eindeutig" vor? Ich habe mal
> Mathe studiert, seitdem hänge ich der Vorstellung an, dass irgendwas
> eindeutig ist oder eben nicht - von Abstufungen haben sie uns damals gar
> nichts verraten.

"Besonders eindeutig" meint hier, daß ich nicht den Eindruck habe, daß
wenn ich genügend UUIDs erzeuge, alle Eindeutig sind. Unter Windows
ist es so, daß sich zwei UUIDs in allen Ziffernblöcken deutlich
unterscheiden. Was hier eben nicht der Fall ist. Deshalb wollte ich
wissen, ob das so OK ist oder ob etwas falsch konfiguriert ist (z.B.
daß MySQL die MAC-Adresse nicht richtig auslesen kann).

> Was genau spricht Deiner Meinung nach denn gegen die Verwendung einer
> auto_increment-Spalte? Das ist doch genau das, was MySQL für diesen
> Zweck bereitstellt, genau wie andere Datenbanken, wo ein ähnliches
> Konzept "serial" heißt.

Der entscheidende Vorteil bei UUIDs ist, daß Du eine ID auf dem Client
erstellen kannst, die garantiert eindeutig ist, ohne daß eine
Datenbankverbindung bestehen muß. Besonders bei komplexen relationalen
Tabellenstrukturen kannst Du alle Datensätze auf dem Client erzeugen
und dann bequem in einer Transaktion in die Datenbank schreiben - wenn
es sein muß auch drei Tage später, wenn man gerade keine
Datenbankverbindung hat.

Das geht m.E. mit einer Auto-Increment-Spalte nur mit wesentlich mehr
Aufwand.

Jonas

Re: UUID als Primärschlüssel

am 08.07.2007 16:33:02 von Christian Kirsch

jonas.a.schmidt@arcor.de schrieb:
>
> Auf den ersten Blick funktioniert es. Vorher hatte ich es mit
> binary(16) getestet, das hat auch auf den ersten Blick funktioniert,
> aber ich hatte dann Probleme beim Speichern mit Qt. Deshalb frage ich
> lieber vorher.
>

Und *was* für "Probleme"? Was meinst Du mit Qt (die Library von
Trolltech, Quicktime, sonst was)? Wie wäre es, wenn Du einfach die ganze
Geschichte möglichst faktenreich erzähltest? Hier kann Dir doch niemand
helfen, wenn Du nur bröckchenweise Informationen ablieferst.

>> Falls es Dir um Performance gehen sollte: Vermutlich ist INT ein
>> günstigerer Datentyp für einen PK. Es dürfte ja schneller gehen, 4 Byte
>> zu vergleichen als 9.
>
> Das ist wohl war, doch wenn MySQL die sauber organisiert (wovon ich
> ausgehe), dann dürfte es nicht viel ausmachen.

Wenn Du meinst... Ich kann mir zwar nicht vorstellen, dass irgendeine
Art von Organisation den Vergleich von 2,25 Integern schneller macht als
den von 1 Integer, aber vielleicht ist das ja bei MSSQL so.

> Habe es aber nicht
> getestet. Meine Datenbank wird auch nur ein paar Tausend Datensätze
> enthalten und es werden auch nicht so wahnsinnig viele Abfragen
> kommen, so daß das kein Problem sein sollte.
>

Was ist denn Deine Frage? Wenn Du weißt, dass es im Prinzip geht, wenn
Performance keine Rolle spielt - was willst Du wissen?

> Der entscheidende Vorteil bei UUIDs ist, daß Du eine ID auf dem Client
> erstellen kannst, die garantiert eindeutig ist, ohne daß eine
> Datenbankverbindung bestehen muß. Besonders bei komplexen relationalen
> Tabellenstrukturen kannst Du alle Datensätze auf dem Client erzeugen
> und dann bequem in einer Transaktion in die Datenbank schreiben - wenn
> es sein muß auch drei Tage später, wenn man gerade keine
> Datenbankverbindung hat.
>

Schwebt Dir sowas vor sie
SELECT @uid1 := UUID()
SELECT @uid2 := UUID()
....

INSERT INTO bla (id,...) VALUES (uid1,...)
INSERT into fasel (id, ...) VALUES (uid2,...)

Dann wirst Du an diese UUIDs wohl nicht bekommen, "ohne dass eine
Datenbankverbindung besteht" (es sei denn, Scotty beamed da was zusammen).

Was also meinst Du? Die UUID-Funktion von MySQL, die Dir "nicht
eindeutig genug" ist - aber auf dem Server läuft, sodass Dein Client sie
nur bei vorhandener DB-Verbindung benutzen kann? Oder eine irgendwie
geartete Client-Funktion, die irgendwelche weltweit einzigartigen Dinge
erzeugt, die Du dann an den Server schickst? In diesem Fall geht es doch
gar nicht um MySQL, sondern um die von Dir benutzt Client-Bibliothek,
die die UUIDs erzeugt.

Re: UUID als Primärschlüssel

am 08.07.2007 16:44:15 von Gregor Kofler

jonas.a.schmidt@arcor.de meinte:
> Hallo zusammen,
>
> bisher habe ich hauptsächlich auf dem MSSQL-Server entwickelt. Dort
> habe ich die Uniqueidentifier kennen und schätzen gelernt.

> Jetzt entwickle ich eine Datenbankanwendung mit MySQL und möchte dort
> auch gerne Uniqueidentifiers als Primärschlüssel verwenden. Jedoch bin
> ich mir nicht sicher, ob das eine gute Idee ist. Deshalb einige
> Fragen:

Warum? UUIDs sind primär wohl nicht für PKs einzelner Tabellen gedacht.
Siehe

Und
"...Der uniqueidentifier-Datentyp generiert nicht wie die
IDENTITY-Eigenschaft automatisch neue IDs für eingefügte Zeilen..."



> Es gibt ja keinen eigenen Datentyp, deshalb speichere ich die Werte in
> einer Spalte vom Typ char(36). Ist das OK?

Wenn man einen eindeutigen PK ohne besondere Zusatzansprüche will, nimmt
man Integer mit Autoincrement. Fertig. Billig, schnell, millionfach
erprobt. Alles andere ist Overhead, Murks, sonstwas.

> Wie kann ich erreichen, daß beim Einfügen einer Zeile automatisch eine
> ID erzeugt wird? Laut Doku ist es ja nicht möglich, den Rückgabewert
> einer Funktion als Standardwert in eine Spalte zu schreiben. Wie macht
> man das? Trigger?
>
> Die UUIDs, die MySQL erzeugt sehen nicht besonders eindeutig aus. Sie
> unterscheiden sich nur im ersten Ziffernblock:
>
> 576d5708-7e9c-102a-8315-8315e22c3790
> 57f320e0-7e9c-102a-8315-8315e22c3790
> 584757dc-7e9c-102a-8315-8315e22c3790
> 6515b86e-7e9c-102a-8315-8315e22c3790
>
> Ist das normal?

Eindeutig sind sie ja. Und bislang hatte ich keinen Bedarf für UUIDs.

> Und Grundsätzlich die Frage: Ist es eine gute Idee, UUIDs als
> Primärschlüssel zu verwenden oder würdet Ihr mir eher abraten?

S.o.

> Vielen Dank!

Das Problem hatten schon andere:

http://forums.mysql.com/read.php?60,33684,33702#msg-33702

HTH, Gregor


--
http://www.gregorkofler.at ::: Landschafts- und Reisefotografie
http://www.licht-blick.at ::: Forum für Multivisionsvorträge
http://www.image2d.com ::: Bildagentur für den alpinen Raum

Re: UUID als Primärschlüssel

am 08.07.2007 16:44:30 von Nicolas Ulmann

> Was also meinst Du? Die UUID-Funktion von MySQL, die Dir "nicht
> eindeutig genug" ist - aber auf dem Server läuft, sodass Dein Client sie
> nur bei vorhandener DB-Verbindung benutzen kann? Oder eine irgendwie
> geartete Client-Funktion, die irgendwelche weltweit einzigartigen Dinge
> erzeugt, die Du dann an den Server schickst? In diesem Fall geht es doch
> gar nicht um MySQL, sondern um die von Dir benutzt Client-Bibliothek,
> die die UUIDs erzeugt.

Ich glaube, sein Grundgedanke ist, dass man Daten zeitversetzt von
verschiedenen Seiten in die Datenbank reinspiegeln kann. Das ist gar
nicht so unnütz.
Bei auto_increment-ids würden die verschiednen CLients im lokalbetrieb
gleiche IDs generieren, die dann bei der Zusammenführung kollidieren
würden, bei einer UID in der Form, wie er sie vorschlagt, also mit ca
10^24 Kombinationen, könnte man die Daten ganz einfach zusammenführen,
ohne PKs ändern zu müssen.

Re: UUID als Primärschlüssel

am 08.07.2007 16:45:53 von Gregor Kofler

Nicolas Ulmann meinte:

> Ich glaube, sein Grundgedanke ist, dass man Daten zeitversetzt von
> verschiedenen Seiten in die Datenbank reinspiegeln kann. Das ist gar
> nicht so unnütz.

Vielleicht sollte er das dann auch schreiben.

Zitat:
bisher habe ich hauptsächlich auf dem MSSQL-Server entwickelt. Dort
habe ich die Uniqueidentifier kennen und schätzen gelernt.

Jetzt entwickle ich eine Datenbankanwendung mit MySQL und möchte dort
auch gerne Uniqueidentifiers als Primärschlüssel verwenden. Jedoch bin
ich mir nicht sicher, ob das eine gute Idee ist.

klingt irgendwie nicht danach.


Gruß, Gregor


--
http://www.gregorkofler.at ::: Landschafts- und Reisefotografie
http://www.licht-blick.at ::: Forum für Multivisionsvorträge
http://www.image2d.com ::: Bildagentur für den alpinen Raum

Re: UUID als Primärschlüssel

am 08.07.2007 17:11:00 von Nicolas Ulmann

> Vielleicht sollte er das dann auch schreiben.

Ich les das aus "Der entscheidende Vorteil bei UUIDs ist, daß Du eine ID
auf dem Client
erstellen kannst, die garantiert eindeutig ist, ohne daß eine
Datenbankverbindung bestehen muß."

Re: UUID als Primärschlüssel

am 08.07.2007 17:40:00 von jonas.a.schmidt

On 8 Jul., 16:33, Christian Kirsch wrote:
> jonas.a.schm...@arcor.de schrieb:
> Und *was* für "Probleme"? Was meinst Du mit Qt (die Library von
> Trolltech, Quicktime, sonst was)? Wie wäre es, wenn Du einfach die ganze
> Geschichte möglichst faktenreich erzähltest? Hier kann Dir doch niema=
nd
> helfen, wenn Du nur bröckchenweise Informationen ablieferst.

Die Library von Trolltech. Das ist aber nicht mein Problem. Meine
Frage ist: Mit welchem Spaltentyp speichert man üblicherweise die
UUIDs in MySQL?

Inzwischen läuft es unter Qt - aber meine Qt-Probleme gehören sowieso
nicht hier hin.

> >> Falls es Dir um Performance gehen sollte: Vermutlich ist INT ein
> >> günstigerer Datentyp für einen PK. Es dürfte ja schneller gehen,=
4 Byte
> >> zu vergleichen als 9.
> > Das ist wohl war, doch wenn MySQL die sauber organisiert (wovon ich
> > ausgehe), dann dürfte es nicht viel ausmachen.
> Wenn Du meinst... Ich kann mir zwar nicht vorstellen, dass irgendeine
> Art von Organisation den Vergleich von 2,25 Integern schneller macht als
> den von 1 Integer,

Das habe ich nicht behauptet. Nur, daß es nicht ins Gewicht fällt.

Wenn Du eine sortierte Liste mit 1.000.000.000 Einträgen hast kannst
Du jeden beliebigen Eintrag mit maximal 30 Vergleichen finden. Und da
ist es wurscht, ob ein Vergleich jetzt 2,25 mal so lange dauert
(zumindest für mein Anwendungsszenario).

Wie ein Datenbankserver seine Daten intern organisiert weiß ich weder
beim SQL Server noch bei MySQL. Aber ich vermute mal, daß er solche
Verfahren verwendet und deshalb Du selbst bei großen Datenbanken mit
vielen Abfragen keinen nennenswerten Performanceverlust hast.

> aber vielleicht ist das ja bei MSSQL so.

Zumindest hatte ich hier bei Tabellen mit Zeilenzahlen im
Millionenbereich noch nie Performanceprobleme wegen der UUIDs.

> Was ist denn Deine Frage? Wenn Du weißt, dass es im Prinzip geht, wenn
> Performance keine Rolle spielt - was willst Du wissen?

Welcher Spaltentyp am besten für UUIDs geeignet ist (s.o.). Wenn es
einen gibt, der z.B. performanter ist, würde ich den trotzdem
bevorzugen.

> Schwebt Dir sowas vor sie
> SELECT @uid1 :=3D UUID()
> SELECT @uid2 :=3D UUID()
> ...
>
> INSERT INTO bla (id,...) VALUES (uid1,...)
> INSERT into fasel (id, ...) VALUES (uid2,...)
>
> Dann wirst Du an diese UUIDs wohl nicht bekommen, "ohne dass eine
> Datenbankverbindung besteht" (es sei denn, Scotty beamed da was zusammen).

Das ist ja gerade der Vorteil, daß Du das SELECT @uid1 :=3D UUID() nicht
brauchst. Bespiel Du hast zwei Tabellen mit einer 1..N Beziehung:
"person" und "email"

person hat per_id als Schlüssel; email em_id als Schlüssel und eine
Relation auf person via em_per_id.

Auf dem Client kann ich die neuen Datensätze jetzt anlegen:

per_id =3D Guid.NewGuid
em_id =3D Guid.NewGuid
em_per_id =3D per_id

(Guid.NewGuid ist die Funktion von C# zum Erzeugen einer neuen UUID -
ohne Datenbankverbindung, ohne Scotty)

Wenn ich dann eine Verbindung zur Datenbank habe, kann ich die Daten
so wie sie sind in einer Transaktion schreiben.

Sicher geht es auch anders, aber bestimmt nicht so bequem. Z.B. kann
ich so den automatischen Insert-Befehl verwenden, den das
Tabellenmodel von Qt odet .NET bereit stellt.

> Was also meinst Du? Die UUID-Funktion von MySQL, die Dir "nicht
> eindeutig genug" ist - aber auf dem Server läuft, sodass Dein Client sie
> nur bei vorhandener DB-Verbindung benutzen kann? Oder eine irgendwie
> geartete Client-Funktion, die irgendwelche weltweit einzigartigen Dinge
> erzeugt, die Du dann an den Server schickst?

Ich meine beides. Für Daten vom Client verwende ich eine Client-
Bibliothek, in Stored Procedures u.a. die Funktion UUID von MySQL.
Außerdem hätte ich gerne, daß bei einem Insert-Befehl, bei dem das
Feld ID leer ist, automatisch eine UUID zugewiesen wird. Womit wir
wieder bei meiner ursprünglichen Frage wären.

> In diesem Fall geht es doch
> gar nicht um MySQL, sondern um die von Dir benutzt Client-Bibliothek,
> die die UUIDs erzeugt.

Richtig.

Jonas

Re: UUID als Primärschlüssel

am 08.07.2007 17:40:20 von jonas.a.schmidt

On 8 Jul., 16:33, Christian Kirsch wrote:
> jonas.a.schm...@arcor.de schrieb:
> Und *was* für "Probleme"? Was meinst Du mit Qt (die Library von
> Trolltech, Quicktime, sonst was)? Wie wäre es, wenn Du einfach die ganze
> Geschichte möglichst faktenreich erzähltest? Hier kann Dir doch niema=
nd
> helfen, wenn Du nur bröckchenweise Informationen ablieferst.

Die Library von Trolltech. Das ist aber nicht mein Problem. Meine
Frage ist: Mit welchem Spaltentyp speichert man üblicherweise die
UUIDs in MySQL?

Inzwischen läuft es unter Qt - aber meine Qt-Probleme gehören sowieso
nicht hier hin.

> >> Falls es Dir um Performance gehen sollte: Vermutlich ist INT ein
> >> günstigerer Datentyp für einen PK. Es dürfte ja schneller gehen,=
4 Byte
> >> zu vergleichen als 9.
> > Das ist wohl war, doch wenn MySQL die sauber organisiert (wovon ich
> > ausgehe), dann dürfte es nicht viel ausmachen.
> Wenn Du meinst... Ich kann mir zwar nicht vorstellen, dass irgendeine
> Art von Organisation den Vergleich von 2,25 Integern schneller macht als
> den von 1 Integer,

Das habe ich nicht behauptet. Nur, daß es nicht ins Gewicht fällt.

Wenn Du eine sortierte Liste mit 1.000.000.000 Einträgen hast kannst
Du jeden beliebigen Eintrag mit maximal 30 Vergleichen finden. Und da
ist es wurscht, ob ein Vergleich jetzt 2,25 mal so lange dauert
(zumindest für mein Anwendungsszenario).

Wie ein Datenbankserver seine Daten intern organisiert weiß ich weder
beim SQL Server noch bei MySQL. Aber ich vermute mal, daß er solche
Verfahren verwendet und deshalb Du selbst bei großen Datenbanken mit
vielen Abfragen keinen nennenswerten Performanceverlust hast.

> aber vielleicht ist das ja bei MSSQL so.

Zumindest hatte ich hier bei Tabellen mit Zeilenzahlen im
Millionenbereich noch nie Performanceprobleme wegen der UUIDs.

> Was ist denn Deine Frage? Wenn Du weißt, dass es im Prinzip geht, wenn
> Performance keine Rolle spielt - was willst Du wissen?

Welcher Spaltentyp am besten für UUIDs geeignet ist (s.o.). Wenn es
einen gibt, der z.B. performanter ist, würde ich den trotzdem
bevorzugen.

> Schwebt Dir sowas vor sie
> SELECT @uid1 :=3D UUID()
> SELECT @uid2 :=3D UUID()
> ...
>
> INSERT INTO bla (id,...) VALUES (uid1,...)
> INSERT into fasel (id, ...) VALUES (uid2,...)
>
> Dann wirst Du an diese UUIDs wohl nicht bekommen, "ohne dass eine
> Datenbankverbindung besteht" (es sei denn, Scotty beamed da was zusammen).

Das ist ja gerade der Vorteil, daß Du das SELECT @uid1 :=3D UUID() nicht
brauchst. Bespiel Du hast zwei Tabellen mit einer 1..N Beziehung:
"person" und "email"

person hat per_id als Schlüssel; email em_id als Schlüssel und eine
Relation auf person via em_per_id.

Auf dem Client kann ich die neuen Datensätze jetzt anlegen:

per_id =3D Guid.NewGuid
em_id =3D Guid.NewGuid
em_per_id =3D per_id

(Guid.NewGuid ist die Funktion von C# zum Erzeugen einer neuen UUID -
ohne Datenbankverbindung, ohne Scotty)

Wenn ich dann eine Verbindung zur Datenbank habe, kann ich die Daten
so wie sie sind in einer Transaktion schreiben.

Sicher geht es auch anders, aber bestimmt nicht so bequem. Z.B. kann
ich so den automatischen Insert-Befehl verwenden, den das
Tabellenmodel von Qt odet .NET bereit stellt.

> Was also meinst Du? Die UUID-Funktion von MySQL, die Dir "nicht
> eindeutig genug" ist - aber auf dem Server läuft, sodass Dein Client sie
> nur bei vorhandener DB-Verbindung benutzen kann? Oder eine irgendwie
> geartete Client-Funktion, die irgendwelche weltweit einzigartigen Dinge
> erzeugt, die Du dann an den Server schickst?

Ich meine beides. Für Daten vom Client verwende ich eine Client-
Bibliothek, in Stored Procedures u.a. die Funktion UUID von MySQL.
Außerdem hätte ich gerne, daß bei einem Insert-Befehl, bei dem das
Feld ID leer ist, automatisch eine UUID zugewiesen wird. Womit wir
wieder bei meiner ursprünglichen Frage wären.

> In diesem Fall geht es doch
> gar nicht um MySQL, sondern um die von Dir benutzt Client-Bibliothek,
> die die UUIDs erzeugt.

Richtig.

Jonas

Re: UUID als Primärschlüssel

am 08.07.2007 17:44:36 von jonas.a.schmidt

On 8 Jul., 16:44, Nicolas Ulmann wrote:
> Ich glaube, sein Grundgedanke ist, dass man Daten zeitversetzt von
> verschiedenen Seiten in die Datenbank reinspiegeln kann. Das ist gar
> nicht so unnütz.

Genau so meine ich es.

> Bei auto_increment-ids würden die verschiednen CLients im lokalbetrieb
> gleiche IDs generieren, die dann bei der Zusammenführung kollidieren
> würden, bei einer UID in der Form, wie er sie vorschlagt, also mit ca
> 10^24 Kombinationen, könnte man die Daten ganz einfach zusammenführen,
> ohne PKs ändern zu müssen.

Richtig. Das ist für mich ein entscheidender Vorteil.

Jonas

Re: UUID als Primärschlüssel

am 08.07.2007 17:54:02 von jonas.a.schmidt

On 8 Jul., 16:44, Gregor Kofler wrote:
> jonas.a.schm...@arcor.de meinte:
> Warum? UUIDs sind primär wohl nicht für PKs einzelner Tabellen gedach=
t
> Siehe
>
> Und
> "...Der uniqueidentifier-Datentyp generiert nicht wie die
> IDENTITY-Eigenschaft automatisch neue IDs für eingefügte Zeilen..."

Warum schließt Du darauf, daß er nicht für PKs gedacht ist. Wenn man
automatisch neue IDs erzeugen will, trägt man als Standardwert die
Funktion NEWID() ein.

Es ist gut, daß der Datentyp das nicht automatisch macht, denn sonst
könnte man ihn nicht zum Speichern von Fremdschlüsseln verwenden.

> Wenn man einen eindeutigen PK ohne besondere Zusatzansprüche will, nimmt
> man Integer mit Autoincrement. Fertig. Billig, schnell, millionfach
> erprobt. Alles andere ist Overhead, Murks, sonstwas.

Overhead ja, Murks nein. Die Vorteile habe ich bereits genannt,
Nachteile stehen in dem von Dir genannten Link. Für mich sind UIDs
immer noch erste Wahl.

> Das Problem hatten schon andere:
>
> http://forums.mysql.com/read.php?60,33684,33702#msg-33702

Dort habe ich auch schon gesucht, aber keine Lösung für mein Problem
gefunden.

Jonas

Re: UUID als Primärschlüssel

am 08.07.2007 18:34:22 von Gregor Kofler

jonas.a.schmidt@arcor.de meinte:
> On 8 Jul., 16:44, Gregor Kofler wrote:
>> jonas.a.schm...@arcor.de meinte:
>> Warum? UUIDs sind primär wohl nicht für PKs einzelner Tabellen gedacht.
>> Siehe
>>
>> Und
>> "...Der uniqueidentifier-Datentyp generiert nicht wie die
>> IDENTITY-Eigenschaft automatisch neue IDs für eingefügte Zeilen..."
>
> Warum schließt Du darauf, daß er nicht für PKs gedacht ist. Wenn man
> automatisch neue IDs erzeugen will, trägt man als Standardwert die
> Funktion NEWID() ein.

Stimmt.

> Es ist gut, daß der Datentyp das nicht automatisch macht, denn sonst
> könnte man ihn nicht zum Speichern von Fremdschlüsseln verwenden.

Naja, das FK-Feld kann ja immer noch was "Äquivalentes" sein.

>> Wenn man einen eindeutigen PK ohne besondere Zusatzansprüche will, nimmt
>> man Integer mit Autoincrement. Fertig. Billig, schnell, millionfach
>> erprobt. Alles andere ist Overhead, Murks, sonstwas.
>
> Overhead ja, Murks nein. Die Vorteile habe ich bereits genannt,
> Nachteile stehen in dem von Dir genannten Link. Für mich sind UIDs
> immer noch erste Wahl.
>
>> Das Problem hatten schon andere:
>>
>> http://forums.mysql.com/read.php?60,33684,33702#msg-33702
>
> Dort habe ich auch schon gesucht, aber keine Lösung für mein Problem
> gefunden.

Hier besser?
http://lists.mysql.com/mysql/165310

Da empfehlen sie auch einfach char(36), wenn es denn eine GUID sein muss.

Gregor


--
http://www.gregorkofler.at ::: Landschafts- und Reisefotografie
http://www.licht-blick.at ::: Forum für Multivisionsvorträge
http://www.image2d.com ::: Bildagentur für den alpinen Raum

Re: UUID_als_Primaerschluessel?

am 09.07.2007 02:19:34 von Axel Schwenke

jonas.a.schmidt@arcor.de wrote:
> On 8 Jul., 16:33, Christian Kirsch wrote:
>
>> Wenn Du meinst... Ich kann mir zwar nicht vorstellen, dass irgendeine
>> Art von Organisation den Vergleich von 2,25 Integern schneller macht als
>> den von 1 Integer,
>
> Das habe ich nicht behauptet. Nur, daß es nicht ins Gewicht fällt.

Naja, ein BIGINT UNSIGNED AUTO_INCREMENT ist halt 8 Bytes, während
ein GUID in Normalform 36 Bytes sind. Ob die 28 extra Bytes signifi-
kant sind, hängt davon ab, was du noch so in jedem Record hast.

IMHO sprechen folgende Gründe gegen GUID als PK

1. Platzverschwendung
2. falls der PK irgendwo als FK referenziert wird: mehr Verschwendung
3. in InnoDB referenzieren sekundäre Indizes den PK: Verschwendung
4. InnoDB clustert Datensätze nach PK. Die pseudo-zufälligen GUID
(insbesondere weil der Timestamp-Teil am Anfang steht) können zu
schlechterer Performance führen im Vergleich zu einem linear
wachsenden AUTO_INCREMENT PK. Insbesondere bei Massen-INSERTs.


>> Was ist denn Deine Frage? Wenn Du weißt, dass es im Prinzip geht, wenn
>> Performance keine Rolle spielt - was willst Du wissen?
>
> Welcher Spaltentyp am besten für UUIDs geeignet ist (s.o.). Wenn es
> einen gibt, der z.B. performanter ist, würde ich den trotzdem
> bevorzugen.

Da MySQL im Moment keine 128-Bit INTEGER kennt, hast du die Wahl
zwischen CHAR(36) und zwei BIGINT UNSIGNED Spalten. Ersteres ist
einfacher zu handhaben (für letzteres könnte man sich mit stored
functions behelfen). Letzteres ist effizienter. 16 vs. 36 Bytes.

>> Schwebt Dir sowas vor sie
>> SELECT @uid1 := UUID()
>> SELECT @uid2 := UUID()
>> ...
>>
>> INSERT INTO bla (id,...) VALUES (uid1,...)
>> INSERT into fasel (id, ...) VALUES (uid2,...)
>>
>> Dann wirst Du an diese UUIDs wohl nicht bekommen, "ohne dass eine
>> Datenbankverbindung besteht" (es sei denn, Scotty beamed da was zusammen).
>
> Das ist ja gerade der Vorteil, daß Du das SELECT @uid1 := UUID() nicht
> brauchst.

Ich bin mir nicht sicher, ob es unbedingt ein Vorteil ist, Primär-
schlüssel außerhalb der Datenbank zu erzeugen und sich darauf zu
verlassen, daß die auch wirklich unique sind. Eine Sequenz oder
AUTO_INCREMENT können Uniqueness garantieren - ein GUID Generator
bietet lediglich ein sehr geringe Wahrscheinlichkeit, daß es zu
einer Kollision kommt.

Im Prinzip müßtest du deine INSERTs auf "duplicate key" Errors
prüfen und notfalls neue PKs generieren. Auch wenn das in der
Praxis nur alle Zintillionen Jahre vorkommen sollte.

> Wenn ich dann eine Verbindung zur Datenbank habe, kann ich die Daten
> so wie sie sind in einer Transaktion schreiben.

Du kannst das mit AUTO_INCREMENT genauso tun:

INSERT INTO person (per_id, ...) VALUES (NULL, ...);
INSERT INTO email (em_id, em_per_id, ...)
VALUES (NULL, LAST_INSERT_ID(), ...);

> Sicher geht es auch anders, aber bestimmt nicht so bequem.

Das liegt offensichtlich im Auge des Betrachters.


XL

Re: UUID_als_Primaerschluessel?

am 09.07.2007 04:47:59 von B.Steinbrink

On Mon, 09 Jul 2007 02:19:34 +0200, Axel Schwenke wrote:

> jonas.a.schmidt@arcor.de wrote:
>> On 8 Jul., 16:33, Christian Kirsch wrote:
>>
>>> Wenn Du meinst... Ich kann mir zwar nicht vorstellen, dass irgendeine
>>> Art von Organisation den Vergleich von 2,25 Integern schneller macht
>>> als den von 1 Integer,
>>
>> Das habe ich nicht behauptet. Nur, daß es nicht ins Gewicht fällt.
>
> Naja, ein BIGINT UNSIGNED AUTO_INCREMENT ist halt 8 Bytes, während ein
> GUID in Normalform 36 Bytes sind. Ob die 28 extra Bytes signifi- kant
> sind, hängt davon ab, was du noch so in jedem Record hast.
>
> IMHO sprechen folgende Gründe gegen GUID als PK
>
> 1. Platzverschwendung
> 2. falls der PK irgendwo als FK referenziert wird: mehr Verschwendung
> 3. in InnoDB referenzieren sekundäre Indizes den PK: Verschwendung
> 4. InnoDB clustert Datensätze nach PK. Die pseudo-zufälligen GUID
> (insbesondere weil der Timestamp-Teil am Anfang steht) können zu
> schlechterer Performance führen im Vergleich zu einem linear
> wachsenden AUTO_INCREMENT PK. Insbesondere bei Massen-INSERTs.

Bei einem sequentiellen PK füllt InnoDB die Index Knoten auch zu etwa
15/16, bei zufälliger Reihenfolge nur zwischen 1/2 und 15/16: Noch mehr
Verschwendung.
http://dev.mysql.com/doc/refman/5.0/en/innodb-physical-struc ture.html

Björn