Подтвердить что ты не робот

Mysql - номера котировок или нет?

Например, я создаю базу данных и таблицу из cli и вставляю некоторые данные:

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 string');

Теперь я могу это сделать, и эти примеры работают (так что кавычки ничего не влияют):

SELECT * FROM test WHERE id = '9';
INSERT INTO test VALUES ('11', 'some string');

Итак, в этих примерах я выбрал строку с помощью строки , которая фактически хранится как INT в mysql, а затем я вставлял строку в столбце, который является INT.

Я не совсем понимаю, почему это работает так, как это работает здесь. Почему строка разрешена для вставки в столбец INT?

Можно ли вставить все типы данных Mysql в виде строк?

Является ли это стандартом поведения для разных РСУБД?

спасибо!

4b9b3361

Ответ 1

MySQL очень похож на PHP и будет автоматически преобразовывать типы данных, насколько это возможно. Поскольку вы работаете с полем int (слева), он попытается прозрачно преобразовать правую часть аргумента в int, поэтому '9' просто становится 9.

Строго говоря, цитаты не нужны и заставляют MySQL делать typecasting/conversion, поэтому он отнимает немного процессорного времени. На практике, если вы не используете операцию размера Google, такие накладные расходы на преобразование будут микроскопически небольшими.

Ответ 2

Вы никогда не должны заключать в кавычки цифры. Для этого есть веская причина.

Настоящая проблема сводится к приведению типов. Когда вы помещаете числа в кавычки, они обрабатываются как строка, и MySQL должен преобразовать их в число, прежде чем он сможет выполнить запрос. Хотя это может занять небольшое количество времени, реальные проблемы начинают возникать, когда MySQL не выполняет хорошую работу по преобразованию вашей строки. Например, MySQL преобразует базовые строки, такие как "123", в целое число 123, но преобразует некоторые большие числа, например "18015376320243459", в число с плавающей запятой. Поскольку с плавающей запятой можно округлить, ваши запросы могут возвращать противоречивые результаты. Подробнее о приведении типов читайте здесь. В зависимости от аппаратного и программного обеспечения вашего сервера, эти результаты могут отличаться. MySQL объясняет это.

Если вы беспокоитесь о SQL-инъекциях, всегда сначала проверяйте значение и используйте PHP, чтобы убрать все не числа. Для этого вы можете использовать preg_replace: preg_replace("/[^0-9]/", "", $string)

Кроме того, если вы пишете SQL-запросы с кавычками, они не будут работать с базами данных, такими как PostgreSQL или Oracle.

Ответ 3

Это не стандартное поведение.

Для MySQL 5.5. это стандартный режим SQL

mysql> select @@sql_mode;
+------------+
| @@sql_mode |
+------------+
|            |
+------------+
1 row in set (0.00 sec)

ANSI и TRADITIONAL используются более строго Oracle и PostgreSQL. Режимы SQL. Должны быть установлены разрешения MySQL. ЕСЛИ И ТОЛЬКО ЕСЛИ вы хотите сделать SQL более ANSI-совместимым. В противном случае вам не нужно прикасаться к предмету. Я никогда этого не делал.

Ответ 4

AFAIK является стандартным, но считается плохой практикой, потому что
- использование этого в предложении WHERE не позволит оптимизатору использовать индексы (пояснить план должен показать это)
- база данных должна выполнить дополнительную работу, чтобы преобразовать строку в число
- если вы используете это для чисел с плавающей запятой ( "9.4" ), у вас возникнут проблемы, если клиент и сервер будут использовать разные языковые настройки (9.4 vs 9,4)

Короче: не делайте этого (но YMMV)

Ответ 5

Проверьте это, вы можете понять лучше...

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)

Ответ 6

Вам не нужно указывать числа, но это всегда хорошая привычка, если вы делаете так, как это согласовано.

Ответ 7

Проблема заключается в том, что у нас есть таблица с именем users, которая имеет столбец с именем current_balance типа FLOAT, если вы запустите этот запрос:

UPDATE `users` SET `current_balance`='231608.09' WHERE `user_id`=9;

Поле current_balance будет обновлено до 231608, потому что MySQL сделал округление, аналогично, если вы попробуете этот запрос:

UPDATE `users` SET `current_balance`='231608.55' WHERE `user_id`=9;

Поле current_balance будет обновлено до 231609

Ответ 8

Это зависит от типа столбца! если вы запускаете

SELECT * FROM 'users' WHERE 'username' = 0;

в mysql/maria-db вы получите все записи, в которых username НЕ НЕДЕЙСТВИТЕЛЕН.

Всегда заключайте в кавычки значения, если столбец имеет тип string (char, varchar,...), иначе вы получите неожиданные результаты!