2010-11-03 4 views
2

J'ai cette structure de base de donnéesChaîne en tant que clé primaire?

CREATE TABLE `productinfo` (
    `ProductID` int(11) NOT NULL AUTO_INCREMENT, 
    `ProductName` varchar(255) NOT NULL, 
    `ProductImage` varchar(255) NOT NULL, 
    `CategoryID` int(11) NOT NULL, 
    `SubCategoryID` int(11) NOT NULL, 
    `ProductBrief` varchar(255) NOT NULL, 
    `Features` text NOT NULL, 
    `Specifications` text NOT NULL, 
    `Reviews` text NOT NULL, 
    `Price` varchar(255) NOT NULL, 
    `Status` tinyint(4) NOT NULL, 
    PRIMARY KEY (`ProductID`) 
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=latin1; 

je maintenant je dois tourner ProductID, CategoryID et SubCategoryID dans une chaîne comme Ps-5678 pour le numéro de pièce. ProductID est la clé primaire, donc comment puis-je changer la structure de la base de données. CategoryID et SubCategoryID sont les clés primaires dans d'autres tableaux alors comment puis-je gérer this..is aussi facile que tourner

`ProductID` int(11) NOT NULL AUTO_INCREMENT 

en string..and se débarrasser de

PRIMARY KEY (`ProductID`) 

idées, suggestions

+1

Surtout si vous avez besoin de gérer des ORM, il peut être plus facile de quitter le PK sortant et d'utiliser un index de couverture unique sur le "Pretty String ID produit" (qui ressemble à une dénormalisation de Category, SubCat , etc ...) –

Répondre

8

Les clés primaires sont pour la base de données.

Les noms d'affichage sont pour les utilisateurs finaux.

Ne pas confondre l'un avec l'autre! Ne faites pas une clé primaire avec quelque chose qui a un sens. Vous le regretterez tôt ou tard. Avoir une clé/identité/numéro de remplacement comme clé primaire est une très bonne idée et est largement utilisée dans la conception de base de données.

Vous pouvez ajouter une colonne ou même une colonne DERIVED et lui ajouter une contrainte unique.

+0

pouvez-vous me donner un exemple de clé de substitution/identité/autonumber comme une clé primaire – Trace

+0

@Matt: Vous n'avez pas besoin d'un exemple - c'est exactement ce que vous avez fait en premier! N'oubliez pas votre intention de transformer ProductId en une colonne varchar ... En fait, puisque ce "nouveau champ" est juste une expression calculée, vous n'avez même pas besoin de créer une colonne avec cette valeur. Il suffit de concaténer les champs sous-jacents avant de les afficher. – rsenna

+1

-1 La création d'une colonne dérivée sur une clé de substitution sape la valeur d'avoir un substitut du tout. Vous devez appliquer la contrainte d'unicité sur la clé métier significative indépendamment de toute clé de substitution que vous utilisez. Que vous ayez besoin ou non d'un substitut est une décision distincte. – sqlvogel

0

Je ne sais pas exactement ce que vous faites du produit, de la catégorie et de la sous-catégorie pour faire votre numéro de pièce. Je suppose que pour les besoins de l'argument que vous les concaténiez ensemble, comme le produit 123, la catégorie 456, la sous-catégorie 789 donne le numéro de pièce 123-456-789 ou une autre. J'aime utiliser les identifiants naturels comme clés primaires chaque fois que cela est possible. Mais "chaque fois que cela est possible" peut être une contrainte sérieuse. Si votre identifiant naturel est dérivé en combinant en quelque sorte trois autres domaines, vous avez quatre choix:

  1. la clé primaire soit la combinaison de ces trois domaines. Cela a tendance à être une douleur. Toutes vos jointures doivent alors correspondre sur trois champs, les recherches doivent tester trois champs, etc.

  2. Créer un nouveau champ qui est la concaténation des trois champs, et l'utiliser comme clé de priamry. Ensuite, chaque fois que l'un des champs «de base» change, modifiez également ce champ concaténé. C'est une très, très mauvaise idée. Ne fais pas ça. Ce sont des données redondantes, avec toutes les mauvaises choses qui proviennent de données redondantes.

  3. Remplacez les trois champs séparés par un champ combiné. C'est pire que # 2. Maintenant, lorsque vous avez besoin des valeurs individuelles, vous devez séparer le champ.

  4. Abandonnez et créez une clé synthétique, comme un numéro de série. Utilisez-le comme clé primaire, puis utilisez simplement la clé naturelle à des fins d'affichage. Si ma clé naturelle nécessite de concaténer ou de manipuler trois champs, j'ai tendance à utiliser cette option.

1

Votre exigence n'est pas claire.Comment obtenez-vous "PS-5678" pour 3 colonnes int? Il n'y a que 2 composants dans votre exemple.

Avez-vous juste besoin de CONVERTIR les 3 INT en une seule chaîne CHAR()?

Si oui, la base de données est bien, pas besoin de changer la table du tout!?!?! Les trois composants sont déjà disponibles, correctement séparés, en tant que colonnes distinctes. Ce que vous recherchez, c'est simplement AFFICHER les trois composants en une seule chaîne.

Questions connexes