38
Время и состояние Существующие решения Documents . . Подход к версионированию данных в реляционной БД

Константин Лопухин: Подход к версионированию данных в реляционной БД

Embed Size (px)

Citation preview

Page 1: Константин Лопухин: Подход к версионированию данных в реляционной БД

..Время и состояниеСуществующие решенияDocuments

.

..Подход к

версионированиюданных в

реляционной БД

Page 2: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Время и состояние

...2

Page 3: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Президент Франции

Это он!

...3

Page 4: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Президент Франции

Или он?

...4

Page 5: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Президент Франции

Нет, он!

...5

Page 6: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Но мы привыкли...

france.president = u'Francois Hollande'

for (var i = 0; i < 10; i++) {console.log(' i = ', i);

}

...6

Page 7: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Делаем то же в базе данных

france.president = u'Francois Hollande'france.save()

илиfrance.update(

president=u'Francois Hollande')

...7

Page 8: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Мы теряем информацию

Кто еще не использует систему контроля версий?

...8

Page 9: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Мы теряем информацию

I Кто может сказать, что было вчера после обеда?I Кто может сказать, что произошло за последние 5 минут?I Кто видел простое кэширование запросов к БД?

...9

Page 10: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Невозможно принять решение

Невозможно принять решение при постоянном измененииданных.Мы хотим получить согласованное состояние:

I сравнивая данные из нескольких источниковI несколько раз смотря на данные из одного источника

...10

Page 11: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Transaction Isolation (1)

start transactionread a bunch of data...long computation...read more data...more computation

end transaction

I DeadlocksI вся логика наизнанкуI производительность

...11

Page 12: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Transaction Isolation (2)

Не спасает и тут:$.get('/x/some-data/', function (data) {

...});$.get('/x/other-stuff/', function (other_stuff) {

...});

...12

Page 13: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Существующие решения

...13

Page 14: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Django tutorial, part 1

from django.db import models

class Poll(models.Model):question = models.CharField(max_length=200)pub_date = models.DateTimeField('date published')

...14

Page 15: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Django apps

https://www.djangopackages.com/grids/g/model-audit/:I django-reversion: сериализация в JSON, magicI django-versioning: JSON, сохраняет diffI django-fullhistory: сериализация в JSONI django-audit-log: отдельная таблица с похожей

структурой

...15

Page 16: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Недостатки

I нужна отдельная поддержка массовых операцийI видим лишь отдельные версии документов (и то с

трудом)I не можем искать по истории - история это текстI поддержка массовых операций (update, delete)

...16

Page 17: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Documents

...17

Page 18: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Documents

I Вячеслав Федоров, июль 2010 годаI API стабильно с осени 2010 годаI используется во всех наших проектахI https://github.com/chtd/doc-versions/

...18

Page 19: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Возвращаясь к президентам

class Country(Document):name = models.CharField(max_length=200)president = models.CharField(max_length=200)

...19

Page 20: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Наследуем от

class Document(models.Model):document_start = models.DateTimeField(

'Time of the start of this version')document_end = models.DateTimeField(

'Time of the end of this version')document_id = models.IntegerField(

'Document identifier')class Meta:

abstract = True

...20

Page 21: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Интервал действия версии

...21

Page 22: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Менеджер now

Мы легко можем получить версии в любой момент времени:model.now.filter(...)# транслируется вdt = retrospection.now()model.objects.filter(document_start__lte=dt,

document_end__gt=dt).filter(...)

...22

Page 23: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Согласованное состояние

I одно время на все выполнение viewI используем менеджер now или замену datetime.now() -

retrospection.now() - thread-local время

...23

Page 24: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Версии одного документа

>>> Country.now.all()[]>>> fr = Country(name='France', president='Napoleon III')>>> fr.document_save()>>> Country.now.count()0

...24

Page 25: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Продвижение по времени

>>> set_now()>>> Country.now.count()1>>> Country.now.get(document_id=1)<Country: "France under Napoleon III">

...25

Page 26: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Редактирование

>>> fr.president = 'Nicolas Sarkozy'>>> fr.document_save()>>> set_now()>>> Country.objects.count()2>>> Country.now.count()1

...26

Page 27: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

И удаление

>>> fr.document_delete() # not for real>>> set_now()>>> Country.objects.count()2>>> Country.now.count()0>>> fr.document_restore() # uff>>> Country.now.count()1

...27

Page 28: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Ретроспекция

По умолчанию не нужно делать ничего, а если хочетсястранного:with current_time(datetime(1848, 12, 20)):

return president_detail(fr)

...28

Page 29: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Кэширование

Основная проблема - инвалидация данных. Два варианта:I по событию изменения данныхI зная историю изменений => зная что изменилось

...29

Page 30: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Кэширование

Тривиально отследить изменения:created = model.objects.filter(

document_start__gte=last_sync)deleted = model.objects.filter(

document_end__gte=last_sync,document_end__lt=FUTURE)

last_sync = datetime.now()

...30

Page 31: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Связанные документы

Один документ хранится в нескольких моделях. Документыссылаются друг на друга. Виды ссылок между документами:

I на версию, действующую в момент создания: припомощи id

I на версию, действующую в текущий момент времени:при помощи document_id

...31

Page 32: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

На некоторых моделях

Например, auth.models.User не версионируется, а Profileверсионируется. Не версионируются редко меняющиесяданные.

I Плюсы: лучше совместимость со стандартнымибиблиотеками, более привычная схема данных

I Минусы: половинчатое решение, все время нужнодумать о версионировании и переключаться

...32

Page 33: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

На всех моделях

Отказ от стандартного пользователя и админки...I Минусы: начальный порог, реализация своего

пользователя (это не так сложно), немного меньшеподдержки ORM

I Плюсы: полное версионирование, о нем не надо думать!

...33

Page 34: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Use case: EAV-модель

I храним граф в реляционной БД (храним ребра)I минимальная схема (по одной модели на каждый тип

данных)I тривиальное кэширование в памятиI очень похожа на Datomic (Rich Hickey, создатель Clojure)

...34

Page 35: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Прореживание истории

I храним фиксированный периодI экспоненциальное прореживаниеI редко бывает проблемой

...35

Page 36: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

За кадром

I интеграция с django-админкойI проверка целостности БДI работа с составными документами

...36

Page 37: Константин Лопухин: Подход к версионированию данных в реляционной БД

..

Время и состояниеСуществующие решенияDocuments

Основные принципы

I очень простое решение, нет магииI не боимся отказаться от некоторых привычных вещейI используем возможности БД

...37

Page 38: Константин Лопухин: Подход к версионированию данных в реляционной БД

..Время и состояниеСуществующие решенияDocuments

.

https://github.com/chtd/doc-versionsКонстантин Лопухин

[email protected]Вячеслав Федоров

[email protected]

... . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .