Базы данных

Мохов Олег
Разработчик интерфейсов

SQL

Теорема Брюера

Теорема Брюера

эвристическое утверждение о том, что в любой реализации распределённых вычислений возможно обеспечить не более двух из трёх следующих свойств:

  • согласованность данных (англ. consistency) — во всех вычислительных узлах в один момент времени данные не противоречат друг другу;
  • доступность (англ. availability) — любой запрос к распределённой системе завершается корректным откликом;
  • устойчивость к разделению (англ. partition tolerance) — расщепление распределённой системы на несколько изолированных секций не приводит к некорректности отклика от каждой из секций.

CAP-теорема

NoSQL

MongoDB

humongous – огромный

  • документо-ориентированное хранение данных (JSON-подобная схема)
  • не требует описания схем данных
  • JavaScript в качестве языка запросов к базе данных

Установка

https://www.mongodb.org/downloads

CRUD

  • create – insert()
  • read – find()
  • update – update()
  • delete – remove()
  • help()

Создание таблицы

CREATE TABLE students (
    id MEDIUMINT NOT NULL
    AUTO_INCREMENT,
    name Varchar(30),
    nickname Varchar(30),
    group Varchar(30),
    PRIMARY KEY (id)
)

db.students.insert({
    name: 'Дарья',
    nickname: 'Пиратка',
    group: 'ПИ-401'
})
            

Выборка данных

SELECT *
FROM students

db.students.find()

ObjectID

db.students.find()
{
    "_id" : ObjectId("56cc30e2e52c943bf62fff72"),
    "name" : "Дарья",
    "nickname" : "Пиратка",
    "group" : "ПИ-401"
}
            
ObjectId("56cc30e2e52c943bf62fff72")
56cc30e2 – time
e52c94 – mid
3bf6 – pid
2fff72 – inc

56cc30e2 e52c94 3bf6 2fff72
56cc3503 e52c94 3bf6 2fff73
            

Любой процесс на любой машине сам отвечает за генерацию ID'шников и не вступает в конфликты с другими.

MongoDB = JavaScript

db.students.insert
function ( obj , options, _allow_dot ){
    if ( ! obj )
        throw "no object passed to insert!";

    var flags = 0;

    var wc = undefined;
    var allowDottedFields = false;
    if ( options === undefined ) {
        // do nothing
    }
    /* и ещё куча кода */

    return result;
}
    

MongoDB = JavaScript

function insertStudent(name, nickname, group) {
    var year = group.split('-').pop().slice(0, 1);
    db.students.insert({
        name: name,
        nickname: nickname,
        group: group,
        year: year
    });
}

        

MongoDB = JavaScript

insertStudent('Пётр', 'petr', 'МТ-204')
db.students.find()
{
    "_id" : ObjectId("56cc30e2e52c943bf62fff72"),
    "name" : "Дарья",
    "nickname" : "Пиратка",
    "group" : "ПИ-401"
}
{
    "_id" : ObjectId("56cc3a2ae52c943bf62fff74"),
    "name" : "Пётр",
    "nickname" : "petr",
    "group" : "МТ-204",
    "year" : "2"
}

Выборка данных

SELECT *
FROM students
WHERE group = "ПИ-301"

db.students.find({
    group: 'ПИ-301'
})

Выборка данных

SELECT github
FROM students
WHERE group = "ПИ-301"

db.students.find({
    group: 'ПИ-301'
}, {github: 1})

Выборка данных – операторы

SELECT *
FROM students
WHERE course < 3

db.students.find({
    course: { $lt : 3 }
})

Операторы

$neне равно
$lt, $lte, $gt, $gte<, ≤, >, ≥
$existsсуществование поля
$allсоответствие всем элементам массива
$inсоответствие хотя бы одному элементу массива
$ninсоответствие ни одному элементу массива
$orили
$norне или
Документация по операторам

Выборка данных – регулярные выражения

SELECT *
FROM students
WHERE group like "%КН%"

db.students.find({
    group: /КН/
})

Выборка данных – булевы операции

SELECT *
FROM students
WHERE course = "2"
OR group = "ПИ-401"

db.students.find({
    $or: [
        { course: '2' },
        { group: 'ПИ-301' }
    ]
})

Поиск по вложенным документам


{
    name: 'Дарья',
    course : 4,
    group : 'ПИ-401',
    grades: {
        javascript: [1,0.5,1,1,1,0.5,1,1,0.5,1],
        verstka: [1,1,1,1,1,0.5,1,0.5,0.5,0.5]
    }
}

db.students.find({
    "grades.javascript.9": 1
})

Обновление

UPDATE students
SET course = "3"
WHERE group like "%30%"

db.students.update({
    group: /3\d{2}/
}, {
    $set: {
        course: "3"
    }
}, {
    multi: true
})

Обновление – инкремент

UPDATE students
SET course = course + 1

db.students.update({
}, {
    $inc: {
        course: 1
    }
}, {
    multi: true
})

Удаление

DELETE from students
WHERE course = "1"

db.students.remove({
    course: 1
})

SQL to MongoDB

SQL to MongoDB Mapping Chart

Индексы

Индексы - база телефонов


db.phones.find({display: “+1 800-5650001”}).explain()

{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 0,
    "nscannedObjects" : 41974,
    "nscanned" : 41974,
    "nscannedObjectsAllPlans" : 41974,
    "nscannedAllPlans" : 41974,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 327,
    "nChunkSkips" : 0,
    "millis" : 30,
    "server" : "130.193.40.246-vpna.dhcp.yndx.net:27017",
    "filterSet" : false
}

Индексы - база телефонов


> db.phones.createIndex(
    { display : 1 },
    { unique : true }
)

Индексы - база телефонов


> db.phones.find({display: “+1 800-5650001”}).explain()

{
	"cursor" : "BtreeCursor display_1",
	"isMultiKey" : false,
	"n" : 0,
	"nscannedObjects" : 0,
	"nscanned" : 0,
	"nscannedObjectsAllPlans" : 0,
	"nscannedAllPlans" : 0,
	"scanAndOrder" : false,
	"indexOnly" : false,
	"nYields" : 0,
	"nChunkSkips" : 0,
	"millis" : 7,
	"indexBounds" : {
		"display" : [
			[
				"+1 800-5650001",
				"+1 800-5650001"
			]
		]
	},
	"server" : "130.193.40.246-vpna.dhcp.yndx.net:27017",
	"filterSet" : false
}

Индексы дорогая операция!

Репликация и шардирование

Репликация

Репликация

Шардирование

Range Based шардирование

Hash Based шардирование

Range Based vs Hash Based

  • Range Based проще настроить, но возможно неравномерное распределение данных
  • Hash Based «соседние данные скорее всего будут в разных шардах», зато распределение максимально равномерно

JOIN

JOIN

Нормализация и денормализация

Транзакции и конкурентность

MongoDriver

MongoDriver

Для чего нужно и не нужно использовать?

Сильные стороны MongoDB

  • Большие объемы данных
  • Гибкая модель данных (schemeless)
  • Простота

Слабые стороны MongoDB

  • Нормализация

Так для чего нужно?

  • Быстрые прототипы
  • Блоги
  • Эксперименты
  • Ваш проект на хакатоне

ДЗ

webdev-tasks-2

Спасибо