SQL vs NoSQL в примерах

SQL vs NoSQL в примерах


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

SQL (язык структурированных запросов) используется большинством СУБД для управления базами, хранящими данные в табличной форме. NoSQL относится к не-SQL или нереляционным базам данных. Она по-прежнему обеспечивает организованный способ хранения данных, но не в табличной форме.

Если отбросить заботу о скорости и масштабируемости, то и SQL и NoSQL обеспечивают разнообразные и эффективные способы получения данных. Это обязательное условие для базы данных, поскольку доступность также имеет решающее значение.

В этой статье мы рассмотрим примеры, демонстрирующие, как выполнять запросы к базам данных SQL и NoSQL. В примерах будет показано, как:

  • Выбирать данные на основании условия
  • Вставлять новые элементы
  • Обновлять существующие элементы
  • Применять функции агрегирования

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

Я буду использовать MySQL для SQL и MongoDB для NoSQL. Прежде чем приступить к примерам, давайте кратко объясним, как хранятся данные в SQL и NoSQL.

SQL хранит данные в табличной форме с обозначенными строками и столбцами. Общими структурами, используемыми базами данных NoSQL, являются пары ключ-значение, семейство столбцов, граф или документ. MongoDB хранит данные в виде документов. Документ в MongoDB состоит из пар "поле-значение". Документы организованы в структуру под названием "коллекция". В качестве аналогии можно представить документы как строки в таблице, а коллекции - как таблицы.

Я создал простую таблицу в MySQL и коллекцию в MongoDB с одинаковыми данными, содержащими характеристики некоторых автомобилей и их цены.

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

 "_id" : ObjectId("600c626932e0e6419cee81a7"),
 "year" : "2017",
 "make" : "hyundai",
 "color" : "white",
 "km" : 22000,
 "price" : 32000
}

В SQL данные (в нашем случае один автомобиль) обозначаются строкой.

+------+---------+-------+-------+-------+
| year | make    | color | km    | price |
+------+---------+-------+-------+-------+
| 2017 | hyundai | white | 22000 | 32000 |
+------+---------+-------+-------+-------+


Пример 1.

Найдите автомобили, произведенные компанией Ford.


NoSQL (MongoDB):

Мы передаем условие в функцию find. "db" обозначает текущую базу данных, а "car" - коллекцию, которую мы запрашиваем.

db.car.find( {make: "ford"} ).limit(1).pretty()

{
 "_id" : ObjectId("600c63cf32e0e6419cee81ab"),
 "year" : "2017",
 "make" : "ford",
 "color" : "black",
 "km" : 34000,
 "price" : 28000
}

 Компания Ford производит больше одного автомобиля, но я использую функцию limit, чтобы вывести только один.

Функция pretty делает вывод более читабельным и привлекательным. Вот как это выглядит без функции pretty.

> db.car.find( {make: "ford"} ).limit(1)

{ "_id" : ObjectId("600c63cf32e0e6419cee81ab"), "year" : "2017", "make" : "ford", "color" : "black", "km" : 34000, "price" : 28000 }


SQL (MySQL):

Выбираем все столбцы (*) и указываем условие в операторе WHERE.

mysql> select * from car
    -> where make = "ford"
    -> limit 1;

+------+------+-------+-------+-------+
| year | make | color | km    | price |
+------+------+-------+-------+-------+
| 2017 | ford | black | 34000 | 28000 |
+------+------+-------+-------+-------+


Пример 2.

Найдите автомобили, выпускаемые компанией Ford в 2019 году.


NoSQL (MongoDB):

Мы можем задать несколько условий, разделенных запятыми, чтобы указать логику "и".

> db.car.find( {make: "ford", year: "2019"} ).pretty()

{
 "_id" : ObjectId("600c63cf32e0e6419cee81af"),
 "year" : "2019",
 "make" : "ford",
 "color" : "white",
 "km" : 8000,
 "price" : 42000
}


SQL (MySQL):

Аналогично предыдущему примеру. Мы можем объединить несколько условий в операторе WHERE с помощью AND.

mysql> select * from car
    -> where make = "ford" and year = "2019";

+------+------+-------+------+-------+
| year | make | color | km   | price |
+------+------+-------+------+-------+
| 2019 | ford | white | 8000 | 42000 |
+------+------+-------+------+-------+


Пример 3.

Найдите автомобили, произведенные Ford или Hyundai в 2017 году.


NoSQL (MongoDB):

Сначала мы объединяем условие по марке с помощью логики "или", а затем объединяем с годом с помощью логики "и". Для логики "или" можно использовать оператор "$in".

> db.car.find( {make: {$in: ["ford","hyundai"] } , year: "2017"} ).pretty()

