2009-07-09 12 views
12

Ich arbeite mit einer alten SQL Server 2000-Datenbank und mische einige Informationen davon mit einer neuen App, die ich gerade erstelle. Ich habe bemerkt, dass einige der Primärschlüssel in einigen der Tabellen Floats sind und nicht irgendeine Art von Ints. Sie sind keine Fremdschlüssel und sind alle einzigartig. Ich kann mir keinen Grund vorstellen, warum irgendjemand ihre einzigartigen Primärschlüssel-IDs schweben lassen möchte, aber ich bin kein SQL-Experte. Also ich denke, was ich frage, ist, wer diese ziemlich umfangreiche Datenbank entworfen hat, weiß etwas, was ich nicht weiß?Sanity Check: Floats als Primärschlüssel?

+0

Ich glaube, dass Ihre Instinkte hier zu 100% korrekt sind; Schwimmer machen schlechte Schlüssel. –

Antwort

8

Ich arbeite derzeit mit einem ziemlich großen Buchhalter-Paket, wo jeder von 350+ Tabellen einen Primärschlüssel von FLOAT (53) hat. Alle tatsächlichen Werte sind Ganzzahlen und das System überprüft streng, dass sie tatsächlich sind (es gibt spezielle Funktionen, die alle Inkrementierungsarbeit erledigen).

Ich habe mich über dieses Design wundern, aber ich kann verstehen, warum es ausgewählt wurde und geben Sie ihm ein paar Credits. Auf der einen Seite ist das System groß genug, um Milliarden Datensätze in einigen Tabellen zu haben. Auf der anderen Seite müssen diese Primärschlüssel leicht von externen Anwendungen wie Excel oder VB6 gelesen werden können. In diesem Fall möchten Sie sie nicht wirklich zu BIGINT machen.

Daher ist Float in Ordnung.

+0

Das ist interessant, können Sie erklären, was Sie mit leicht lesbar meinen? Meinst du es ist einfacher für die externen Anwendungen, sie zu lesen oder lesbar? Danke für die Antwort. –

+1

Nein, ich meine die Systeme, mit denen Leute ihre eigenen kleinen Hilfsanwendungen rund um das große Ding schreiben, können einfach nicht mit 64-Bit-Ganzzahlen zurechtkommen. Es gibt keinen Datentyp in VB6, um nativ ein BIGINT zu unterstützen, Sie müssten mit Double (wie es von Excel vorgeschlagen wird) oder Variant-Decimal (wie ADO) spielen. Und das ist zumindest etwas! Ich kann mir leicht ein externes System vorstellen, das BIGINTs überhaupt nicht konsumieren kann. – GSerg

+0

Ah OK ich sehe was du sagst, upvoted, danke. –

2

Ist es ein NUMERIC (x, y) -Format und eine IDENTITY? In diesem Fall könnte es sich um eine Aktualisierung von einer älteren Version von SQL Server handeln. Back-the-Day IDENTITY könnte nur ein NUMERIC-Format sein, nicht das gemeinsame INT, das wir heute verwenden.

Andernfalls gibt es keine Möglichkeit festzustellen, ob ein Float als Primärschlüssel geeignet ist - das hängt von Ihrer Domäne ab. Es ist ein bisschen schwieriger zu vergleichen (IEEE INT ist effizienter als Float) und die meisten Leute verwenden monoton steigende Zahlen (IDENTITY), also sind Integer oft, was die Leute wirklich wollen.

Da es so aussieht, Sie Ints speichern:

die ursprüngliche Frage mehr direkt zu beantworten: Wenn Sie Ints sind zu speichern, verwenden Sie den Integer-Datentyp. Es ist effizienter zu speichern und zu vergleichen.

+1

Eigentlich konnten PKs immer INTs sein, aber da BIGINTs nicht existierten, benutzten Leute NUMERIC – zvolkov

+1

Ah OK. Ich weiß, dass Sybase SQL Server - für immer - nur unterstützt NUMERICS und ich dachte, dass SQL Server älter als 6.5 geerbt diese Einschränkung –

+0

Ich glaube, sie verwendeten SQL Server 2000 von Anfang an, obwohl ich mir nicht 100% sicher bin. Ich werde das aber nochmal überprüfen. –

6

