2009-06-07 8 views
1

J'ai une clé primaire composite, qui ensemble s'avère assez grande (~ 2000 octets). Je n'ai pas de considérations de performances, je voudrais juste une clé primaire pour renforcer l'unicité.Clé primaire MySql> 900/1000 octets?

MySql doesn't like long primary keys. Y a-t-il un moyen de contourner ceci? Peut-être seulement pour imposer l'unicité, sans construire un index?

Je ne voudrais pas utiliser ASCII au lieu de UTF8 juste pour activer une clé primaire (le caractère UTF8 prend 3 octets).

Ma table est définie comme suit:

CREATE TABLE `configuration` (
    `Section` varchar(200) NOT NULL, 
    `StoredKey` VARCHAR(200) NOT NULL, 
    `ServiceName` VARCHAR(300) NOT NULL, 
    `ServiceMajorVersion` int unsigned NOT NULL, 
    `ServiceMinorVersion` int unsigned NOT NULL, 
    `ServiceInstanceID` VARCHAR(100) NOT NULL, 
    `StoredValue` VARCHAR(1024) 

, PRIMARY KEY (`Section`, `StoredKey`, `ServiceName`, `ServiceMajorVersion`, `ServiceMinorVersion`, `ServiceID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 
+0

vous suggérons de poster votre définition de table ... –

+0

Très bien, table affichée. – ripper234

Répondre

3

utiliser des entiers pour clé primaire auto-incrémentée et ajouter une autre clé unique.

Sinon, vous pouvez essayer d'utiliser binary(16) comme clé primaire avec unhex(md5(concat(colonnes))) en tant que valeur.

+2

"Il suffit de taper un PK entier auto-incrémenté" n'est pas * toujours * la réponse à un problème de conception de base de données, malgré ce que beaucoup de gens semblent penser. Dans ce cas, il ne cachera que des problèmes beaucoup plus profonds dans ce schéma, et sera en outre complètement inutile pour imposer des contraintes d'unicité appropriées. – kquinn

+0

@kquinn: Bien sûr.Je suis juste en train de répondre à la question de savoir comment travailler avec PK long _assuming_ on a de bonnes raisons de l'utiliser. – Kornel

2

Il est difficile de dire sans comprendre votre base de données, mais cela pourrait nécessiter une normalisation. Vous pouvez toujours créer un UNIQUE INDEX qui n'est pas une clé primaire, et s'il existe déjà une seule colonne qui sera unique, faites-en une clé primaire, et si ce n'est pas le cas, vous pouvez créer une clé primaire de substitution (INTEGER AUTO_INCREMENT).

0

D'accord avec ce que @pornel et @CadeRoux ont déjà posté; Il vaudrait mieux créer une clé primaire de substitution (ConfigurationId) en tant que colonne entière auto-incrémentée, puis créer un index unique séparé.

4

Vous devriez lire un livre sur la conception de structure de base de données, vous n'aurez alors pas de tables avec de telles clés primaires. Ou embaucher quelqu'un qui mon créer (prototype) pour la structure DB pour vous. Ceci est juste un conseil amical.

+0

Merci noonex, d'autres réponses jusqu'à présent sont sur la mauvaise voie, voir Pounding a Nail: Old Shoe ou une bouteille en verre? (http://weblogs.asp.net/alex_papadimoulis/archive/2005/05/25/408925.aspx) – MGOwen

4

@porneL a la bonne réponse pour ce cas, cependant, @Cade Roux et @noonex sont également correctes: bases de données ne sont pas destinés à être utilisés comme Excel.

Vous devriez avoir des tables secondaires:

CREATE TABLE ServiceInstance (
    ID int(11) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    Hash binary(16) NOT NULL, 
    ServiceInstanceID varchar(100) NOT NULL, 
    UNIQUE(Hash) 
); 

Pour chaque table, sauf les données qui seront uniques par ligne de configuration.

Lorsque vous insérez, faites:

INSERT INTO ServiceInstance (Hash, ServiceInstanceID) VALUES (unhex(md5('whatever')), 'whatever'); 

Ensuite, votre table primaire devient:

CREATE TABLE `configuration` (
    `Section_ID`   int unsigned NOT NULL, 
    `StoredKey_ID`  int unsigned NOT NULL, 
    `ServiceName_ID`  int unsigned NOT NULL, 
    `ServiceMajorVersion` int unsigned NOT NULL, 
    `ServiceMinorVersion` int unsigned NOT NULL, 
    `ServiceInstanceID` int unsigned NOT NULL, 
    `StoredValue`   VARCHAR(1024), 
    UNIQUE (`Section_ID`, `StoredKey_ID`, `ServiceName_ID`, `ServiceMajorVersion`, `ServiceMinorVersion`, `ServiceInstanceID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

Utilisez la touche UNIQUE à la place, comme les clés primaires sont généralement utilisés lorsque vous allez accéder à des lignes par la clé primaire toujours. Si c'est juste une contrainte, utilisez UNIQUE à la place.

Questions connexes