2008-10-03 4 views
8

Salut, je souhaite que deux tables aient chacune une colonne INT "id" qui s'incrémente automatiquement, mais je ne veux pas que les colonnes "id" partagent le même nombre. Comment s'appelle-t-il et quelle est la meilleure façon de le faire? Séquence? Iterator? Indice? Incrementor? Motivation: nous migrons d'un schéma à l'autre et avons une page web qui lit les deux tables et montre l'ID (int), mais je ne peux pas avoir le même ID utilisé pour les deux tables. J'utilise SQL Server 9.0.3068.Clé primaire auto-incrémentée en partage entre deux tables

Merci!

+0

Pouvez-vous ajouter pourquoi cela serait nécessaire s'il vous plaît? Il pourrait y avoir une meilleure conception qui ne nécessiterait pas l'utilisation de GUID. –

Répondre

14

Il suffit de configurer l'incrément d'identité pour être> 1 par ex. la première table utilise IDENTITY (1, 10) [1,11,21 ...] et la deuxième utilise IDENTITY (2, 10) [2,12,22 ...]. Cela vous donnera également de la place pour l'expansion si nécessaire plus tard.

+0

Comment faire exactement cela? Y a-t-il un moyen de le faire en utilisant PHPMyadmin? – everconfusedGuy

+0

Envisagez également d'utiliser un bigint en faisant cela. –

3

Je pense que l'utilisation d'un GUID serait le moyen le plus simple, si je vous ai bien compris.

SELECT NEWID() 
+0

Désolé, je devrais avoir mentionné qu'il doit être un int. – user24881

2

Utilisez une colonne avec le type GUID (Globally Unique Identifier). C'est 16 octets et sera toujours unique pour chaque rangée. Sachez que vous obtiendrez un gain de performance significatif par rapport aux clés entières normales.

1

Utilisez une autre table avec une clé ID de type int par défaut à 1, appelée KeyID ou autre. Avoir une procédure stockée récupérer la valeur, ajouter 1, puis mettre à jour le KeyID, puis renvoyer à la procédure stockée qui met à jour vos deux tables qui a besoin de la nouvelle clé unique

Cela garantira que l'ID est un int, et qu'il est unique entre l'ensemble des tables qui utilisent la procédure stockée pour générer de nouveaux ID.

0

Je ne sais pas comment vous l'appelleriez. Si vous ne souhaitez pas utiliser un GUID ou une table distincte, vous pouvez également créer une fonction qui a examiné les valeurs maximales des ID des deux tables et en a ajouté une à cette valeur (ou quelque chose comme ça) .

Vous pouvez ensuite appeler cette fonction dans un déclencheur d'insertion sur les deux tables.

0

Je suis personnellement un fan de la solution GUID, mais voici une option viable.

De nombreuses solutions à ce problème ont évité GUID et utilisé bon vieux nombre entier. Ceci est courant également avec les situations de réplication de fusion où de nombreux sites satellites fusionnent avec un maître et les conflits de clés doivent être évités.

Si GUID ne fonctionne pas pour vous, et vous devez absolument avoir int, bigint, ou similaire, vous pouvez toujours utiliser une colonne IDENTITY et avoir chaque table avec une valeur différente pour SEED. Ces types de données ont une très large gamme, et il n'est pas trop difficile de diviser la gamme en segments utilisables, surtout si tout ce que vous voulez est deux divisions. À titre d'exemple, int basique a une gamme de -2^31 (-2 147 483 648) à 2^31 - 1 (2 147 483 647). C'est plus que suffisant pour une table client, par exemple.

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

Exemple:

--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

Vous pouvez définir une colonne IDENTITY dans une troisième table, utiliser pour générer des valeurs d'identité, mais vous toujours ramener tous les inserts que vous faites dans la table (pour éviter de le faire pousser). L'annulation de la transaction ne supprime pas le fait que l'ID a été généré. Je ne suis pas un utilisateur régulier de Microsoft SQL Server, donc s'il vous plaît pardonner toute syntaxe gaffes. Mais quelque chose comme ce qui suit est ce que je pense:

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

Si vous avez vraiment besoin de le faire avec un int et vous avez un numéro incrémentiel automatique, la façon dont je l'ai fait avant est de changer le champ id fonction d'incrémentation automatique à la séquence de l'autre table. Je ne suis pas trop sûr en ms sql ou mon sql, mais dans pgsql cela signifie que dans le sql, vous auriez ce champ

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

où table_two_sequence est la fonction de séquence pour l'autre table. Ensuite, testez-le en insérant des données. Je suis vraiment désolé si cela ne marchera pas dans ms sql j'essaie d'éviter tbh. A défaut, le GUID est le meilleur moyen mentionné par d'autres. Ou lors de l'insertion dans le code que vous utilisez, vous pouvez mettre un algorithme dans celui-ci, mais il pourrait être désordonné.

Vous pouvez également envisager d'avoir les données dans une table, car ce serait un moyen de contourner le problème. Si vous en avez besoin, vous pouvez avoir une vue simulant deux tables. Juste une pensée.

espoir que je l'ai aidé

0

A partir de SQL Server 2012, vous pouvez déclarer un objet de séquence https://msdn.microsoft.com/en-us/library/ff878091.aspx qui est exactement ce dont vous avez besoin.

Je devrais être assez trivial pour émuler un objet séquence avec une table contenant la valeur de séquence suivante et une procédure stockée atomiquement sélectionner la valeur et incrémenter. [Vous auriez aimé utiliser la fonction, mais les fonctions ne peuvent pas avoir d'effets secondaires.]

Que diriez-vous de ce hack? Créez une table (MySequence) avec deux colonnes: Et la colonne Identité (SequenceValue) et une colonne factice (DummyValue) et utilisez cette procédure stockée pour obtenir une nouvelle valeur de séquence. La seule ligne de la table sera la dernière valeur de la séquence récupérée. Pour utiliser la séquence, vous devez gérer les insertions dans les tables cibles. Un déclencheur fonctionnerait probablement.

Questions connexes