2008-10-03 11 views
8

Hallo Ich möchte zwei Tabellen haben jeweils eine INT "id" -Spalte, die automatisch inkrementieren, aber ich will nicht, dass beide "ID" Spalten die gleiche Nummer teilen. Wie heißt das und was ist der beste Weg? Sequenz? Iterator? Index? Incrementor?Share-inkrementierten Primärschlüssel zwischen zwei Tabellen

Motivation: Wir migrieren von einem Schema zu einem anderen und haben eine Webseite, die beide Tabellen liest und zeigt die (int) ID, aber ich kann nicht die gleiche ID für beide Tabellen verwendet haben.

Ich benutze SQL Server 9.0.3068.

Danke!

+0

Können Sie hinzufügen, warum das bitte erforderlich wäre? Möglicherweise gibt es ein besseres Design, das die Verwendung von GUIDs nicht erfordert. –

Antwort

14

Konfigurieren Sie einfach das Identitätsinkrement auf> 1, z. Tabelle 1 verwendet IDENTITY (1, 10) [1,11,21 ...] und Tabelle 2 verwendet IDENTITY (2, 10) [2,12,22 ...]. Dies gibt Ihnen auch später noch Raum für Erweiterungen.

+0

Wie genau mache ich das? Gibt es das irgendwie mit PHPMyadmin? – everconfusedGuy

+0

Verwenden Sie auch eine Bigint, wenn Sie dies tun. –

3

Ich denke, mit einer GUID wäre der einfachste Weg, wenn ich dich richtig verstehe.

SELECT NEWID() 
+0

Entschuldigung, ich hätte erwähnen sollen, dass es ein int sein muss. – user24881

2

Verwenden einer Säule mit GUID (Globally Unique Identifier) ​​einzugeben. Es ist 16 Byte und wird immer für jede Zeile eindeutig sein.

Beachten Sie, dass Sie im Vergleich zu normalen Integer-Schlüsseln einen signifikanten Leistungseinbruch erhalten.

1

Verwenden Sie eine andere Tabelle mit einem ID-Schlüssel vom Typ int standardmäßig auf 1, genannt KeyID oder was auch immer.

Lassen Sie eine gespeicherte Prozedur den Wert abrufen, fügen Sie 1 hinzu, aktualisieren Sie dann die KeyID und geben Sie diese dann an die gespeicherte Prozedur zurück, die Ihre zwei Tabellen aktualisiert, die den neuen eindeutigen Schlüssel benötigen.

Dadurch wird sichergestellt, dass die ID ein int ist, und dass es zwischen den Tabellen, die die gespeicherte Prozedur verwenden, um neue IDs zu generieren, eindeutig ist.

0

Ich weiß nicht, wie Sie es nennen würden.

Wenn Sie keine GUID oder eine separate Tabelle verwenden möchten, können Sie auch eine Funktion erstellen, die sich die Maximalwerte der IDs aus beiden Tabellen anschaut und eine dem Wert (oder etwas ähnlichem) hinzufügt. .

Sie könnten diese Funktion dann in einem Insert-Trigger für beide Tabellen aufrufen.

0

Ich persönlich bin ein Fan der GUID-Lösung, aber hier ist eine praktikable Option.

Viele Lösungen für dieses Problem haben GUID vermieden und gute alte Ganzzahl verwendet. Dies ist auch bei Mergereplikationssituationen üblich, bei denen viele Satellitenstandorte mit einem Master zusammengeführt werden und Schlüsselkonflikte vermieden werden müssen.

Wenn GUID für Sie nicht funktioniert, und Sie unbedingt Int, Bigint oder dergleichen haben müssen, können Sie immer nur eine IDENTITY-Spalte verwenden und jede Tabelle mit einem anderen Wert für SEED haben. Diese Datentypen haben einen sehr großen Bereich, und es ist nicht schwer, den Bereich in nutzbare Segmente aufzuteilen, besonders wenn Sie nur zwei Splits haben wollen. Als Beispiel hat basic int einen Bereich von -2^31 (-2.147.483.648) bis 2^31-1 (2.147.483.647). Das ist mehr als genug für eine Kundentabelle zum Beispiel.

