Какой хороший способ обеспечить версионные строки в PostgreSQL?Как запросить их? - PullRequest
3 голосов
/ 13 февраля 2012

Я хочу хранить разные версии разных текстов и других данных в таблице. Для текстов моя таблица выглядит так:

id BigSerial, PRIMARY KEY  
version Integer  
text Text  
origin BigInt

Теперь я хочу хранить разные версии текстов в этой таблице, например:

1,0,"My Text, first Version",null  
2,1,"My Text, second Version",1  
3,0,"My 2nd Text v1",null  
4,1,"My 2nd Text v2",3

Я пока не знаю, как запросить строку с наибольшим номером версии для каждого набора текстов.

Ответы [ 3 ]

3 голосов
/ 13 февраля 2012

Идентификационный номер Bigserial бесполезен.

create temp table my_table (
  id integer not null,
  version integer not null check(version > 0),
  -- Give a lot of thought to whether text should also be unique. *I* think
  -- it probably should, but it's really application-dependent.
  text Text not null unique,
  primary key (id, version)
);

insert into my_table values 
(1, 1, 'My Text, first Version'),
(1, 2, 'My Text, second Version'),
(2, 1, 'My 2nd text v1'),
(2, 2, 'My 2nd text v2')

Количество версий для каждого идентификатора.

select id, count(*)
from my_table
group by id;

Текущая версия для каждого идентификатора.

with current_ver as (
  select id, max(version) as version
  from my_table
  group by id
)
select m.* from my_table m
inner join current_ver c on c.id = m.id and c.version = m.version

Хотя я написал это с помощью общего табличного выражения, вы, вероятно, захотите создать представление о текущих версиях.Я думаю, что большинству приложений, которые получают доступ к этим данным, потребуется текущая версия.

2 голосов
/ 13 февраля 2012

Поскольку не все наборы текстов могут получать новые версии с одинаковой скоростью, нет реального способа сделать утверждение по номеру версии, который не должен был бы включать как идентификатор, так и источник.

Например, чтобы знать, что «5» - это последняя версия определенного текстового набора, вам нужно будет установить, что «6» не существует. Способ сделать это - посмотреть, есть ли строка с версией «6», которая имеет происхождение от строки с версией «5». Но это просто сводится к тому, чтобы найти строку, у которой нет другой строки, претендующей на то, что она является исходной точкой; вам не нужен номер версии.

Итак, вы можете перефразировать вопрос «есть ли у меня самый высокий номер версии», как «нет ли другой строки, в которой мой идентификатор указан в качестве источника». Если другой строки нет, то это ваша самая новая строка, и вы можете вернуть свой результат. Вы можете выполнить это с помощью следующего запроса:

select t.id 
from table parent
left join table descendants on parent.id = descendants.origin 
where descendants.id is null;

Единственными строками в итоговой объединенной таблице, в которой значение параметра downndant.id будет нулевым, являются самые новые. Обратите внимание, что оба родителя и потомки имеют псевдонимы из одной и той же таблицы. Это то, что называется «самостоятельным объединением», и его удобно делать, когда у вас есть иерархические данные (например, механизм управления версиями), хранящиеся в одной таблице.

Стоит отметить, однако, что это находит только самую новую версию для вас. Если вы хотите узнать , какая это версия, то вам определенно будет полезен столбец версии. В противном случае вам придется выполнять рекурсивный запрос, так как вы не будете заранее знать всю глубину списка версий. Никто не любит их писать.

Надеюсь, это поможет.

0 голосов
/ 22 мая 2016

Временные таблицы * Расширение 1002 * может помочь, если вы не хотите бросать свои собственные, которые ...

https://github.com/arkhipov/temporal_tables

...