Choix du type clé primaire

voix
0

J'ai une table qui potentiellement aura nombre d'inserts par seconde, et je suis en train de choisir un type de clé primaire que je veux utiliser. À titre d'exemple disons, c'est la table des utilisateurs. Je suis en train de choisir entre l'utilisation de GUID et BIGINT comme clé primaire et, finalement, comme UserID à travers l'application. Si j'utilise GUID, je sauve un voyage à la base de données pour générer un nouvel ID, mais GUID n'est pas « convivial » et il est impossible de la table de partition par cet ID (qui je prévois de le faire). Utilisation BIGINT est beaucoup plus pratique, mais la génération est un problème - je ne peux pas utiliser l'identité (il y a une raison vient que), donc mon seul choix est d'avoir une table d'assistance qui contiendrait la dernière ID utilisé et puis j'appeler ce proc stocké:

create proc GetNewID @ID BIGINT OUTPUT
as
begin
update HelperIDTable set @ID=id, id = id + 1 
end

pour obtenir le nouvel identifiant. Mais ce tableau d'aide est un goulot d'étranglement évident et je suis préoccupé par le nombre de mises à jour par seconde, il peut le faire.

Je aime vraiment l'idée d'utiliser BIGINT comme pk, mais le problème de goulot d'étranglement me concerne - est-il possible d'estimer à peu près le nombre de numéros d'identification, il pourrait produire par seconde? Je me rends compte que cela dépend fortement du matériel, mais qu'il y a des limites physiques et quel degré regardons-nous? 100 s / s? 1000 de / s?

Toutes les idées sur la façon d'aborder le problème sont très appréciés! Ce problème ne me laisse pas dormir la nuit pour beaucoup maintenant!

Merci! Andrey

Créé 26/08/2009 à 22:16
source utilisateur
Dans d'autres langues...                            


5 réponses

voix
2

GUID semble être un choix naturel - et si vous devez vraiment, on pourrait dire probablement l'utiliser pour la clé principale de la table - la valeur unique qui identifie de manière unique la ligne dans la base de données.

Ce que je recommande fortement de ne pas faire est d'utiliser la colonne GUID comme la clé de cluster qui SQL Server fait par défaut, à moins que vous dire spécifiquement pas.

Comme Kimberly Tripp - la reine d'indexation - et d' autres ont déclaré un grand nombre de fois - un GUID comme la clé de cluster n'est pas optimale, car en raison de son caractère aléatoire, cela conduira à la page massive et la fragmentation des index et des performances généralement mauvais.

Oui, je sais - il y a newsequentialid()dans SQL Server 2005 et jusqu'à - mais même ce n'est pas vraiment et entièrement séquentielle subit donc aussi des mêmes problèmes que le GUID - juste un peu moins occupe une place prépondérante.

Ensuite, il y a une autre question à considérer: la clé de cluster sur une table sera ajoutée à chaque entrée sur chaque index non cluster sur votre table et - donc vous voulez vraiment vous assurer qu'il est aussi petit que possible. En règle générale, une INT à partir de 2 milliards de lignes devrait être suffisant pour la grande majorité des tables - et par rapport à un GUID comme la clé de cluster, vous pouvez vous sauver des centaines de méga-octets de stockage sur disque et en mémoire du serveur.

Donc , pour résumer: à moins que vous avez une très bonne raison, je recommande toujours un INT IDENTITYdomaine comme la clé primaire / cluster sur votre table.

Marc

Créé 26/08/2009 à 22:28
source utilisateur

voix
1

Voulez - vous une clé primaire, pour des raisons d'affaires, ou une clé clustred, pour des raisons de stockage? Voir stackoverflow.com/questions/1151625/int-vs-unique-identifier-for-id-field-in-database pour un poste plus élaboré sur le thème de PK vs clé en cluster.

Il faut vraiment préciser pourquoi ne pas utiliser l' identité. Génération des ID manuellement, et spécialement sur le serveur avec un rountrip supplémentaire et une mise à jour juste pour générer chaque ID pour l'insert il ne sera pas l' échelle. Vous seriez chanceux d'atteindre 100s inférieurs par seconde. Le problème est non seulement le temps de rountrip et mettre à jour, mais surtout de l'interaction de mise à jour de génération ID avec insert batching: la transaction batching insertion sérialise génération d'identité. Le woraround est de séparer la génération d'ID de session séparée de sorte qu'il peut autocommit, mais le dosage d'insertion est inutile parce que le genartion ID n'est pas en lots: il doit attendre au ras du journal après chaque ID genrated afin de commettre. Par rapport à cette UUID sera en cours d' exécution des cercles autour de votre génération manuelle d'identité. Mais UUID sont le choix horrible pour clé clustred en raison de la fragmentation.

Créé 26/08/2009 à 22:32
source utilisateur

voix
1

J'essaie d'utiliser GUID pour toutes les tables PKs sauf petites tables de consultation. Le concept GUID assure que l'identité de l'objet peut être créé en toute sécurité memeory sans aller-retour à la base de données et l'enregistrement plus tard sans changer l'identité.

Lorsque vous avez besoin d'un identifiant « lisible », vous pouvez utiliser un incrément automatique int lors de l'enregistrement. Pour vous partitionner pouvez aussi créer les bigints plus tard par un programme de base de données pour de nombreux utilisateurs en un seul coup.

Créé 26/08/2009 à 22:26
source utilisateur

voix
0

Une idée qui nécessite des tests sérieux: essayez de créer (insérer) de nouvelles lignes par lots - dire 1000 fois (10 000 1M?). Vous pourriez avoir un maître (goulot d'étranglement aka) tableau répertoriant la suivante à utiliser, ou vous pourriez avoir une requête qui fait quelque chose comme

 select min(id) where (name = '')

Générer un nouveau lot de lignes Emtpy le matin, toutes les heures, ou chaque fois que vous êtes en bas à un certain nombre de gratuites. Ce ne porte que sur la question de la création de nouveaux identifiants, mais si c'est le principal goulot d'étranglement, il pourrait aider.

Une option de partitionnement de table: En supposant une colonne ID bigint, comment vous définissez la partition? Si vous autorisez pour les lignes 1G par jour, vous pouvez configurer la nouvelle partition dans la soirée (day1 = 1000000000 par 1999999999, day2 = 2000000000 par 2999999999, etc.), puis échanger quand il est prêt. Vous bien sûr limité à 1000 partitions, donc avec bigints vous manquez de partitions avant de manquer d'ID.

Créé 26/08/2009 à 23:05
source utilisateur

voix
0

essayez de frapper votre base de données avec un script, peut-être avec l'utilisation de jmeter pour simuler hits concurrents. Peut-être que vous pouvez juste vous mesurer à quel point la charge que vous pouvez manipuler. De plus, votre DB pourrait provoquer un goulot de bouteille. Laquelle est-ce? Je prefure PostgreSQL pour une charge lourde, comme Yahoo et skype font aussi

Créé 26/08/2009 à 22:24
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more