БОЛЬ УЖАС И БЕЗSQLНОСТЬ
МИНУТКА БОЯНОВРеляционные (от Oracle до sqlite)● отношения и нормализация● связи отношений и ограничения● ACID ● 12* правил Кодда● SQL● 2 БББ*
MyS
QL
Postgre
Mongo DB
* Но это не точно
МИНУТКА БОЯНОВНереляционные (NoSQL)● document (mongodb, orientdb)● графовые (orientdb, neo4j)● key-value (redis, memcache)
...тысячи их● JS, Cypher, API любого языка ● динамическая схема данных● специфические модели данных
○ колонки (без кортежей)○ графы○ иерархические данные○ ключ-значение
M
ySQ
L
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, MDWD just NO
● read concern levels● write concern flags (w, j )● two phase commits (intermediate
data concern)
MyS
QL
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'));
Top Related