Par exemple, je crée une firebase database et une table à partir de cli et insère des données:
CREATE DATABASE testdb CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; USE testdb; CREATE TABLE test (id INT, str VARCHAR(100)) TYPE=innodb CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; INSERT INTO test VALUES (9, 'some ssortingng');
Maintenant je peux le faire et ces exemples fonctionnent (donc – les guillemets n’affectent rien de ce qu’il semble):
SELECT * FROM test WHERE id = '9'; INSERT INTO test VALUES ('11', 'some ssortingng');
Donc, dans ces exemples, j’ai sélectionné une ligne par une chaîne de caractères stockée sous INT dans mysql, puis j’ai inséré une chaîne dans une colonne qui est INT.
Je ne comprends pas bien pourquoi cela fonctionne comme cela fonctionne ici. Pourquoi la chaîne doit-elle être insérée dans une colonne INT?
Puis-je insérer tous les types de données Mysql en tant que chaînes?
Ce comportement est-il standard sur différents SGBDR?
Merci!
MySQL ressemble beaucoup à PHP et convertira automatiquement les types de données au mieux. Puisque vous travaillez avec un champ int (à gauche), il essaiera également de convertir de manière transparente le côté droit de l’argument en int, afin que '9'
devienne simplement 9
.
Ssortingctement parlant, les guillemets ne sont pas nécessaires et obligent MySQL à effectuer une conversion / conversion, ce qui lui fait perdre un peu de temps CPU. En pratique, à moins d’exécuter une opération de taille Google, cette surcharge de conversion sera minime sur le plan microscopique.
Vous ne devriez jamais mettre des guillemets autour des nombres. Il y a une raison valable à cela.
Le vrai problème vient du type casting. Lorsque vous mettez des nombres entre guillemets, il est traité comme une chaîne et MySQL doit le convertir en nombre avant de pouvoir exécuter la requête. Bien que cela puisse prendre un peu de temps, les vrais problèmes commencent à se produire lorsque MySQL ne fait pas un bon travail de conversion de votre chaîne. Par exemple, MySQL convertira les chaînes de base telles que “123” en entier 123, mais convertira certains nombres plus importants, tels que “18015376320243459”, en virgule flottante. Comme le virgule flottante peut être arrondi, vos requêtes peuvent renvoyer des résultats incohérents. En savoir plus sur le casting de type ici . Selon le matériel et les logiciels de votre serveur, ces résultats varient. MySQL explique cela.
Si vous vous inquiétez des injections SQL, vérifiez d’abord la valeur et utilisez PHP pour supprimer les non-nombres. Vous pouvez utiliser preg_replace pour cela: preg_replace("/[^0-9]/", "", $ssortingng)
De plus, si vous écrivez vos requêtes SQL avec des guillemets, elles ne fonctionneront pas sur des bases de données telles que PostgreSQL ou Oracle.
AFAIK c’est standard, mais c’est considéré comme une mauvaise pratique parce que
– son utilisation dans une clause WHERE empêchera l’optimiseur d’utiliser des indices (expliquez que le plan doit le montrer)
– la firebase database doit faire un travail supplémentaire pour convertir la chaîne en nombre
– Si vous utilisez ceci pour des nombres à virgule flottante (“9.4”), vous rencontrerez des problèmes si le client et le serveur utilisent des parameters de langue différents (9.4 vs 9,4)
En bref: ne le faites pas (mais YMMV)
Ce n’est pas un comportement standard.
Pour MySQL 5.5. c’est le mode SQL par défaut
mysql> select @@sql_mode; +------------+ | @@sql_mode | +------------+ | | +------------+ 1 row in set (0.00 sec)
ANSI et TRADITIONAL sont utilisés plus rigoureusement par Oracle et PostgreSQL. Les modes SQL que MySQL autorise doivent être définis SI ET UNIQUEMENT SI vous souhaitez rendre le SQL plus conforme à la norme ANSI. Sinon, vous ne devez rien toucher. Je ne l’ai jamais fait.
Vérifiez ceci, vous pouvez mieux comprendre …
mysql> EXPLAIN SELECT COUNT(1) FROM test_no WHERE varchar_num=0000194701461220130201115347; +----+-------------+------------------------+-------+-------------------+-------------------+---------+------+---------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------------------+-------+-------------------+-------------------+---------+------+---------+--------------------------+ | 1 | SIMPLE | test_no | index | Uniq_idx_varchar_num | Uniq_idx_varchar_num | 63 | NULL | 3126240 | Using where; Using index | +----+-------------+------------------------+-------+-------------------+-------------------+---------+------+---------+--------------------------+ 1 row in set (0.00 sec) mysql> EXPLAIN SELECT COUNT(1) FROM test_no WHERE varchar_num='0000194701461220130201115347'; +----+-------------+------------------------+-------+-------------------+-------------------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------------------+-------+-------------------+-------------------+---------+-------+------+-------------+ | 1 | SIMPLE | test_no | const | Uniq_idx_varchar_num | Uniq_idx_varchar_num | 63 | const | 1 | Using index | +----+-------------+------------------------+-------+-------------------+-------------------+---------+-------+------+-------------+ 1 row in set (0.00 sec) mysql> mysql> mysql> SELECT COUNT(1) FROM test_no WHERE varchar_num=0000194701461220130201115347; +----------+ | COUNT(1) | +----------+ | 1 | +----------+ 1 row in set, 1 warning (7.94 sec) mysql> SELECT COUNT(1) FROM test_no WHERE varchar_num='0000194701461220130201115347'; +----------+ | COUNT(1) | +----------+ | 1 | +----------+ 1 row in set (0.00 sec)
Vous n’avez pas besoin de citer les chiffres, mais c’est toujours une bonne habitude si vous faites ce qui est cohérent.
Le problème est, disons que nous avons une table appelée users, qui a une colonne appelée current_balance de type FLOAT, si vous exécutez cette requête:
UPDATE `users` SET `current_balance`='231608.09' WHERE `user_id`=9;
Le champ current_balance sera mis à jour à 231608, car MySQL a arrondi, de même si vous essayez cette requête:
UPDATE `users` SET `current_balance`='231608.55' WHERE `user_id`=9;
Le champ current_balance sera mis à jour à 231609