2009-07-06 1 views
8

Ich mag eine Liste von Zahlen speichern (im Wesentlichen ein set mathematisch) in einer relationalen Datenbank, speziell SQL Server 2005.Wie speichere ich am besten eine Liste von Zahlen in einer relationalen Datenbank?

, ich würde es am liebsten eine einzige Spalte einer Tabelle sein, 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 (Lücken in Ordnung, normal sind also und typisch) sein sequenziellen erforderlich
  • Bereiche möglich sind (dh 1 - 4), aber während ich möchte es auf diese Weise ich anzuzeigen Es kann auch "all" sein, also muss mindestens ein Wert reserviert sein, vorzugsweise logisch, für diesen "unendlichen" Fall
  • Die Liste der Zahlen muss nicht in sein Reihenfolge (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 manuelle Benutzer. Dennoch sollte es sich wahrscheinlich nicht darauf verlassen oder erwarten, dass die Liste bereits sortiert ist.
  • Der Satz von Zahlen sollten für eine Teilmenge leicht gefunden werden (siehe unten)
  • Alle Zahlen sollten (keine Betrogenen) verschieden sein, aber dies kann und wird vor
  • Insertion erzwungen werden

Diese Spalte gemeint ist um alle "Schrittnummern" eines bestimmten Prozesses zu 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 Abbildung ist so einfach wie das Setzen der Spalte auf not null.

Wie auch immer es gespeichert wird, möchte ich es leicht gesucht werden. 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 bestimmte Zeile mehrere Schritte hat (z. B. 2, 3, 7 und 8), sollte es bei der Suche nach Schritt 3 nicht zu schwierig sein.

Auch wenn ich möchte Es macht einen logischen Sinn, wenn man sich die Rohdaten anschaut (für jeden, der nach der Anfrage an dem System arbeiten muss und keine dicke Dokumentation lesen muss, um meine obskure Codierung herauszufinden), Ich bin dazu bereit, Kompromisse einzugehen. Das Codieren der Liste in etwas, das zuverlässig decodiert werden kann, ist somit akzeptabel.

Ich entschuldige mich, wenn das ein dupe ist — Ich habe herum gegoogelt, aber ich vermute, dass dieses Problem von mir leidet nicht zu wissen, was zu suchen oder wie es zu formulieren oder zu nennen, um zu finden, was ich suche.

Bei 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 nicht in Frage.

Antwort

1

Beendet mit einem solution to a similar question.

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

2

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

SELECT process.name FROM process, steps WHERE process.id = steps.processID AND steps.step = 3; 

Pardon meine SQL, aber es ist schon eine Weile :)

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

1

Ich würde ein einfaches und kanonisches relationales Design 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 überschneiden. Einfache Wartung. Allgemeine Verständlichkeit und Einfachheit.

Nachteile: einige Logik erforderlich, wenn das Set geändert wird, d. H. Überprüft, ob sich neu eingefügt oder geänderter Bereich schneidet. Spleißbereiche sind möglicherweise erforderlich.

+0

Aber die Liste muss nicht (und ist in der Regel nicht) eine schöne einfache Auswahl. Typischerweise sind es eine oder zwei, möglicherweise drei verschiedene Zahlen in keiner bestimmten Reihenfolge (d. H. 3, 5, 9). Nur gelegentlich ist es 1 - 4. –

4

ich die richtige Terminologie für diese nicht mehr erinnern kann, aber der richtigen Weg, dies zu tun, um eine Tabelle wie die erstellen wäre unten: Sie die erforderlichen Werte in

| id | table1_id | value | 
-------------------------------- 
| 0 |   1 |  1 | 
| 1 |   1 |  2 | 
| 2 |   1 |  3 | 
| 3 |   1 |  7 | 
| 4 |   1 |  9 | 
| 5 |   2 |  1 | 
| 6 |   2 |  3 | 
| ... |  ... | ... | 

Für jeden Wert in table1 hinzufügen dieser Tisch.

Für 'alle' können Sie eine Spalte in Tabelle1 erstellen, die Sie festlegen können, wenn Sie alle möchten. (Ich benutze 'enum' in MySql, aber ich bin mir nicht sicher, ob dies in SQL Server existiert).

Ich bin nicht sicher, ob es einige Sql-Server-spezifische Vorgehensweise gibt, da ich hauptsächlich MySql verwende.

+0

Ich erwähnte die Plattform, aber ehrlich gesagt hoffe ich, dass die Antwort generisch genug für jedes vernünftig ausgestattete relationale Datenbanksystem ist. Ich würde mich lieber nicht auf eine Microsoft-basierte Lösung verlassen, aber wenn es ein paar raffinierte Tricks gibt, bin ich dafür. Zum Beispiel verwende ich häufige Tabellenausdrücke sehr oft, und ich bin ziemlich sicher, dass sie eine SQL Server-spezifische Funktion sind. –

1

Die Antwort unten, um eine Untertabelle (MitMaro) zu tun 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, die ich vorstellen kann, bitweise Operationen zum Speichern des Satzes zu verwenden, und Sie können bitweise Operationen in Ihren Datenabfragen verwenden, um nach bestimmten Bits zu suchen einstellen. Die schnelle Google-Suche zeigt an, dass MSSQL 2005 dies unterstützt, aber nur bis zu 32-Bit-Int. Wenn Sie also 32 Schritte überschreiten, treten Probleme auf.

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.

1

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

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

+0

Interessant, dass es das hat. Ich wollte etwas wie einen "Array" -Datentyp. Aber ja, ich bin verpflichtet, zu verwenden, was wir haben --- SQL Server. :) –

1
create table setmember (setid int, setmemberid int) 
create unique nonclustered index idx_setmember_idx1 on setmember (setid, setmemberid) 

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

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

Zusätzlich fügen

create nonclustered index idx_setmember_idx2 on setmember (setmemberid, setid) 

für 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 alle obigen SQL-Anweisungen ANSI-konform sind.