Версионность данных в БД mySQL

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
В общем написал сюда, а не в форум по mySQL, ибо вопрос по PHP в том числе.

Есть некоторое количество сущностей, задачи, люди, новости, проекты, которые хранятся в таблицах вида todo/persons/news/projects со своим набором полей у каждой сущности.

Необходимо сделать историю изменения каждой сущности с возможностью отслеживать изменения каждого отдельного поля (например, поле title у новости), так и с возможностью построения своего рода ньюзфида, где было бы написано, кто и что изменил в той или иной записи.

Помимо этого у новостей имеются привязанные профили компаний, то есть запись 1-к-нескольким. Одна новость - дофига компаний к которым она относится. Связки тоже надо обложить версионностью.

Собственно сабж, кто как делал подобное?
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Пока было предложение хранить данные в подобном виде:

Но есть сомнения в правильности подхода.

Код:
--
-- Table structure for table `log`
--

CREATE TABLE IF NOT EXISTS `log` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `type` varchar(20) NOT NULL,
  `property` varchar(50) NOT NULL,
  `entity_id` int(11) unsigned NOT NULL,
  `value` text NOT NULL,
  `version` int(11) unsigned NOT NULL,
  `date` datetime NOT NULL,
  `author` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `type` (`type`),
  KEY `property` (`property`),
  KEY `entity_id` (`entity_id`),
  KEY `version` (`version`),
  KEY `author` (`author`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=15 ;

--
-- Dumping data for table `log`
--

INSERT INTO `log` (`id`, `type`, `property`, `entity_id`, `value`, `version`, `date`, `author`) VALUES
(1, 'news', 'title', 1, 'test', 1, '2013-01-16 12:00:00', 1),
(2, 'news', 'url', 1, 'url', 1, '2013-01-16 12:00:00', 1),
(3, 'news', 'annotation', 1, 'annotation', 1, '2013-01-16 12:00:00', 1),
(4, 'news', 'companies', 1, '1', 1, '2013-01-16 12:00:00', 1),
(5, 'news', 'companies', 1, '2', 1, '2013-01-16 12:00:00', 1),
(6, 'news', 'companies', 1, '3', 1, '2013-01-16 12:00:00', 1),
(7, 'news', 'companies', 1, '4', 1, '2013-01-16 12:00:00', 1),
(8, 'news', 'companies', 1, '5', 1, '2013-01-16 12:00:00', 1),
(9, 'news', 'title', 1, 'test1', 2, '2013-01-16 13:00:00', 1),
(10, 'news', 'url', 1, 'url1', 2, '2013-01-16 13:00:00', 1),
(11, 'news', 'annotation', 1, 'annotation1', 2, '2013-01-16 13:00:00', 1),
(12, 'news', 'companies', 1, '1', 2, '2013-01-16 13:00:00', 1),
(13, 'news', 'companies', 1, '3', 2, '2013-01-16 13:00:00', 1),
(14, 'news', 'companies', 1, '5', 2, '2013-01-16 13:00:00', 1);
 

fixxxer

К.О.
Партнер клуба
Как-то сложно, это что, все руками делать?

Я бы, наверное, сделал копии всех версионируемых табличек с суффиксом _log и добавлением поля version, и складывал туда копии триггерами (или их аналогом на уровне приложения).

Изменения полей можно уже потом высчитывать. Связанные изменения - ну, например, версионировать не отдельной табличкой, а сиквенсом в рамках транзакции.
 
  • Like
Реакции: WMix

craz

Нестандартное звание
Ага надо выталкивать измененные записи в такие таблички...
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Копии сделать была идея, так же как и хранить историю подобно EAV с указаниями типов сущности, к которым мы храним историю.

Вопрос в том, что у нас жуе довольно много записей копится, новосте > 50k людей и проектов > 2k
Далее не хотелось бы джоинить такие таблицы в выборках. Вот пока думаем. Тяжело идет, у нас тут переезд в офисе и полный здец. Голова как кубик
 
Сверху