
Lev
27.04.2018
11:34:42
это если ID монотонно возрастают. Или хранить timestamp создания и последнего обновления

Yaroslav
27.04.2018
11:35:04

Darafei
27.04.2018
11:35:23
удаляйте просмотренные записи

Ibosh
27.04.2018
11:35:26

Google

Ibosh
27.04.2018
11:35:36

Сергей
27.04.2018
11:35:59

Yaroslav
27.04.2018
11:36:09
именно
Ничего себе! Слушайте, а вам это зачем?

Darafei
27.04.2018
11:36:18
почему? делаете инбокс для пользователя, на вставке вставляете ему всё в инбокс, на чтении удаляйте

Ibosh
27.04.2018
11:36:21

Сергей
27.04.2018
11:36:22
решение железнобетонное и не противоречит вашим требованиям

Yaroslav
27.04.2018
11:36:23
Там 40 таблиц в одном запросе может участвовать, почему нет?

Ilia
27.04.2018
11:37:25
не вариант
Да можно...
Удаляешь записи, делаешь повт. SELECT, потом опять удаляешь, потом в конце — ОТКАТЫВАЕШЬ ТРАНЗАКЦИЮ!

Yaroslav
27.04.2018
11:37:53

Ilia
27.04.2018
11:38:16
А где я тебе говорил про многотабличное удаление?

Yaroslav
27.04.2018
11:39:15

Darafei
27.04.2018
11:41:08

Google

Denis
27.04.2018
11:41:25

Yaroslav
27.04.2018
11:41:34
именно
А вот она... если я правильно понял.

Ibosh
27.04.2018
11:41:34
приложение

Darafei
27.04.2018
11:42:33

Yaroslav
27.04.2018
11:43:20

Ilia
27.04.2018
11:43:38
И?

Yaroslav
27.04.2018
11:43:40
Автор, вы в самом деле имели в виду это?

Ilia
27.04.2018
11:44:29
Чего он там имел в виду — даже не важно.
Надо удалять из одной таблицы — пожалуйста. Надо из нескольких — пожалуйста. Всё равно это надо в одной транзакции делать.

Yaroslav
27.04.2018
11:45:36

Ilia
27.04.2018
11:46:35
Да пусть всё что угодно удаляет, это его проблемы уже.

Denis
27.04.2018
11:48:32
приложение
А админ читает записи по одной или все разом?

Yaroslav
27.04.2018
11:49:29

Lev
27.04.2018
11:50:07
А как удалять? Допустим есть таблица
A (id, payload) {(1, a)}
B(id, aid, payload) {(10, 1, z)}
Посмотрел, стёрлись записи. Потом появляется в запись (11, 1, x), которая должна бы цепляться к А по LEFT JOIN, но А уже вся просмотрена и удалена!

Ibosh
27.04.2018
11:51:39

Yaroslav
27.04.2018
11:51:53
все разом
Вообще это очень странная задача... вы уверены, что это не про одну таблицу? ;)

Darafei
27.04.2018
11:52:13
ой, тогда есть крамольная тема!
индекс по xid

Ilia
27.04.2018
11:53:43
А как удалять? Допустим есть таблица
A (id, payload) {(1, a)}
B(id, aid, payload) {(10, 1, z)}
Посмотрел, стёрлись записи. Потом появляется в запись (11, 1, x), которая должна бы цепляться к А по LEFT JOIN, но А уже вся просмотрена и удалена!
Чтобы запись не светилась в запросе, достаточно хотя бы с одной стороны JOINа удалить, если LEFT JOIN, то нужно с ЛЕВОЙ стороны.
А там уже гляди сам, что тебе нужно по логике задачи удалять.

Lev
27.04.2018
11:54:47

Darafei
27.04.2018
11:55:01
индексом по xid порешали репликацию в osm, но теперь так нельзя: https://github.com/openstreetmap/operations/issues/154

Google

Amir
27.04.2018
11:55:18
а если админ сонный был? невнимательно посмотрел, а повторно уже не увидит)))

Ilia
27.04.2018
11:55:49

Amir
27.04.2018
11:56:04
вам обычную пагинацию и все, показывать все последние энцать записей,... остальное уходит на вторую треюю и далее страницы

Denis
27.04.2018
11:56:09
все разом
тогда как насчет вот этих вариантов:

Ilia
27.04.2018
11:56:17

Denis
27.04.2018
11:56:18
хранить на клиенте ИД последнего просмотренного?)
это если ID монотонно возрастают. Или хранить timestamp создания и последнего обновления
подходят?

Yaroslav
27.04.2018
11:57:05

Александр
27.04.2018
11:58:35
безнадежно всё это. Если автор так задает вопросы по своей проблеме , то в таком же ключе он всё и понимает ему предложенное.

Denis
27.04.2018
11:59:00
туплю >_<
почему только для пагинации?

Amir
27.04.2018
11:59:16
лочить на уровне строк
показывать незалоченные строки

Igor
27.04.2018
11:59:44
Если нет – максимально банальное pешение – отдельная табличка с метаданными о том, что было пpосмотpено, а что – нет.

Yaroslav
27.04.2018
12:00:54
можете раскрыть мысль?
Я думал, что под id вы имели в виду sequence, нет? Так они принципиально не атомарны, и для таких вещей, естественно, не подходят.

