MySQL, являющийся Null, вызовет 5 проблем, все из которых фатальные!

Java MySQL
MySQL, являющийся Null, вызовет 5 проблем, все из которых фатальные!

Перед официальным запуском давайте взглянем на информацию о конфигурации и номере версии сервера MySQL, как показано на следующем рисунке:image.png

«Давайте без перемещения войск и лошадей», после прочтения соответствующей конфигурации давайте сначала создадим тестовую таблицу и некоторые тестовые данные.

-- 如果存在 person 表先删除
DROP TABLE IF EXISTS person; 

-- 创建 person 表,其中 username 字段可为空,并为其设置普通索引
CREATE TABLE person (
	id INT PRIMARY KEY auto_increment,
	name VARCHAR(20),
	mobile VARCHAR(13),
	index(name)
) ENGINE='innodb';

-- person 表添加测试数据
insert into person(name,mobile) values('Java','13333333330'),
	('MySQL','13333333331'),
	('Redis','13333333332'),
	('Kafka','13333333333'),
	('Spring','13333333334'),
	('MyBatis','13333333335'),
	('RabbitMQ','13333333336'),
	('Golang','13333333337'),
	(NULL,'13333333338'),
	(NULL,'13333333339');
  
select * from person;

Построенные тестовые данные показаны на следующем рисунке:

image.png

После того, как у нас есть данные, давайте посмотрим, существует ли столбец.NULLзначение, какие проблемы это вызовет?

1. подсчет потери данных

когда столбец существуетNULLзначение, затем используйтеcountПри запросе этого столбца возникнет проблема «потери» данных, как показано в следующем SQL:

select count(*),count(name) from person;

Результат выполнения запроса следующий:

image.png

Из вышеприведенных результатов видно, что при использованииcount(name)При запросе теряются два значенияNULLданных теряется.

решение

если столбец существуетNULLценность, использованиеcount(*)Сделать статистику.

Расширенные знания: не используйте count(constant)

«Руководство по разработке Java» Alibaba предписывает: не используйте count (имя столбца) или count (константа) вместо count (), считать() — это стандартный синтаксис для подсчета строк, определенный в SQL92, который не имеет ничего общего с базой данных и не имеет ничего общего с NULL и не-NULL.

Описание: count(*) будет подсчитывать строки со значениями NULL, а count(имя столбца) не будет подсчитывать строки со значениями NULL в этом столбце.

2. отчетливая потеря данных

когда используешьcount(distinct col1, col2)При запросе, если один из столбцовNULL, то даже если другой столбец имеет другое значение, результат запроса потеряет данные, как показано в следующем SQL:

select count(distinct name,mobile) from person;

Результат выполнения запроса следующий:

image.png

Необработанные данные базы данных выглядят следующим образом:

image.png

Из приведенных выше результатов видно, что все 10 фрагментов данных в столбце с номером мобильного телефона разные, но результат запроса равен 8.

3.выберите потерю данных

если столбец существуетNULLзначение, выполнение запроса, не равного (/!=), приводит кNULLРезультат значения теряется. Например, следующие данные:

image.png

Мне нужно запросить все данные, кроме имени, равного «Java», и ожидается, что они вернут данные с идентификатором от 2 до 10, но при выполнении следующего запроса:

select * from person where name<>'Java' order by id;
-- 或
select * from person where name!='Java' order by id;

Результаты запроса следующие:

image.png

можно рассматривать какNULLДва данных исчезли из ниоткуда, и этот результат не оправдал наших обычных ожиданий.

решение

Чтобы решить вышеуказанную проблему, просто добавьте в результат запроса какNULLРезультат значения может быть выполнен, и SQL выполняется следующим образом:

select * from person where name<>'Java' or isnull(name) order by id;

Окончательный результат выполнения следующий:

image.png

4. Вызывает исключение нулевого указателя

если столбец существуетNULLзначение, может привести кsum(column)Возвращаемый результатNULLвместо 0, еслиsumРезультат запросаNULLЭто может вызвать исключение нулевого указателя (NPE) во время выполнения программы.Давайте продемонстрируем эту проблему.

