Utilisez-vous déjà une table séparée pour "générer" clés primaires artificielles pour DB (et pourquoi)? Ce que je veux dire, c'est avoir une table avec deux colonnes, nom de table et identifiant actuel - avec lequel vous pouvez obtenir une nouvelle "ID" pour une table en verrouillant simplement la ligne avec ce nom de table, obtenant la valeur actuelle de la clé, incrémenter par un, et déverrouillez la ligne. Pourquoi préféreriez-vous cela sur une colonne d'identité entière standard? P>
P.s. "L'idée" provient des motifs de fowlers de l'architecture d'applications d'entreprise, BTW ... P>
6 Réponses :
La seule fois où j'ai jamais utilisé cela, c'est quand j'avais une application à Btrieve, et il n'avait pas une colonne d'identité. Et je devrais aussi dire quand ils ont essayé d'utiliser cette table, cela a entraîné une ralentissement massive lorsqu'ils ont essayé d'importer des données, à cause de toutes les lectures supplémentaires et écrites. Mon ami l'a regardé et réécrit comment ils l'ont fait pour accélérer, mais la morale de l'histoire est que si vous faites quelque chose comme cela de manière incorrecte, il peut y avoir des conséquences brutales. p>
Personnellement, je ne pense pas que je voudrais jamais faire cela. Il y a trop de possibilité d'erreur. Deux personnes essaient d'utiliser la même clé, car elles ont oublié de verrouiller la table avant de saisir l'identifiant. Cela semble juste être quelque chose qui devrait être laissé à la SGBDM si possible. Comme aura-t-il été élevé, il est facile de minimiser cette situation, mais si vous ne savez pas ce que vous faites, cela peut arriver. P>
Si vous avez une fonction d'obtenir l'identifiant et de l'incrémentation de la valeur dans ce tableau à l'aide d'une transaction avec un niveau d'isolation de la ligne, de telles situations deviendront presque impossibles.
@Will - Oui ... Si B> Vous le faites bien, et il est facile de vous tromper. Et cela crée un point de contention dans l'application qui peut blesser la performance.
Chaque fois que vous pouvez utiliser les fonctionnalités de l'identité ou du guid de SQL Server, vous devez. Cependant, il y a quelques situations où cela peut ne pas être possible. P>
Un exemple est que SQL Server n'autorise qu'une colonne d'identité par table. Rarement, une table aura des enregistrements qui ont besoin d'une pièce d'identité privée et d'une pièce d'identité publique, et une limite d'un moyen de colonne d'identité générant les deux entiers peut être une douleur. Vous pouvez toujours utiliser un GUID pour un, mais vous voulez que l'intégrité de l'ID privée de la vitesse et que vous souhaitiez également que l'ID du public soit plus lisible à l'homme qu'un GUID. P>
Dans cette situation, une table supplémentaire pour générer les ID peut avoir un sens. Cependant, je le ferais un peu différemment. Dont toujours deux colonnes dans la table, mais faites une table "ombre" ou "mappage d'identifiant" pour chaque table réelle. L'une des colonnes sera votre identifiant privé (contrainte unique) et une identité de votre public (identité avec peut-être une valeur d'incrément de '7' ou «13» ou autre nombre moins évident que «1 '). P >
La différence clé ici est que vous ne voulez pas faire le verrouillage vous-même. Laissez SQL Server la gérer. P>
Ceci s'appelle l'affectation HI / LO. P>
Vous feriez cela ayant soit une gâchette sur INSERT sur vos tables pour obtenir l'identifiant de cette table et l'incrémentation avant ou après avoir reçu votre identifiant, en fonction de votre choix. P>
Ceci est couramment utilisé lorsque vous devez gérer plusieurs moteurs de base de données. L'identifiant autocramental à Oracle passe par une séquence, que vous incrémentez avec la séquence.NextValue à partir d'un déclencheur avant l'insertion sur votre table de données. P>
Server de manière opposée, SQL Server dispose de colonnes d'identité, d'autocramentating de manière native et ceci est géré par le DBE lui-même. P>
Pour que votre logiciel fonctionne sur les deux DBE, vous devez venir à une sorte de standard, puis la "norme" la plus courante utilisée pour ceci est l'affectation HI / LO à la clé primaire. P>
C'est une approche entre d'autres. Ces jours-ci, avec des outils de mappage ORM tels que NHibernate, il est proposé par la configuration afin de pouvoir avoir besoin de moins pour vous soucier de l'application et des côtés de la base de données. P>
edit # 1 fort> p>
Parce que ce type de manœuvre ne peut pas être utilisé pour une portée globale, vous devez avoir une telle table par base de données ou schéma de base de données. De cette façon, chaque schéma est indéniable de l'autre. Cependant, les données d'un schéma ne peuvent pas être déplacées implicitement vers une autre avec la même clé, car elles seraient peut-être en conflit avec une rangée déjà existante. P>
Quant à un schéma de sécurité, il accède à la même base de données qu'un autre schéma ou utilisateur, aucune table supplémentaire ne devrait exister pour un schéma de sécurité spécifique. P>
Le manque d'incrément automatique natif est ma plainte la plus importante concernant Oracle.
Travailler avec des séquences Oracle peut être amusant aussi! =) C'est différent seulement, mais sert exactement le même objectif. Mais je suis d'accord, quand je suis d'abord dirigé vers Oracle il y a deux ans, il m'a fallu un peu de temps pour s'habituer à cela et à d'autres caractéristiques différentes. Cependant, PL / SQL offre de nombreuses fonctionnalités intéressantes que TSQL préférerait à prendre. Donc, les deux ont des faiblesses et des points forts. =)
Wow ne connaissait jamais l'affectation Hi / Lo .... Belle explication apprise quelque chose de nouveau. Merci :-)
+1 J'ai utilisé cela moi-même et oui, il faut soutenir 4 SGBD différents, bien fait :)
Merci pour tous les super commentaires! Je suis content de voir que je nous ai apporté quelque chose à tous, la communauté de la fois. =)
@Joel Coehoorn: Les champs auto-incréments natifs dans Oracle sont des séquences. =)
J'ai vu ce modèle utilisé lorsque des données créées dans une base de données doivent être migrées, sauvegardées, groupées ou mises en scène vers une autre base de données. Dans cette situation, vous souhaitez d'abord vous assurer que les clés principales n'auront pas besoin de changer. Deuxièmement les clés étrangères. Troisièmement, des clés externes exposées ou des références durables. P>
Vous ne le préféreriez pas du tout. P>
Quoi que vous gagnez à l'aide du motif ou de devenir dB agnostique, vous perdrez dans des maux de tête, du support et des performances. P>
Verrouillage de la ligne avec ce nom de table, Obtenir la valeur actuelle de la clé, incrémenter par un et déverrouillez le ligne p>
Cela semble simple, n'est-ce pas? P>
UPDATE TableOfId SET Id += 1 OUTPUT Inserted.Id WHERE Name = @Name;