Transact-SQL-Referenz (SQL Server 2000) int, bigint, smallint, and tinyint

Beispiel:

--Create table with a seed of 1 billion and an increment of 1 
CREATE TABLE myTable 
(
primaryKey int IDENTITY (1000000000, 1), 
columnOne varchar(10) NOT NULL 
) 
1

Sie können eine Identity-Spalte in einer dritten Tabelle definieren, verwenden die ID-Werte zu generieren, aber Sie Ziehen Sie alle von Ihnen erstellten Einfügungen immer in die Tabelle zurück (damit sie nicht wachsen). Durch das Zurücksetzen der Transaktion wird die Tatsache, dass die ID generiert wurde, nicht zurückgesetzt.

Ich bin kein normaler Benutzer von Microsoft SQL Server, also bitte verzeihen Sie alle Syntaxfehler. Aber so etwas wie das folgende ist, was ich im Sinn haben:

CREATE TABLE AlwaysRollback (
    id IDENTITY(1,1) 
); 

BEGIN TRANSACTION; 
INSERT INTO AllwaysRollBack() VALUES(); 
ROLLBACK TRANSACTION; 

INSERT INTO RealTable1 (id, ...) VALUES (SCOPE_IDENTITY(), ...); 

BEGIN TRANSACTION; 
INSERT INTO AllwaysRollBack() VALUES(); 
ROLLBACK TRANSACTION; 

INSERT INTO RealTable2 (id, ...) VALUES (SCOPE_IDENTITY(), ...); 
0

Wenn Sie wirklich diese mit einem int tun müssen, und Sie haben eine automatische Inkrementierung Nummer, die Art, wie ich zuvor getan haben, ist das ID-Feld zu ändern Auto-Inkrement-Funktion auf die Reihenfolge der anderen Tabelle. Ich bin nicht sicher, in MS SQL oder My SQL, aber in pgsql das bedeutet, dass in dem SQL Sie dieses Feld

id integer NOT NULL DEFAULT nextval('table_two_seq'::regclass), 

wo table_two_sequence ist die Sequenzfunktion für die andere Tabelle haben würde. Testen Sie es dann, indem Sie einige Daten einfügen. Es tut mir wirklich leid, wenn das nicht funktioniert in ms sql ich versuche, es tbh zu vermeiden. Andernfalls ist die GUID der beste Weg, wie von anderen erwähnt wurde. Oder wenn Sie in den Code einfügen, den Sie verwenden, könnten Sie einen Algorithmus in das einfügen, aber es könnte unordentlich werden.

Alternativ, denken Sie darüber nach, die Daten in einer Tabelle zu haben, da dies ein Weg wäre. Wenn Sie möchten, können Sie eine Ansicht haben, die zwei Tabellen simuliert. Nur ein Gedanke.

Hoffnung i geholfen haben

0

mit SQL Server 2012 starten können Sie eine Sequenzobjekt https://msdn.microsoft.com/en-us/library/ff878091.aspx erklären was genau das ist, was Sie brauchen.

soll ich ziemlich trivial sein, ein Sequenzobjekt mit einer Tabelle zu emulieren den nächsten Sequenzwert und eine gespeicherten Prozedur atomar wählen den Wert und das Schrittweite enthält. [Sie möchten Funktion verwenden, aber Funktionen können keine Nebenwirkungen haben.]

Wie wäre es mit diesem Hack? Erstellen Sie eine Tabelle (MySequence) mit zwei Spalten: Und Identity-Spalte (SequenceValue) und einer Dummy-Spalte (DummyValue) und verwenden Sie diese gespeicherte Prozedur, um einen neuen Sequenzwert zu erhalten. Die einzige Zeile in der Tabelle wird der letzte abgerufene Sequenzwert sein.

Um die Reihenfolge zu verwenden, müssten Sie die Einfügungen zu den Zieltabellen verwalten - ein Trigger würde wahrscheinlich funktionieren.

Verwandte Themen