Во-первых, давайте создадим таблицу и некоторые тестовые данные:

-- 如果存在 goods 表先删除
DROP TABLE IF EXISTS goods; 

-- 创建 goods 表
CREATE TABLE goods (
	id INT PRIMARY KEY auto_increment,
	num int
) ENGINE='innodb';

-- goods 表添加测试数据
insert into goods(num) values(3),(6),(6),(NULL);

select * from goods;

Исходные данные в таблице следующие:

image.png

Далее мы используемsumзапрос, выполните следующий SQL:

select sum(num) from goods where id>4;

Результат выполнения запроса следующий:

image.png

Когда результат запросаNULLВместо 0 это может вызвать исключение нулевого указателя.

Разрешить исключение нулевого указателя

Исключений нулевого указателя можно избежать, используя:

select ifnull(sum(num), 0) from goods where id>4;

Результат выполнения запроса следующий:

image.png

5. Повышенная сложность запросов

когда значение столбца имеетNULLстоимость, во времяNULLценность или нетNULLСложность запроса значения возрастает.

Так называемое увеличение сложности запросов относится кNULLПри запросе по значению вы должны использоватьNULLМетод запроса, соответствующий значению, напримерIS NULL илиIS NOT NULL Или этоIFNULL(cloumn)Такие выражения запрашиваются, в то время как традиционные=、!=、<>...Когда эти выражения нельзя использовать, это увеличивает сложность запросов, особенно для начинающих программистов.Далее давайте продемонстрируем эти проблемы.

или сpersonТаблица в качестве примера, ее исходные данные таковы:

image.png

Плохое использование 1:

select * from person where name<>null;

Результат выполнения пуст, и данные не запрашиваются, как показано на следующем рисунке:

image.png

Неправильное использование 2:

select * from person where name!=null;

Результат выполнения также пуст, и данные не запрашиваются, как показано на следующем рисунке:

image.png

Правильное использование 1:

select * from person where name is not null;

Результат выполнения следующий:

image.png

Правильное использование 2:

select * from person where !isnull(name);

Результат выполнения следующий:

image.png

Рекомендуемое использование

Alibaba «Руководство по разработке Java» рекомендует использоватьISNULL(cloumn)судитьNULLценность, причина в том, что в операторе SQL разрыв строки перед нулевым значением влияет на читабельность; иISNULL(column)Он цельный, лаконичный и понятный. Анализ данных о производительностиISNULL(column)Эффективность выполнения также выше.

Расширенные знания: NULL не влияет на индексы

Осторожные друзья, возможно, узнали, я создаюpersonТаблицаnameполе, для него создается нормальный индекс, как показано на следующем рисунке:

image.png

Затем мы используемexplainЧтобы проанализировать план запроса, посмотрите, когдаnameимеютNULLПовлияет ли значение на выбор индекса.

explainРезультат выполнения показан на следующем рисунке:

image.png

Из вышеприведенных результатов видно, что дажеnameимеютNULLЭто значение также не влияет на использование MySQL индекса для запросов.

Суммировать

В этой статье мы говорили о том, когда столбецNULL5 видов проблем, которые могут быть вызваны временем: потеря результатов запроса, исключение нулевого указателя и увеличение сложности запроса. Поэтому, в конце концов, рекомендуется установить как можно больше при создании таблицыis not nullОграничение: если столбец не имеет значения, вы можете установить нулевое значение ('') или 0 в качестве значения по умолчанию.

Наконец: у вас все еще есть различные ямы, вызванные NULL? Дополнительные комментарии приветствуются в области комментариев.

Ссылки и благодарности

Alibaba "Руководство по разработке Java"

Подпишитесь на официальный аккаунт «Java Chinese Community», чтобы узнать больше о галантерейных товарах. Посетите Github, чтобы узнать больше интересных вещей:GitHub.com/VIP камень/Али…