2010-02-18 7 views
2

J'ai une table et je discute entre 2 façons différentes de stocker des informations. Il a une structure telle sortePerformance - Int vs Char (3)

int id

int FK_id

varchar (50) info1

varchar (50) info2

varchar (50) info3

int pourTable ou char (3) fortable

L'FK_id peut être une clé étrangère à l'un des 6 tables, donc je besoin d'un autre champ pour déterminer quelle table il est pour.

Je vois deux solutions:

  • Un entier qui est un FK à une table de paramètres qui a sa valeur réelle.
  • Un champ char (3) avec une version abrégée de la table.

Je me demande si quelqu'un sait si on sera vitesse plus bénéfique sage sur l'autre ou s'il y aura des problèmes majeurs à l'aide du charbon (3)

Note: je vais créerez un indexé vue sur chacune des 6 valeurs différentes pour ce champ. Cette table contiendra ~ 30k lignes et devra être jointe avec des tables beaucoup plus grandes

+0

Que signifie la première ligne de votre définition de table? ** int id int FK_id varchar (50) ** –

+0

Donc la valeur FK peut être un PK de 1 des 6 autres tables? –

+0

@KM cela signifie que l'éditeur m'a eu. Le fixe maintenant. @iKnowKungFoo Correct.C'est parce que c'est la même information dans chaque table mais je dois pouvoir accéder à n'importe lequel d'entre eux sans devoir réunir chacune des 6 tables. – corymathews

Répondre

3

Dans ce cas, il n'a probablement pas d'importance, sauf pour les frais généraux de classement (A vs a vs ä va à)

j'utiliser char (3), par exemple pour le code de monnaie comme CHF, GBP, etc. Mais si ma clé naturelle était "Swiss Franc", "British Pound", etc, je prendrais le numérique.

3 octets + collation contre 4 octets numériques? Vous auriez besoin d'un zillion lignes ou d'un pays de taille moyenne avant que cela ne compte ...

1

Avez-vous envisagé d'utiliser un TinyInt. Ne prend qu'un octet pour stocker sa valeur. TinyInt a une plage de valeurs comprise entre 0 et 255.

+0

Sans regarder spécifiquement les données, comment saurais-je quel numéro va avec quelle table? Surtout un mois ou deux à partir de maintenant. Y a-t-il aussi beaucoup d'avantages à cela par rapport à un int normal, c'est-à-dire un FK à une table de paramètres qui contiendrait le nom de la table correspondante? – corymathews

+1

Avec seulement ~ 30K lignes, il n'y aurait probablement pas beaucoup de différence. En fait, je doute que vous * notiez * toute différence entre un int, un petit int, un petit int ou un caractère (3). En outre, si vous avez seulement 6 valeurs différentes dans ce tableau, il ne sera probablement pas assez sélectif pour être un bon candidat pour la première colonne d'un index non plus. –

0

Je pense qu'un petit entier (tinyint) est requis ici. Une "version abrégée" ressemble trop à un nombre magique.

Je pense aussi que l'entier devrait battre le char (3).

+0

la version abrégée serait quelque chose comme «ppl» pour les personnes ou similaires. – corymathews

0

Tout d'abord, un Id de 50 caractères qui n'est pas globalement unique semble un peu effrayant. Les ID ont-ils un sens? Sinon, vous pouvez facilement obtenir un GUID dans moins d'espace. Personnellement, je suis un grand fan de rendre les choses lisibles par l'homme autant que possible. Je voudrais, et j'ai, mis le nom complet dans les graphiques jusqu'à ce que je devais faire autrement. Ma préférence serait d'avoir des tables de liaison pour chaque table connexe possible si.À moins que vous ne parliez de très grande échelle, il est préférable de réduire la taille des ID et de prendre quelques caractères de plus pour le nom de la table. Pour une très grande échelle, je diminuerais la taille des identifiants et utiliserais un nombre entier.

Jacob

+0

Désolé jacob l'éditeur (ou moi) a été un peu mélangé en l'écrivant. PK est un champ d'incrémentation automatique entier. Le varchar50 n'était pas censé être sur cette ligne. D'une manière ou d'une autre, ça s'est mal passé et je l'ai raté quand je l'ai lu rapidement. – corymathews

+0

