SQL-запрос, чтобы избежать декартова произведения

Опубликовано: 10 Января, 2023

SQL Server — универсальная база данных. Он придерживается принципов управления реляционными базами данных и, следовательно, является популярной СУБД. Поскольку данные доступны в нескольких таблицах, если SQL-запрос написан неэффективным образом, в основных сценариях возникает декартово произведение. Мы увидим это здесь.

В общей математике декартово произведение двух множеств, а именно M и N, обозначается M × N. Это множество всех упорядоченных пар, где m находится в M, а n — в N.

При переходе к SQL, если таблица M имеет 10 строк данных и если таблица N имеет 20 строк данных, таблица декартовых произведений будет иметь 10 * 20 = 200 строк данных. т.е. добавляются все возможные упорядоченные пары исходного набора элементов. Мы можем думать, что каждый первичный ключ первой таблицы сопоставляется с первичным ключом второй таблицы. Обычно декартово произведение приводит к избыточным данным, и это также для больших наборов данных дает очень большие избыточные данные. Следовательно, нам нужно писать эффективные SQL-запросы.

Декартово произведение включает в себя большое количество вычислительных операций, которые обычно являются избыточными. Следовательно, нам нужно избегать создания декартова произведения

Процесс, позволяющий избежать декартова произведения:

Шаг 1: Давайте возьмем базу данных с именем «гики для гиков», и в ней возьмем 2 таблицы, а именно «Фрукты» и «Размеры», и пусть у нас будет указанный выше набор данных.

Запрос:

USE GEEKSFORGEEKS

CREATE TABLE [dbo].[FRUITS] (
    [fruitName] VARCHAR (20) NULL
);

INSERT INTO FRUITS VALUES("Apples");
INSERT INTO FRUITS VALUES("Mangoes");

SELECT * FROM FRUITS;

Выход:

Запрос:

CREATE TABLE [dbo].[SIZES] (
    [sizeName] VARCHAR (20) NULL
);
INSERT INTO SIZES VALUES("Small");
INSERT INTO SIZES VALUES("Medium");
INSERT INTO SIZES VALUES("Big");
SELECT * FROM SIZES;

Выход:

Шаг 2: Теперь, если мы просто объединим две таблицы, чтобы получить из них оба столбца, мы можем написать запрос как:

Запрос:

SELECT A.*, B.* FROM FRUITS A,SIZES B;

Шаг 3: Теперь, если это большая таблица, результирующий вывод будет очень большим, и большая часть данных будет избыточной. Следовательно, нам нужно избегать этого. Это можно сделать, выполнив условие «JOIN». На самом деле сейчас обе таблицы не имеют общего соединительного столбца, поэтому нам нужно ввести общий соединительный столбец.

Давайте введем «fruidId», чтобы иметь уникальное значение в таблице «Fruits» и тот же «fruitId», что и внешний ключ в таблице «Sizes». После применения значений:

Запрос:

ALTER TABLE FRUITS ADD FRUITID INT NULL;
-- SET THE VALUE 1 TO APPLES AND 2 TO MANGOES
SELECT * from FRUITS;

Выход:

Запрос:

ALTER TABLE SIZES ADD FRUITID INT NULL;
--LET US APPLY VALUES OF FRUITID TO 1 FOR SMALL, 2 FOR MEDIUM,1 FOR BIG
SELECT * from SIZES;

Выход:

Шаг 4: Поскольку у нас есть общий соединительный столбец, мы можем легко соединить обе таблицы с помощью этого соединительного столбца:

Запрос:

SELECT A.fruitName, B.sizeName FROM FRUITS A,SIZES B
WHERE A.FRUITID = B.FRUITID;
--Here we need to join fruitid in both the tables
--In this way, we can avoid cartesian product 
--As in Sizes table, fruitid is having 1 and 2 only,
-- we need to get apples and mangoes only
--that too apples will be having small and big sizes and 
-- mangoes will be having medium sizes.
--We can achieve that with this query

Выход:

Примечание:

  • Нам нужно написать запросы. осторожно.
  • Любые две таблицы, имеющие имя столбца с одинаковыми типами данных, будут использоваться для объединения.
  • Особенно всегда полезно сохранять отношения первичного ключа и внешнего ключа между таблицами. Это поможет легко синхронизировать результаты. В этих сценариях большая часть первичного ключа будет доступна в первой таблице с одним именем столбца, и то же имя столбца будет использоваться во второй таблице в качестве внешнего ключа.
  • Значимые соединения хороши и всегда соединяются и избегают декартовых произведений. Это может быть достигнуто либо путем сохранения отношений первичного и внешнего ключей, либо путем сохранения общего имени столбца, мы можем создавать соединения.
  • Условия соединения должны быть указаны в предложении «WHERE», а в случае операций «Group By» они должны применяться в предложении «Having».

Вывод:

Декартовы данные продукта сильно избыточны, особенно когда мы работаем с большими наборами данных, и их можно исправить с помощью допустимых соединений. Это слишком внутреннее соединение (которое описано в приведенном выше примере) даст точный результат, то есть извлекаются только совпадающие значения в обеих или нескольких таблицах. Кроме того, у нас есть левое внешнее соединение и правое внешнее соединение, но все они должны использоваться по мере необходимости, в противном случае внутреннее соединение является эффективным, чтобы избежать декартова произведения.