2. .
Время и состояние Время и состояние
Существующие решения
Documents
2
.
3. .
Президент Франции Время и состояние
Существующие решения
Documents
Это он!
3
.
4. .
Президент Франции Время и состояние
Существующие решения
Documents
Или он?
4
.
5. .
Президент Франции Время и состояние
Существующие решения
Documents
Нет, он!
5
.
6. .
Но мы привыкли... Время и состояние
Существующие решения
Documents
france.president = u'Francois Hollande'
for (var i = 0; i < 10; i++) {
console.log(' i = ', i);
}
6
.
7. .
Время и состояние
Делаем то же в базе данных Существующие решения
Documents
france.president = u'Francois Hollande'
france.save()
или
france.update(
president=u'Francois Hollande')
7
.
8. .
Мы теряем информацию Время и состояние
Существующие решения
Documents
Кто еще не использует систему контроля версий?
8
.
9. .
Мы теряем информацию Время и состояние
Существующие решения
Documents
Кто может сказать, что было вчера после обеда?
Кто может сказать, что произошло за последние 5 минут?
Кто видел простое кэширование запросов к БД?
9
.
10. .
Невозможно принять решение Время и состояние
Существующие решения
Documents
Невозможно принять решение при постоянном изменении
данных.
Мы хотим получить согласованное состояние:
сравнивая данные из нескольких источников
несколько раз смотря на данные из одного источника
10
.
11. .
Время и состояние
Transaction Isolation (1) Существующие решения
Documents
start transaction
read a bunch of data
...
long computation
...
read more data
...
more computation
end transaction
Deadlocks
вся логика наизнанку
производительность
11
.
12. .
Время и состояние
Transaction Isolation (2) Существующие решения
Documents
Не спасает и тут:
$.get('/x/some-data/', function (data) {
...
});
$.get('/x/other-stuff/', function (other_stuff) {
...
});
12
.
13. .
Существующие решения Время и состояние
Существующие решения
Documents
13
.
14. .
Django tutorial, part 1 Время и состояние
Существующие решения
Documents
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
14
.
15. .
Django apps Время и состояние
Существующие решения
Documents
https://www.djangopackages.com/grids/g/model-audit/:
django-reversion: сериализация в JSON, magic
django-versioning: JSON, сохраняет diff
django-fullhistory: сериализация в JSON
django-audit-log: отдельная таблица с похожей
структурой
15
.
16. .
Время и состояние
Недостатки Существующие решения
Documents
нужна отдельная поддержка массовых операций
видим лишь отдельные версии документов (и то с
трудом)
не можем искать по истории - история это текст
поддержка массовых операций (update, delete)
16
.
17. .
Время и состояние
Documents Существующие решения
Documents
17
.
18. .
Время и состояние
Documents Существующие решения
Documents
Вячеслав Федоров, июль 2010 года
API стабильно с осени 2010 года
используется во всех наших проектах
https://github.com/chtd/doc-versions/
18
.
19. .
Возвращаясь к президентам Время и состояние
Существующие решения
Documents
class Country(Document):
name = models.CharField(max_length=200)
president = models.CharField(max_length=200)
19
.
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
.
21. .
Интервал действия версии Время и состояние
Существующие решения
Documents
21
.
22. .
Менеджер now Время и состояние
Существующие решения
Documents
Мы легко можем получить версии в любой момент времени:
model.now.filter(...)
# транслируется в
dt = retrospection.now()
model.objects.filter(document_start__lte=dt,
document_end__gt=dt)
.filter(...)
22
.
23. .
Время и состояние
Согласованное состояние Существующие решения
Documents
одно время на все выполнение view
используем менеджер now или замену datetime.now() -
retrospection.now() - thread-local время
23
.
24. .
Версии одного документа Время и состояние
Существующие решения
Documents
>>> Country.now.all()
[]
>>> fr = Country(name='France', president='Napoleon III')
>>> fr.document_save()
>>> Country.now.count()
0
24
.
25. .
Продвижение по времени Время и состояние
Существующие решения
Documents
>>> set_now()
>>> Country.now.count()
1
>>> Country.now.get(document_id=1)
<Country: "France under Napoleon III">
25
.
26. .
Редактирование Время и состояние
Существующие решения
Documents
>>> fr.president = 'Nicolas Sarkozy'
>>> fr.document_save()
>>> set_now()
>>> Country.objects.count()
2
>>> Country.now.count()
1
26
.
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
.
28. .
Ретроспекция Время и состояние
Существующие решения
Documents
По умолчанию не нужно делать ничего, а если хочется
странного:
with current_time(datetime(1848, 12, 20)):
return president_detail(fr)
28
.
29. .
Кэширование Время и состояние
Существующие решения
Documents
Основная проблема - инвалидация данных. Два варианта:
по событию изменения данных
зная историю изменений => зная что изменилось
29
.
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
.
31. .
Связанные документы Время и состояние
Существующие решения
Documents
Один документ хранится в нескольких моделях. Документы
ссылаются друг на друга. Виды ссылок между документами:
на версию, действующую в момент создания: при
помощи id
на версию, действующую в текущий момент времени:
при помощи document_id
31
.
32. .
На некоторых моделях Время и состояние
Существующие решения
Documents
Например, auth.models.User не версионируется, а Profile
версионируется. Не версионируются редко меняющиеся
данные.
Плюсы: лучше совместимость со стандартными
библиотеками, более привычная схема данных
Минусы: половинчатое решение, все время нужно
думать о версионировании и переключаться
32
.
33. .
Время и состояние
На всех моделях Существующие решения
Documents
Отказ от стандартного пользователя и админки...
Минусы: начальный порог, реализация своего
пользователя (это не так сложно), немного меньше
поддержки ORM
Плюсы: полное версионирование, о нем не надо думать!
33
.
34. .
Время и состояние
Use case: EAV-модель Существующие решения
Documents
храним граф в реляционной БД (храним ребра)
минимальная схема (по одной модели на каждый тип
данных)
тривиальное кэширование в памяти
очень похожа на Datomic (Rich Hickey, создатель Clojure)
34
.
35. .
Прореживание истории Время и состояние
Существующие решения
Documents
храним фиксированный период
экспоненциальное прореживание
редко бывает проблемой
35
.
36. .
За кадром Время и состояние
Существующие решения
Documents
интеграция с django-админкой
проверка целостности БД
работа с составными документами
36
.
37. .
Основные принципы Время и состояние
Существующие решения
Documents
очень простое решение, нет магии
не боимся отказаться от некоторых привычных вещей
используем возможности БД
37
.