Пока @WW. ответ - хороший ответ. Другой способ - создать столбец версий и сохранить все версии в одной таблице.
Для одного подхода к столу вы либо:
- Используйте флажок для обозначения последней буквы Word Press
- ИЛИ сделать противную версию
outer join
.
Пример SQL метода outer join
с использованием номеров ревизий:
SELECT tc.*
FROM text_content tc
LEFT OUTER JOIN text_content mc ON tc.path = mc.path
AND mc.revision > tc.revision
WHERE mc.revision is NULL
AND tc.path = '/stuff' -- path in this case is our natural id.
Плохая новость заключается в том, что выше требуется outer join
, а внешние соединения могут быть медленными. Хорошей новостью является то, что создание новых записей теоретически дешевле, потому что вы можете сделать это в одной операции записи без транзакций (при условии, что ваша база данных является атомарной).
Примером новой редакции для '/stuff'
может быть:
INSERT INTO text_content (id, path, data, revision, revision_comment, enabled, create_time, update_time)
(
SELECT
(md5(random()::text)) -- {id}
, tc.path
, 'NEW' -- {data}
, (tc.revision + 1)
, 'UPDATE' -- {comment}
, 't' -- {enabled}
, tc.create_time
, now()
FROM text_content tc
LEFT OUTER JOIN text_content mc ON tc.path = mc.path
AND mc.revision > tc.revision
WHERE mc.revision is NULL
AND tc.path = '/stuff' -- {path}
)
Вставляем, используя старые данные. Это особенно полезно, если, например, вы хотите обновить только один столбец и избежать оптимистической блокировки и / или транзакций.
Подход с использованием флагов и таблицы истории требует две строки для вставки / обновления.
Другое преимущество подхода outer join
с номером ревизии заключается в том, что вы всегда можете рефакторинг для подхода с несколькими таблицами позже с помощью триггеров, потому что ваш триггер должен, по сути, делать что-то подобное выше.