Denis
27.04.2018
12:02:52
Да, sequence. Если я сделал SELECT, сохранили себе максимальный id из записей, полученных таким селектом. И следующий селект сделаю с условием WHERE id > сохраненный id, я получу неожиданное?

Google

Amir
27.04.2018
12:04:15
Вот это идея! ;)
я просто недавно в одном проекте видел чтото такое
сейчас попробую найти что там было, сам ниразу не использовал еще)
но там это было для одновременного доступа к одним и тем же данным что бы распаралелить обработку

Yaroslav
27.04.2018
12:04:39
И после того, как вы прочитали записи и сохранили себе максимальный id, происходит COMMIT транзакции, которая вставила запись с меньшим id, чем вы запомнили. Ups.

Denis
27.04.2018
12:05:11
спасибо.

Darafei
27.04.2018
12:05:47

Yaroslav
27.04.2018
12:06:45

Darafei
27.04.2018
12:08:03
да, но возможно при анализе окажется, что требование более мягкое, "не показывать записи более одного раза"

Сергей
27.04.2018
12:09:53
Что ты так уперлись в задачу этого упоротого чувака? Она явно на бд не ложится в его понимании. Надо просто фильтровать по дате и все

Yaroslav
27.04.2018
12:10:57

Denis
27.04.2018
12:13:07

Darafei
27.04.2018
12:13:34

Сергей
27.04.2018
12:14:14
Ок)

Amir
27.04.2018
12:16:58
в общем уровни изоляции строк точно не подойдут для текущей задачи, там это для конкурентного доступа, что бы если один открыл, второй не смог, даже видеть)
но локи только в пределах жизни транзакции...нет транзакции нет лока
делайте просто вьюху на функцию возвращающую таблицу
в функции уже реализуете вашу логику как вам угодно
и лучше сразу себя отучить от мысли что с базой будет работать только 1 пользователь, получается он же суперюзер
лучше сразу отделить админа (суперпользователя) от пользователя системы

Ilia
27.04.2018
12:34:45


Dmitry
27.04.2018
12:45:21
Есть большая таблица, есть маленькая таблица того же формата и диапазон первичных ключей. Не подскажете как лучше одной операцией заменить все записи в большой таблице принадлежащие диапазону записями из маленькой таблицы, причём просто удалить и добавить нельзя, т.к. должны правильно отработать триггеры на update.
вопрос больше о том как UPSERT связать с DELETE
что-то типа:
DELETE WHERE id NOT IN (
INSERT SELECT ... ON CONFLICT DO UPDATE ... RETURNING id);
или правильнее с CTE?
я тут просто NOT IN перестал доверять, поскольку переписывание одного запроса на NOT EXISTS ускорило его в сотню раз из-за того что планнер догадался использовать anti join'ы

Amir
27.04.2018
12:48:07

Dmitry
27.04.2018
12:48:28
а есть пример для такого паттерна?

Google

Amir
27.04.2018
12:49:46
with i as
(INSERT SELECT ... ON CONFLICT DO UPDATE ... RETURNING id),
d as
(DELETE WHERE id NOT IN (select id from i) returning *)
select count(*) from d;

Dmitry
27.04.2018
12:50:22
ага, спасибо!

Amir
27.04.2018
12:50:45
это на быструю руку

Yaroslav
27.04.2018
12:50:50

Amir
27.04.2018
12:50:53
там если что подправите

Serg
27.04.2018
12:53:13
With smaltable as ( select data, id from small) update grostable grostable.data = smaltable.data where grostable.id in (select id from smaltable)

Ilia
27.04.2018
12:57:31

Dmitry
27.04.2018
12:57:49
потому что есть добавления и удаления

Ilia
27.04.2018
12:58:41
Ты же написал, что триггера должны сработать...
Ну, коли так, так сделай 1 UPDATE, 1 DELETE и 1 INSERT...
Там никаких принципиальных сложностей нет, надо просто взять и написать.

Dmitry
27.04.2018
13:00:29
дублировать код в insert и update не хочется, а для delete нужно всё равно список id получить и где-то хранить

Ilia
27.04.2018
13:00:35
У тебя ТРИ РАЗНЫХ оператора будет. INSERT, UPDATE, DELETE — какое ещё может быть дублирование?

Dmitry
27.04.2018
13:02:02
всё что вычисляется нужно будет вычислять и в insert и в update
т.е. писать два раза

Denis
27.04.2018
13:02:23
Кто нибудь решал проблему репликации изменений в кафку?

Yaroslav
27.04.2018
13:06:41
всё что вычисляется нужно будет вычислять и в insert и в update
Я ничего не понял... зачем 2 раза?
Вы что-то такое делаете?
WITH u AS (
UPDATE foo
SET something = foo_small.something, something_else = foo_small.something_else
FROM foo_small
WHERE foo.foo_id = foo_small.foo_id
RETURNING foo.foo_id
)
DELETE FROM foo
WHERE NOT EXISTS (SELECT 1 FROM u WHERE u.foo_id = foo.foo_id);
AND <диапазон>;

Dmitry
27.04.2018
13:07:48
Да
Вот это только с upsert как раз то что нужно