Floats haben eine interessante Eigenschaft: Es ist immer möglich, einen Wert zwischen zwei anderen einzufügen, außer für den pathologischen Fall, in dem Ihnen die Bits ausgehen. Es hat den Nachteil, dass Repräsentationsprobleme Sie davon abhalten können, mit dem Schlüssel auf eine Zeile zu verweisen. Es ist schwierig, zwei Gleitkommawerte gleich zu machen.

+2

Wenn Sie diese Eigenschaften haben möchten, würde ich denken, dass Sie grundsätzlich eine indexierte Spalte hinzufügen können, die zusätzlich zum Primärschlüssel den Float enthält. –

+0

Das war mein erster Gedanke, aber ich kann keine solche finden, sie sind alle sequentiell 3.0, 4.0, 5.0 usw. vielleicht war dies eine Art Zukunftssicherheit, obwohl ich mir nicht ganz sicher bin, warum sie so scheinen IDs sein. Danke für deinen Beitrag. –

+2

Es klingt nicht so, als ob dies die richtige Antwort für den speziellen Fall des Fragestellers wäre ... aber Sie werden trotzdem dafür gewählt, dass Sie eine interessante und mögliche Antwort für die nächste Person haben, die nach dieser Frage sucht. – Beska

8

Ich arbeitete mit jemandem, der Floats als PKs in SQL Server-Datenbanken verwendet. Er war besorgt, dass ihm die Zahlen für die Identifikatoren ausgehen würden, wenn er bei INTs bleiben würde. (32 Bit auf SQL Server.) Er schaute sich nur den Bereich des Floats an und dachte nicht darüber nach, dass bei größeren Zahlen der eine Platz wegen der begrenzten Genauigkeit nicht in der Zahl enthalten ist. Also würde sein Code, um MAX (PK) + 1.0 zu nehmen, irgendwann eine Zahl gleich MAX (PK) zurückgeben. Nicht gut. Ich überzeugte ihn schließlich, float nicht für Ersatz-Primärschlüssel für zukünftige Datenbanken zu verwenden. Er hörte auf, bevor er die DB reparierte, an der er arbeitete.

Um Ihre Frage zu beantworten, "Also ich denke, was ich frage, ist, wer diese ziemlich umfangreiche Datenbank entworfen hat, weiß etwas, was ich nicht weiß?" Höchstwahrscheinlich NEIN! Zumindest nicht in Bezug auf die Auswahl von Datentypen.

+1

Die Nummer, wo Sie beginnen, auf das Problem PK + 1.0 = PK zu stoßen ist 9007199254740992. Bei 1000000 neue PK pro Sekunde dauert es 285 Jahre, um in diese Nummer zu laufen. Ich denke nicht, dass dies ein Punkt ist, um den es sich zu kümmern lohnt. Auf der anderen Seite, mit nur 100 pro Sekunde, können Sie in weniger als einem Jahr keinen signierten Int. –

1

Ich arbeite seit ein paar Jahren mit der Cerner Millenium Datenbank (unter der Decke benutzt es Oracle). Anfangs war ich sehr überrascht zu sehen, dass Floats für IDs auf Tischen verwendet wurden. Dann stieß ich auf eine ID in unserer Datenbank> 2^32 und eine Abfrage, die ich schrieb, gab die falschen Ergebnisse, weil ich es falsch zu einem INT umgewandelt hatte, erkannte ich, warum sie es taten.Ich finde keines der oben genannten Argumente gegen die Verwendung von Floats, die in der realen Welt überzeugend sind, wo für Schlüssel nur Nummern nur "etwas größer" als 2^32 benötigt werden und der Wert der ID immer die Form #### hat. ##. 0. (Niemand spricht über eine ID der Form ######. ######.) Jetzt, da wir diese Daten in ein SQL Server-Warehouse importieren und bigint verfügbar ist, werden wir jetzt gehen mit bigint statt float.

1

FYI-- gibt es eine andere Art und Weise, dies zu betrachten:

Ich arbeite in Echtzeit-Prozesskontrolle und als solche, die meisten meiner Zeileneinträge sind zeitbasiert und werden durch nicht automatisch bei hohen Geschwindigkeiten erzeugt -ASCII-Maschinen. Zeit - das ist, wonach meine Benutzer normalerweise suchen, und viele meiner "Benutzer" sind tatsächlich selbst Maschinen. Daher UTC-basierte Primärschlüssel.

Verwandte Themen