БОЛЬ УЖАС И БЕЗSQLНОСТЬ
МИНУТКА БОЯНОВ
Реляционные (от Oracle до sqlite)
● отношения и нормализация
● связи отношений и ограничения
● ACID
● 12*
правил Кодда
● SQL
● 2 БББ*
MySQL
Postgre
Mongo DB
*
Но это не точно
МИНУТКА БОЯНОВ
Нереляционные (NoSQL)
● document (mongodb, orientdb)
● графовые (orientdb, neo4j)
● key-value (redis, memcache)
...тысячи их
● JS, Cypher, API любого языка
● динамическая схема данных
● специфические модели данных
○ колонки (без кортежей)
○ графы
○ иерархические данные
○ ключ-значение
MySQL
Mongo DB
ЗАЧЕМ NOSQL?
● быстрое распределенное чтение
● горизонтальное масштабирование
● шардинг из коробки
● никаких join-ов, агрегаты
● eventual consistency достаточно
● map/reduce
● простые запросы (если это не
графовая БД, конечно)
● атрибуты ↔ виды документов
● атрибуты ↔ виды атрибутов
● атрибуты ↔ тип значения
● связи с внешними сущностями
В простейших запросах в среднем
ГИТЛЕРИАРД
join-ов.
ХРАНИМ ДОКУМЕНТ В RDBMS
ВЫБИРАЕМ ДОКУМЕНТ:
select *
from document_info d
join document_type dt on ..
join document_type_attribute dta ..
join document_attribute da ..
join document_datetime_attribute ddta
on ddta.id = ...
… N штук типов семантик
join organization_documents od on
od.id_dts = dta.id and …
… M штук типов ссылок на сущности
MEANWHILE IN MONGO AND NEO4J:
db.documents.insert ({
id: ObjectId (“507f1f77bcf86cd799439011”) ,
title: “Разрешение на использование” ,
validDue: Date (“11/11/11”) ,
by: ObjectId (“348f1f7bcf86cd799434893”) ,
for: [ObjectId (“348f1f7bcf86cd799434893”) ,
...
]
...
});
db.documents.find({title: {$regex:
/^М/}}).sort({title: 1});
MATCH (grantedBy :Organization :Inspection {name:
“РЧС”})
MATCH(issuedFor :Organization :PublicRadio
{name: “Просто Радио”})
CREATE
(issuedFor) - [:PERMIT] ->
(:Document :Permission {title: “РИ”, ...})
-[:ISSUED_BY]->(grantedBy)
MATCH(myPermission :Document) - [:PERMIT] ->
(justRadio: PublicRadio{name: “Просто Радио”})
RETURN myPermission.title, myPermission.validDue
ORDER BY myPermission.validDue
А ЕСЛИ ДАННЫХ ДОХРЕНА?
RDBMS
● мощное железо за все деньги
● репликация (читаем с рабов)
● шардинг (+денормализация)
● горизонтальный шардинг
Все это непросто и дорого!
… но будет ли у вас столько данных?
… нет, 10 миллионов строк это не много.
NOSQL
● просто добавим ноду
● суп из семи Hadoop
… жизнь без наркотиков
… потеря данных не критична
ЭХ! ЗАЖИВЕМ!*
* нет.
МИР БЕЗ НАРКОТИКОВ
A только на уровне документа
С :( нет транзакций - нет и С
I read uncommitted, MDW
D just NO
● read concern levels
● write concern flags (w, j )
● two phase commits (intermediate
data concern)
MySQL
Mongo DB
● primary асинхронно реплицирует на N
secondaries
● узлы сами решают кто главный
● можно получить подтверждение записи
в логах главного или остальных узлов
ценой увеличившейся latency
● и primary УПАЛ.
● если остальные составляют
большинство, то новый primary - узел с
наивысшим optime
● меньшинство видит, что кворума нет,
primary теряет чин, запись на него
невозможна.
● GOOD NEWS - NO SPLIT BRAIN!
ВСЕ ПОШЛО НЕ ТАК
ВСЕ ПОШЛО НЕ ТАК
● на главном есть подтвержденные, но не
реплицированные записи
● сеть вернулась и новый secondary
должен ОТМЕНИТЬ эти операции
Количество отмененных данных зависит от
того, что успело реплицироваться на нового
primary, и это ОЧЕНЬ БОЛЬНО!
(P.S. данные почти наверняка остались в
папке rollbacks).
(P.P.S иногда они просто пропадают и все)
МОЖНО ИСПРАВИТЬ?
● сейчас - ДА!
● строгие read-write concerns на
чувствительных данных
● двухфазные коммиты
Проблемы динамической схемы данных
● атрибуты нетипизированы
● byrthday problem
● sort по полю, содержащему массивы и
одиночные значения
● нужны автотесты, как и в случае
динамических ЯП
ПОЛИТЕИЗМ
● языки NoSQL разные, часто есть только
API на common языках
● модели доступа к данным разные
● нужно искать разработчика, знакомого
именно с выбранной СУБД
МОЛОДОСТЬ
● быстрые изменения фич и API
● нет широкого выбора инструментов
● bleeding edge крутейших технологий,
требующих высокой квалификации
кодеров
● нужно искать УМНОГО разработчика,
знакомого именно с выбранной СУБД
● или УЧИТЬСЯ, УЧИТЬСЯ и УЧИТЬСЯ!
КАК ЖИТЬ?
в этом бардаке?
● Использовать совместно
с классическими СУБД
● Писать автотесты
● Учиться-учиться-учиться!
● Использовать гибридные
решения
P.S. POSTGRESQL 9.3+
● JSON, HSTORE
● restrictions
● where
● indexes
● hadoop connector
CREATE TABLE A (
data JSON
CONSTRAINT validateId CHECK ((data->>'id')::integer
>= 1 AND (data->>'id') IS NOT NULL ),
CONSTRAINT validateName CHECK (length(data->>'name')
> 0 AND (data->>'name') IS NOT NULL )
);
INSERT INTO A(data) VALUES(
'{
"id": 1,
"name": "A",
"age": 49
}');
CREATE UNIQUE INDEX ui_a_id ON a((data->>'id'));
NoSQL pain

NoSQL pain

  • 1.
    БОЛЬ УЖАС ИБЕЗSQLНОСТЬ
  • 2.
    МИНУТКА БОЯНОВ Реляционные (отOracle до sqlite) ● отношения и нормализация ● связи отношений и ограничения ● ACID ● 12* правил Кодда ● SQL ● 2 БББ* MySQL Postgre Mongo DB * Но это не точно
  • 3.
    МИНУТКА БОЯНОВ Нереляционные (NoSQL) ●document (mongodb, orientdb) ● графовые (orientdb, neo4j) ● key-value (redis, memcache) ...тысячи их ● JS, Cypher, API любого языка ● динамическая схема данных ● специфические модели данных ○ колонки (без кортежей) ○ графы ○ иерархические данные ○ ключ-значение MySQL Mongo DB
  • 4.
    ЗАЧЕМ NOSQL? ● быстроераспределенное чтение ● горизонтальное масштабирование ● шардинг из коробки ● никаких join-ов, агрегаты ● eventual consistency достаточно ● map/reduce ● простые запросы (если это не графовая БД, конечно)
  • 5.
    ● атрибуты ↔виды документов ● атрибуты ↔ виды атрибутов ● атрибуты ↔ тип значения ● связи с внешними сущностями В простейших запросах в среднем ГИТЛЕРИАРД join-ов. ХРАНИМ ДОКУМЕНТ В RDBMS
  • 6.
    ВЫБИРАЕМ ДОКУМЕНТ: select * fromdocument_info d join document_type dt on .. join document_type_attribute dta .. join document_attribute da .. join document_datetime_attribute ddta on ddta.id = ... … N штук типов семантик join organization_documents od on od.id_dts = dta.id and … … M штук типов ссылок на сущности
  • 7.
    MEANWHILE IN MONGOAND NEO4J: db.documents.insert ({ id: ObjectId (“507f1f77bcf86cd799439011”) , title: “Разрешение на использование” , validDue: Date (“11/11/11”) , by: ObjectId (“348f1f7bcf86cd799434893”) , for: [ObjectId (“348f1f7bcf86cd799434893”) , ... ] ... }); db.documents.find({title: {$regex: /^М/}}).sort({title: 1}); MATCH (grantedBy :Organization :Inspection {name: “РЧС”}) MATCH(issuedFor :Organization :PublicRadio {name: “Просто Радио”}) CREATE (issuedFor) - [:PERMIT] -> (:Document :Permission {title: “РИ”, ...}) -[:ISSUED_BY]->(grantedBy) MATCH(myPermission :Document) - [:PERMIT] -> (justRadio: PublicRadio{name: “Просто Радио”}) RETURN myPermission.title, myPermission.validDue ORDER BY myPermission.validDue
  • 8.
    А ЕСЛИ ДАННЫХДОХРЕНА? RDBMS ● мощное железо за все деньги ● репликация (читаем с рабов) ● шардинг (+денормализация) ● горизонтальный шардинг Все это непросто и дорого! … но будет ли у вас столько данных? … нет, 10 миллионов строк это не много. NOSQL ● просто добавим ноду ● суп из семи Hadoop … жизнь без наркотиков … потеря данных не критична
  • 9.
  • 10.
    МИР БЕЗ НАРКОТИКОВ Aтолько на уровне документа С :( нет транзакций - нет и С I read uncommitted, MDW D just NO ● read concern levels ● write concern flags (w, j ) ● two phase commits (intermediate data concern) MySQL Mongo DB
  • 11.
    ● primary асинхроннореплицирует на N secondaries ● узлы сами решают кто главный ● можно получить подтверждение записи в логах главного или остальных узлов ценой увеличившейся latency ● и primary УПАЛ. ● если остальные составляют большинство, то новый primary - узел с наивысшим optime ● меньшинство видит, что кворума нет, primary теряет чин, запись на него невозможна. ● GOOD NEWS - NO SPLIT BRAIN! ВСЕ ПОШЛО НЕ ТАК
  • 12.
    ВСЕ ПОШЛО НЕТАК ● на главном есть подтвержденные, но не реплицированные записи ● сеть вернулась и новый secondary должен ОТМЕНИТЬ эти операции Количество отмененных данных зависит от того, что успело реплицироваться на нового primary, и это ОЧЕНЬ БОЛЬНО! (P.S. данные почти наверняка остались в папке rollbacks). (P.P.S иногда они просто пропадают и все)
  • 13.
    МОЖНО ИСПРАВИТЬ? ● сейчас- ДА! ● строгие read-write concerns на чувствительных данных ● двухфазные коммиты
  • 14.
    Проблемы динамической схемыданных ● атрибуты нетипизированы ● byrthday problem ● sort по полю, содержащему массивы и одиночные значения ● нужны автотесты, как и в случае динамических ЯП
  • 15.
    ПОЛИТЕИЗМ ● языки NoSQLразные, часто есть только API на common языках ● модели доступа к данным разные ● нужно искать разработчика, знакомого именно с выбранной СУБД
  • 16.
    МОЛОДОСТЬ ● быстрые измененияфич и API ● нет широкого выбора инструментов ● bleeding edge крутейших технологий, требующих высокой квалификации кодеров ● нужно искать УМНОГО разработчика, знакомого именно с выбранной СУБД ● или УЧИТЬСЯ, УЧИТЬСЯ и УЧИТЬСЯ!
  • 17.
  • 18.
    ● Использовать совместно склассическими СУБД ● Писать автотесты ● Учиться-учиться-учиться! ● Использовать гибридные решения
  • 19.
    P.S. POSTGRESQL 9.3+ ●JSON, HSTORE ● restrictions ● where ● indexes ● hadoop connector CREATE TABLE A ( data JSON CONSTRAINT validateId CHECK ((data->>'id')::integer >= 1 AND (data->>'id') IS NOT NULL ), CONSTRAINT validateName CHECK (length(data->>'name') > 0 AND (data->>'name') IS NOT NULL ) ); INSERT INTO A(data) VALUES( '{ "id": 1, "name": "A", "age": 49 }'); CREATE UNIQUE INDEX ui_a_id ON a((data->>'id'));