Главная » Заметки » День 24. Немного про SQL и чуть больше про MongoDB
День 24. Немного про SQL и чуть больше про MongoDB
Автор статьи никого не призывает к правонарушениям и отказывается нести ответственность за ваши действия. Вся информация предоставлена исключительно в ознакомительных целях. Все действия происходят на виртуальных машинах и внутри локальной сети автора. Спасибо!

В системах с реляционной моделью данных используется высокоуровневое средство выполнения запросов – язык SQL. Да, кстати, продолжаю чтение четвертой главы книги Б.А. Новикова, Е.А. Горшкова, Н.Г. Графеева «Основы технологий баз данных. 2 изд.».

Оператор CREATE TABLE пропускаю. Его вчера вспомнил. Далее речь заходит про ALTER. Он предназначен для добавления, переименования или удаления отдельных атрибутов таблицы, а также для управления ограничениями целостности. Кстати о них. В языке SQL существуют следующие ограничения целостности:

  • NOT NULL – его использовал вчера. Предназначен для запрета появления неопределенных значений атрибута. То есть столбец не будет принимать значение NULL (обязательно к заполнению);
  • UNIQUE – говорит само за себя – все значения в столбце должны различаться;
  • PRIMARY KEY – чем-то похоже на предыдущий. Первичный ключ, который однозначно идентифицирует каждую запись в таблице. Таблица может иметь только один первичный ключ неравный NULL.
  • FOREIGN KEY – ключ, который связывает две таблицы между собой. Т.е. это поле, которое ссылается на первичный ключ в другой таблице. Таблица с таким полем называется дочерней.
  • CHECK – предназначено для ограничения диапазона значений для столбца;
  • DEFAULT – для автоматического добавления значения по умолчанию, если оно не будет указано.

Кстати, это хорошо расписано на этом сайте: https://html5css.ru/sql/default.php. В учебнике слишком мудрено написано.

В целом, цель достигнута. Не вижу смысла переписывать справочник. Всегда к нему можно обратиться. Теперь перейду к знакомству с MongoDB.

Знакомство с MongoDB

В MongoDB нет таблиц, запросов SQL и прочего, что присуще реляционным базам данных. Разумеется, MongoDB подходит для каких-то задач лучше, а для каких-то – хуже. Например, если необходимо хранить сложные по структуре данные – MongoDB отлично подойдет. Так же MongoDB может быть распределенной системой и физически храниться на разных серверах, сохраняя целостность. Способ хранения данных в MongoDB похож на JSON и называется BSON (binary JSON). Такой формат хранения более объемный в плане занимаемого места, но это компенсируется скоростью выполнения поиска и обработки.

MongoDB написана на С++, поэтому является кроссплатформенной.

Реляционные базы хранят строки, а MongoDB – документы. Но об этом уже было (о хранении сложных структур).

В MongoDB, по аналогии с реляционными СУБД есть у каждого документа специальный идентификатор _id, он же первичный ключ.

В SQL – таблицы, в MongoDB – коллекции. Смысл, в целом, тот же.

Понятие «репликация» в MongoDB. Система хранения в MongoDB представляет собой набор реплик, в которых есть основной и вторичные узлы. Вторичные узлы обновляются автоматически в соответствии с основным узлом. Вторичные узлы могут замещать основной при необходимости.

В СУБД иногда возникает необходимости хранить данные большого размера. В MySQL с этим поможет BLOB. MongoDB предоставляет возможность хранить данные до 16 Мб. Если необходимо хранить более 16 Мб, то здесь поможет GridFS, состоящий из двух коллекций: первая хранит имена файлов и метаданные, вторая, в виде небольших сегментов, данные файлов. В пакете с MongoDB идет специальная утилита mongofiles.

Настало время скачать MongoDB. После загрузки открываем папку bin. В ней оказывается несколько программ: mongo – клиент, mongod – сервер и mongos – служба маршрутизации.

Создаем папку по пути S:\data\db и запускаем сервер. Сама программа у меня лежит на диске S. Немного попишем в консоли.

> use test
switched to db test
> db.users.insertOne({name: "Tom"})
{
        "acknowledged" : true,
        "insertedId" : ObjectId("62dd6798948652865fc3f6c3")
}
> db.users.find()
{ "_id" : ObjectId("62dd6798948652865fc3f6c3"), "name" : "Tom" }
> use test
switched to db test
> db.users.insertOne({name: "Иван"})
{
        "acknowledged" : true,
        "insertedId" : ObjectId("62dd67ee948652865fc3f6c4")
}
> db.users.find()
{ "_id" : ObjectId("62dd6798948652865fc3f6c3"), "name" : "Tom" }
{ "_id" : ObjectId("62dd67ee948652865fc3f6c4"), "name" : "Иван" }

