Wie speichere ich am besten eine Liste von Zahlen in einer relationalen Datenbank?

8

Ich möchte eine Liste von Zahlen speichern (im Wesentlichen eine Menge in mathematischen Begriffen) in a relationale Datenbank, insbesondere SQL Server 2005.

Idealerweise möchte ich, dass es eine einzelne Spalte an einem gegebenen Tisch ist, aber ich bin bereit, irgendeine Art von Lösung zu hören. Die Daten, die ich speichern muss, sind, wie gesagt, eine Menge von Zahlen.

  • Es ist nicht erforderlich, dass es sequenziell ist (d. h. Lücken sind in Ordnung, normal und typisch)
  • Bereiche sind möglich (z. B. 1 - 4), aber während ich es so anzeigen möchte, ist es ok, Verknüpfungen zu verwenden und sie zu speichern
  • Es kann auch "all" sein, also muss mindestens ein Wert, vorzugsweise logisch, für diesen "unendlichen" Fall reserviert werden
  • Die Liste der Zahlen muss nicht in Ordnung sein (dh 3, 2, 9, 5), aber es ist vorzuziehen und vollkommen vernünftig, dass sie vor dem Einfügen sortiert werden und sortiert werden können, da nur Code das Einfügen durchführt, nicht manuell Benutzer. Trotzdem sollte es sich wahrscheinlich nicht darauf verlassen oder erwarten, dass die Liste bereits sortiert ist.
  • Die Menge der Zahlen sollte leicht für eine Teilmenge durchsuchbar sein (siehe unten)
  • Alle Zahlen sollten eindeutig sein (keine Duplikate), aber dies kann und wird vor dem Einfügen erzwungen

Diese Spalte soll alle "Schrittnummern" eines bestimmten Prozesses speichern, auf den sich die Zeile bezieht. Jede Zeile kann daher auf einen oder mehrere Schritte in beliebiger Reihenfolge, Reihenfolge oder Reihenfolge angewendet werden. Die maximale Anzahl der möglichen Schritte (der maximale Bereich im Wesentlichen) unterscheidet sich von Zeile zu Zeile, obwohl ich sehr bezweifle, dass einer von ihnen in die Hunderte gelangt, so dass in 99,9% der Fälle niemals der Höchstwert 20 oder 30 und I überschreiten sollte Würde mich wundern, wenn es irgendwo nahe bei 100 kommt. Jede Zeile hat garantiert mindestens einen Wert (Schritt) (dh es macht keinen Sinn, eine Zeile zu haben, die für keinen Schritt gilt), aber ich Das ist so einfach wie das Setzen der Spalte auf not null .

Wie auch immer es gespeichert wird, ich möchte, dass es leicht durchsucht wird. Zum Beispiel würde ich lieber nicht durch viele Schleifen springen müssen, um eine SQL-Abfrage zu schreiben, um zum Beispiel alle Zeilen zu finden, die für "Schritt 3" gelten. Wenn eine gegebene Zeile mehrere Schritte hat (z. B. 2, 3, 7 und 8), sollte es nicht zu schwierig sein, sie bei der Suche nach Schritt 3 zu finden.

Auch wenn ich möchte, dass es einen logischen Sinn ergibt, wenn ich die Rohdaten betrachte (für jeden, der an dem System arbeiten muss, nachdem ich nicht in der Nähe bin, um zu fragen, und deshalb nicht lesen muss dicke Dokumentation, um meine obskure Kodierung herauszufinden), ich bin bereit, hier Kompromisse einzugehen. Das Codieren der Liste in etwas, das zuverlässig decodiert werden kann, ist somit akzeptabel.

Ich entschuldige mich, wenn das ein Betrogener ist - ich habe gegoogelt, aber ich vermute, dass mein Problem darunter leidet, dass ich nicht weiß, wonach ich suchen oder wie ich es formulieren soll, um das zu finden, wonach ich suche.

In einer weiteren Anmerkung frage ich mich, ob dies nicht einer der Bereiche ist, in denen relationale Datenbanken nicht ausreichen. Leider habe ich hier keine Wahl. Ich muss es in SQL Server speichern. Das separate Speichern in einer Datei oder einem anderen persistenten Datenspeicher kommt für mich leider nicht in Frage.

    
Sean Hanley 06.07.2009, 15:02
quelle

7 Antworten

1

Beendet mit einer Lösung einer ähnlichen Frage .

Trotzdem trotzdem! Ich genieße es, alle Meinungen zu diesen esoterischen Bereichen des Datenbankdesigns zu lesen.

    
Sean Hanley 10.09.2009, 19:42
quelle
4

