День 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.
Ссылки дня:
- Учебник/справочник по SQL: https://html5css.ru/sql/default.php
- Telegram-канал про SQL: https://t.me/db_guides
- Уроки по MongoDB: https://metanit.com/nosql/mongodb/1.1.php