2010-12-03 2 views
1

Ma structure de table est:Mysql clé primaire lorsque vous utilisez INSERT INTO ... Duplicate KEY UPDATE

CREATE TABLE IF NOT EXISTS `users_settings_temp` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `userid` int(10) unsigned DEFAULT NULL, 
    `type` enum('type1','type2') 
    `data` text, 
    `date_created` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

Ce que je suis en train de faire est:

Disons que je veux insérer une nouvelle entrée , mais je ne veux pas que ce soit en double, après Google autour, je trouve ce format:

INSERT INTO users_settings_temp(...) 
ON DUPLICATE KEY UPDATE data = '{$data}' 

Je suppose que le problème est dans ma table, la clé primaire =>id. Comment puis-je modifier la table, de sorte que je pourrais utiliser le:

INSERT INTO ... ON DUPLICATE KEY UPDATE 

Puis-je utiliser user_id + type comme clé primaire? Si oui, pourriez-vous s'il vous plaît me montrer comment le faire?

+0

Que voulez-vous exactement se produire sur un duplicata? Jetez-le? Changer les données à quelque chose? –

+0

Désolé pour ne pas préciser. Je veux mettre à jour quand il est en double. Je vais mettre à jour ma question sous peu. –

+0

clé primaire (ID utilisateur, type) –

Répondre

5
CREATE TABLE IF NOT EXISTS `users_settings_temp` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `userid` int(10) unsigned DEFAULT NULL, 
    `type` enum('type1','type2'), 
    `data` text, 
    `date_created` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`, `type`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

Lorsque vous le faites comme ça alors

a) id spécifiant fonctionne

mysql> INSERT INTO users_settings_temp VALUES (1, 2, 'type1', 'keks', 5); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO users_settings_temp VALUES (1, 2, 'type2', 'keks', 5); 
Query OK, 1 row affected (0.00 sec) 

b) bien sûr la clé primaire est garantie unique

mysql> INSERT INTO users_settings_temp VALUES (1, 2, 'type2', 'keks', 5); 
ERROR 1062 (23000): Duplicate entry '1-type2' for key 'PRIMARY' 

c) laisser la base de données tirer un nouvel identifiant fonctionne

mysql> INSERT INTO users_settings_temp VALUES (NULL, 2, 'type2', 'keks', 5); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO users_settings_temp VALUES (NULL, 2, 'type1', 'keks', 5); 
Query OK, 1 row affected (0.00 sec) 

mais les multiplierai toujours

mysql> SELECT * FROM users_settings_temp; 
+----+--------+-------+------+--------------+ 
| id | userid | type | data | date_created | 
+----+--------+-------+------+--------------+ 
| 1 |  2 | type1 | keks |   5 | 
| 1 |  2 | type2 | keks |   5 | 
| 2 |  2 | type2 | keks |   5 | 
| 3 |  2 | type1 | keks |   5 | 
+----+--------+-------+------+--------------+ 
4 rows in set (0.00 sec) 

NOTES:

Vous devriez penser si votre id devrait encore être autoIncrement ou non. En outre, ne peut pas penser à une raison pour laquelle date_created devrait être int(11) au lieu de datetime

+0

Je convertis le temps en secondes en utilisant strtotime() et stocke l'heure dans la base de données. Je suis un tutoriel sur internet. Je ne sais pas si c'est une bonne pratique. –

+0

@ webdev_007, ce n'est pas le cas, mais ce n'est pas si simple non plus. La détermination du domaine/type dans la base de données détermine * tout * l'utilisation ultérieure des données (code d'application, code de base de données, requêtes, formatage, transformations, etc ...) - à moins qu'il n'y ait une couche d'abstraction de données côté application) Par conséquent, il est bon de bien faire les choses. Les règles ne sont pas si simples - mais normalement vous devriez aller pour les types naturels, la date est la date, le montant est décimal, etc. * sauf si vous avez une raison. (aussi, si vous trouvez la réponse utile, vous pouvez aussi l'augmenter et non l'accepter) – Unreason

Questions connexes