Gotcha. 32 bits contre 100 octets fait une petite différence. Je dirais que d'un point de vue de la vitesse, la comparaison d'entiers est une seule instruction de CPU. La comparaison de chaînes est généralement multiple (au moins une par caractère). Bien qu'ils puissent gérer plus simultanément, je ne suis pas au courant de le faire. – TheJacobTaylor

1

Parce que votre FK ne peut pas être appliquée (car il est une variante selon le type) par la contrainte de base de données, je voudrais envisager de réévaluer votre conception à l'utilisation des tables de lien, où chaque table de liaison comprend deux FK colonnes, une au PK de l'entité et une au PK de l'une des 6 tables.

Bien que cela puisse sembler excessif, cela simplifie énormément de choses et l'ajout de nouvelles tables de liens n'est pas plus complexe que l'adaptation de nouveaux types FK. En outre, il est plus facilement extensible au cas où une entité a besoin de plus d'une relation 1-1 à une seule table, ou a besoin de plusieurs relations 1-1 aux six autres entités.

Dans un scénario variable-FK, vous pouvez perdre la cohérence de la base de données, vous pouvez vous joindre à la mauvaise entité en négligeant de filtrer sur le code de type, etc.

Je dois ajouter qu'un autre avantage énorme de tables de liens est que vous pouvez lier à des tables qui ont des clés de différents types de données (ints, clés naturelles, etc) sans avoir à ajouter des clés de substitution ou stockées dans une clé de varchar ou des solutions de contournement similaires qui sont sujettes à des problèmes.

+0

Ou si vous n'utilisez pas ou ne pouvez pas lier des tables (ce qui est une idée avec laquelle je suis d'accord), vous avez besoin d'un déclencheur pour maintenir l'intégrité des données car vous ne pouvez pas définir un champ comme FK. – HLGEM

2

La raison pour laquelle vous avez besoin d'une table unique est-elle la raison pour laquelle vous voulez vous assurer que lorsque les six tables parent référencent une instance donnée d'une ligne enfant dont la garantie est la même instance? C'est le problème classique des "multi-parents". Un exemple d'où vous pourriez rencontrer ceci est avec des adresses ou des numéros de téléphone avec plusieurs tables de personne/contact.

je peux penser à deux options:

Choix 1: Une table de lien pour chaque table parent. Ce serait l'architecture Hoyle. Donc, quelque chose comme:

Create Table MyTable(
        id int not null Primary Key Clustered 
        , info1 varchar(50) null 
        , info2 varchar(50) null 
        , info3 varchar(50) null 
        ) 

Create Table LinkTable1(
         MyTableId int not null 
         , ParentTable1Id int not null 
         , Constraint PK_LinkTable1 Primary Key Clustered(MyTableId, ParentTable1Id) 
         , Constraint FK_LinkTable1_ParentTable1 
          Foreign Key (MyTableId) 
          References MyTable (Id) 
         , Constraint FK_LinkTable1_ParentTable1 
          Foreign Key (ParentTable1Id) 
          References ParentTable1 (Id) 
         ) 
... 
Create Table LinkTable2...LinkTable3 

Choix 2. Si vous saviez que vous auriez jamais plus dire six tables et étaient prêts à accepter une dénormalisation et un design fugly, vous pouvez ajouter six clés étrangères à votre table principale . Cela évite le problème de remplir un tas de tables de liens et garantit une intégrité référentielle correcte. Cependant, cette conception peut rapidement devenir incontrôlable si le nombre de parents augmente.

Si vous êtes satisfait de votre conception existante, alors en ce qui concerne la taille du champ, j'utiliserais le nom complet de la table. Franchement, la différence de performance entre un char (3) et un varchar (50) ou même un varchar (128) sera négligeable pour la quantité de données que vous êtes susceptible de mettre dans le tableau. Si vous pensiez vraiment que vous alliez avoir des millions de lignes, alors je considérerais fortement l'option de relier des tables. Si vous vouliez rester avec votre conception et que vous vouliez la performance maximale, alors j'utiliserais une tinyint avec une clé étrangère à une table qui contenait la liste des six tables avec une clé primaire tinyint. Cela empêche le nombre d'être "magique" et garantit que vous affinez la liste des tables parent. Bien sûr, cela n'empêche toujours pas les enregistrements orphelins. Dans cette conception, vous devez utiliser des déclencheurs pour le faire.

+0

Pouvez-vous fournir un lien ou plus de détails pour l'architecture "Hoyle" décrite comme un motif? Je ne peux pas trouver une description autre que celle-ci. – StingyJack