Слегка непривычно, но в целом все понятно. Кстати, сейчас я читаю о MongoDB на этом сайте (https://metanit.com/nosql/mongodb/1.2.php), достаточно понятно написано.

Первая команда (use test) устанавливает используемую базу данных. Далее обращение к db будет представлять базу данных test. Во второй команде users – название коллекции (таблицы), в которую вставляем один объект. В SQL таблицы следует создавать заранее, в MongoDB – нет. В результате выполнения операции, в консоль был выведен уникальный идентификатор объекта.

Команда find() выводит все объекты из коллекции users. Консоль — это хорошо, но лучше для взаимодействия использовать какой-нибудь высокоуровневый язык программирования. Наверное, Python или C++, решу чуть позже. Все же Python, ни к чему усложнять.

Кстати, для MongoDB есть графический клиент. Называется MongoDB Compass.

Считаю нужно пробежаться по основам и попробовать взаимодействовать на Python с MongoDB. Глубже вникать нет необходимости.

Модель БД MongoDB очень проста: База данных -> Коллекция -> Документ. Коллекций может быть n-ое количество, как и документов.

Каждая коллекция имеет уникальное имя. Документ представляет собой пару ключ: значение.

Важный нюанс, запросы в MongoDB обладают регистрозависимостью и строгой типизацией.

Уникальный идентификатор задается автоматически. Так же можно задавать его вручную, но при этом он должен быть уникальным в пределах коллекции. Если попробовать добавить два документа с одинаковыми _id, то первый добавится, а второй вызовет ошибку.

Кстати, о недостатках MongoDB – он не поддерживает отношения между сохраненными данными, поэтому трудно выполнить ACID. Т.е. могут возникнуть проблемы с согласованностью.

Параллельно с изучением основ, установим PyMongo, который необходим для работы в Python с MongoDB.

pip install pymongo

Теперь запустим сервер MongoDB и перейдем к написанию кода на Python. Подключимся к базе данных test:

from pymongo import MongoClient

client = MongoClient('localhost', 27017)
db = client['test']

Далее получим коллекцию users:

series_collection = db['users']

Теперь найдем в коллекции документы, где поле name равно «Иван»:

results = series_collection.find({'name': 'Иван'})
for item in results:
    print(item)

В итоге получилось:

from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client['test']
series_collection = db['users']
results = series_collection.find({'name': 'Иван'})
for item in results:
    print(item)

Теперь попробуем изменить поле. Часть кода взял с сайта (https://dev-gang.ru/article/integracija-mongodb-s-python-s-ispolzovaniem-pymongo-9hmv4a77cw/), на котором хорошо расписаны моменты работы с MongoDB на Python.

from pymongo import MongoClient

def insert_doc(collection, data):
    return collection.insert_one(data).inserted_id

def find_doc(collection, element):
    results = collection.find(element)
    return [r for r in results]

def update_doc(collection, query_elements, new_values):
    collection.update_one(query_elements, {'$set': new_values})

client = MongoClient('localhost', 27017)
db = client['test']

series_collection = db['users']

list_result = find_doc(series_collection, {'name': 'Tom'})
id = list_result[0]['_id']
update_doc(series_collection, {'_id': id}, {'name': 'Петр'})

print(find_doc(series_collection, {'_id': id}))

Для удаления документа используется метод delete_one(). Например, чтобы пройтись по всей коллекции и добавить новое поле, например, возраст, можно сделать следующим образом:

def update_doc(collection, query_elements, new_values):
    collection.update_one(query_elements, {'$set': new_values})

client = MongoClient('localhost', 27017)
db = client['test']

series_collection = db['users']

r = series_collection.find()
for item in r:
    update_doc(series_collection, {'_id':item['_id']}, {'age': 0})

r = series_collection.find()
print([i for i in r])

Так же можно использовать регулярные выражения при поиске. Результатом поиска являются курсоры, которые хранят наборы полученных значений, с которыми можно работать. Их мы в список превращали при помощи списковых включений.

Про условные и логические операторы хорошо написано здесь (https://metanit.com/nosql/mongodb/2.8.php).

В целом MongoDB достаточно проста в использовании. Поэтому на сегодня хватит. Завтра буду разбираться с Microsoft SQL Server.

Ссылки дня:

  1. Учебник/справочник по SQL: https://html5css.ru/sql/default.php
  2. Telegram-канал про SQL: https://t.me/db_guides
  3. Уроки по MongoDB: https://metanit.com/nosql/mongodb/1.1.php
Просмотров: 33
19.07.2022
Автор