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