{
 "_id" : ObjectId("600c626932e0e6419cee81a7"),
 "year" : "2017",
 "make" : "hyundai",
 "color" : "white",
 "km" : 22000,
 "price" : 32000
}
{
 "_id" : ObjectId("600c63cf32e0e6419cee81ab"),
 "year" : "2017",
 "make" : "ford",
 "color" : "black",
 "km" : 34000,
 "price" : 28000
}


SQL (MySQL):

Условие WHERE принимает оператор "in", поэтому мы можем задавать условия аналогично NoSQL.

mysql> select * from car
    -> where make in ("ford","hyundai") and year = "2017";

+------+---------+-------+-------+-------+
| year | make    | color | km    | price |
+------+---------+-------+-------+-------+
| 2017 | hyundai | white | 22000 | 32000 |
| 2017 | ford    | black | 34000 | 28000 |
+------+---------+-------+-------+-------+


Пример 4.

Вставка нового элемента.


NoSQL (MongoDB):

Функция "insertOne" используется для вставки одного документа в коллекцию. Нам нужно записать пары поле-значение нового документа.

> db.car.insertOne(
... {year: "2017", make: "bmw", color: "silver", 
...  km: 28000, price: 39000}
... )
{
 "acknowledged" : true,
 "insertedId" : ObjectId("600c6bc79445b834692e3b91")
}


SQL (MySQL):

Функция "insert into" используется для добавления новой строки в таблицу. В отличие от NoSQL, нам не нужно писать имена столбцов. Однако порядок значений должен соответствовать порядку столбцов в таблице.

mysql> insert into car values 
    -> ("2017", "bmw", "silver", 28000, 39000);

Query OK, 1 row affected (0.03 sec)


Пример 5.

Обновление марки "bmw" на "BMW".


NoSQL (MongoDB):

Используется функция update. Сначала мы передаем условие, которое указывает на документы, подлежащие обновлению, а затем передаем обновленные значения вместе с ключевым словом set.

> db.car.update(
... { make: "bmw" },
... { $set: { make: "BMW" }},
... { multi: true }
... )
WriteResult({ "nMatched" : 5, "nUpserted" : 0, "nModified" : 5 })

Нам необходимо использовать параметр multi для обновления всех документов, удовлетворяющих заданному условию. В противном случае будет обновлен только один документ.


SQL (MySQL):

Мы используем код, как показано ниже:

mysql> update car
    -> set make = "BMW"
    -> where make = "bmw";

Query OK, 5 rows affected (0.05 sec)
Rows matched: 5  Changed: 5  Warnings: 0


Пример 6.

И SQL, и NoSQL очень универсальны в плане агрегации данных при запросе к базе данных. Например, мы можем легко рассчитать среднюю цену для каждого бренда.


NoSQL (MongoDB):

Мы используем функцию aggregate.

> db.car.aggregate([
... { $group: { _id: "$make", avg_price: { $avg: "$price" }}}
... ])

{ "_id" : "hyundai", "avg_price" : 36333.333333333336 }
{ "_id" : "BMW", "avg_price" : 47400 }
{ "_id" : "ford", "avg_price" : 35333.333333333336 }

Сначала мы группируем документы по маркам, выбирая "$make" в качестве id. В следующей части указывается агрегатная функция, которая в нашем случае равна "$avg", и поле для агрегации.

Если вы знакомы с Pandas, то синтаксис очень похож на функцию groupby.


SQL (MySQL):

Оператор GROUP BY используется для группировки строк на основе категорий в заданном столбце. При выборе столбца применяется агрегатная функция.

mysql> select make, avg(price)
    -> from car
    -> group by make;

+---------+------------+
| make    | avg(price) |
+---------+------------+
| BMW     | 47400.0000 |
| ford    | 35333.3333 |
| hyundai | 36333.3333 |
+---------+------------+


Пример 7.

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


NoSQL (MongoDB):

Нам просто нужно добавить ключевое слово match, чтобы задать условие.

> db.car.aggregate([
... { $match: { year: "2019" }},
... { $group: { _id: "$make", avg_price: { $avg: "$price" }}}
... ])
{ "_id" : "BMW", "avg_price" : 53000 }
{ "_id" : "ford", "avg_price" : 42000 }
{ "_id" : "hyundai", "avg_price" : 41000 }


SQL (MySQL):

Мы используем операторы WHERE и GROUP BY, как показано ниже:

mysql> select make, avg(price)
    -> from car
    -> where year = "2019"
    -> group by make;
+---------+------------+
| make    | avg(price) |
+---------+------------+
| BMW     | 53000.0000 |
| ford    | 42000.0000 |
| hyundai | 41000.0000 |
+---------+------------+


Заключение

Мы рассмотрели примеры, демонстрирующие базовые операции с базами данных SQL и NoSQL.

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


Оригинал статьи: https://towardsdatascience.com/sql-vs-nosql-in-8-examples-25aebcf49922

Report Page