Ich kann mich nicht an die korrekte Terminologie dafür erinnern, aber die korrekte Vorgehensweise wäre, eine Tabelle wie die folgende zu erstellen:

%Vor%

Für jeden Wert in Tabelle1 fügen Sie die erforderlichen Werte in diese Tabelle ein.

Für 'all' können Sie eine Spalte in table1 erstellen, die ein Flag ist, das Sie setzen können, wenn Sie alle möchten. (Ich verwende 'enum' in MySql, aber ich bin mir nicht sicher, ob dies in SQL Server existiert).

Ich bin nicht sicher, ob es eine bestimmte Sql Server-Methode gibt, da ich hauptsächlich MySql verwende.

    
MitMaro 06.07.2009 15:17
quelle
2

Und warum sind zusätzliche Tabellenschritte (processID JOIN, Schritt INT) keine Option? Ich bin mir ziemlich sicher, dass es am einfachsten zu pflegen / zu programmieren wäre.

%Vor%

Entschuldige mein SQL, aber es ist eine Weile her :)

EDIT: UNIQUE(processID, step) wäre empfehlenswert.

    
Wojciech Bederski 06.07.2009 15:14
quelle
1

Ich würde einen einfachen und kanonischen relationalen Entwurf verwenden: CREATE TABLE-Bereiche (prozess_id int, num_low int, num_hi int). Letztere geben den Bereich an. Unabhängiger Index für jede Spalte. Für "spezielle" Unendlichkeitswerte verwenden Sie einfach maxints oder zusätzliche boolesche Spalten.

Vorteile: einfache Suche, ob eine bestimmte Zahl in Reichweite ist oder ob sich Bereiche schneiden. Einfache Wartung. Allgemeine Verständlichkeit und Einfachheit.

Nachteile: eine gewisse Logik wird benötigt, wenn der Satz modifiziert wird, d. h. es wird geprüft, ob sich der neu eingefügte oder modifizierte Bereich überschneidet. Spleißbereiche sind möglicherweise erforderlich.

    
ttarchala 06.07.2009 15:15
quelle
1

Die Antwort unten, um eine Untertabelle (MitMaro) zu machen, ist der "Standard" Weg.

Wenn Sie eine Reihe von Zahlen in eine Spalte oder eine Tabelle einfügen müssen, ist die einzige Möglichkeit, bitweise Operationen zum Speichern der Menge zu verwenden, und Sie können bitweise Operationen in Ihren Datenabfragen verwenden, um nach bestimmten gesetzten Bits zu suchen . Die schnelle Google-Suche zeigt an, dass MSSQL 2005 dies unterstützt, aber nur bis zu 32-Bit-Int. Wenn Sie also 32 Schritte durchlaufen, werden Sie auf Probleme stoßen.

Alles in allem ist die Untertabelle der Standard, der für etwas verständlichere Abfragen gegen die Tabelle (n) sorgen würde. Dies ist auch der sicherste, um zukünftige Fälle zu unterstützen, in denen Sie mehr als 32 Wertkarten verwenden würden.

    
Jeffrey Shackelford 06.07.2009 15:40
quelle
1

Wenn Sie nicht mit SQL Server verbunden sind, hat Postgresql eine große Unterstützung für diese Art von Dingen über eine Array . Sie haben sogar einen besonderen Wert für die Unendlichkeit.

Wenn Sie mit SQL Server verbunden sind, ist MitMaro am besten.

    
rfusca 06.07.2009 15:57
quelle
1
%Vor%

Lassen Sie mich eine magische Zahl (-1 oder 999999999) für "alle" annehmen.

Dies ist sehr leistungsfähig sowohl für die Abfrage pro Satz als auch für die Aktualisierung der Einfügung über den Nonclustered-Index. Die Eindeutigkeit erzwingt keine Wiederholung von Einträgen. Es ist problematisch, entweder "alle" oder auch mehrere Mengenmitglieder als Einschränkung zu erzwingen, aber es gibt abnehmende Renditen, obwohl es in einem Trigger durchgeführt werden könnte.

Zusätzlich hinzufügen

%Vor%

, um effiziente Reverse-Lookup-Abfragen zu ermöglichen.

Wenn Sie Array-Typen verwenden, können Sie möglicherweise keine effiziente Reverse-Suche implementieren.

Beachten Sie, dass das obige SQL ANSI-konform ist.

    
Jason Zavaglia 06.07.2009 16:32
quelle

Tags und Links